Hacker News

Top stories

Live mirror
30 storiesupdated just nowView source snapshot
  1. OpenJev(openjev.com ↗)
    53comments
  2. Jemalloc 5.4.0(github.com/jemalloc ↗)
    48comments
  3. Microsoft exec called AI scraping 'the largest theft of labor in human history'(techcrunch.com ↗)
    66comments
  4. The scourge of x86 emulation(fex-emu.com ↗)
    28comments
  5. Astra for Law(openai.com ↗)
    593comments
  6. Bonsai 2 27B: Near-Lossless Compression in a 9x Smaller Footprint(prismml.com ↗)
    136comments
  7. Bend – A language that blocks AI mistakes via proof, on CPU and GPU(bend-lang.com ↗)
    230comments
  8. Qwen 3.8 Omni Flash(qwen.ai ↗)
    83comments
  9. Replacing Pull Requests with Delta(zed.dev ↗)
    6comments
  10. Hister: A private search engine for the pages you visit and the files you keep(github.com/asciimoo ↗)
    170comments
  11. Wax motor(wikipedia.org ↗)
    72comments
  12. Pre-Greek: The lost language hidden within Ancient Greek(linguisticdiscovery.com ↗)
    40comments
  13. Fujitsu launches made-in-Japan next-generation CPU FUJITSU-MONAKA(global.fujitsu ↗)
    234comments
  14. When the fractional part of a float fixes your shader(crocidb.com ↗)
    1comments
  15. Shapelearn Qwen 3.8 27B (13.1 GB VRAM)(byteshape.com ↗)
    12comments
  16. Dr Julius Neubronner's Miniature Pigeon Camera(publicdomainreview.org ↗)
    discuss
  17. A heap overflow and SSO misconfiguration to compromise OpenAI internal repos(hacktron.ai ↗)
    158comments
  18. How to Write with an LLM(sockpuppet.org ↗)
    116comments
  19. Ask A Monk – A digital wilderness for thoughts with no immediate answer(askamonk.online ↗)
    24comments
  20. Flet 1.0 – Build cross-platform apps in Python(flet.dev ↗)
    59comments
  21. Telstra outage: The night a network decided the year was 2006(netnod.se ↗)
    29comments
  22. Speeding up gearhash on ARM64(sam.dev ↗)
    discuss
  23. Diplodocus, Long Thought Exclusively American, Turns Up in Spain(sci.news ↗)
    44comments
  24. How do we prevent mathemathics from devolving into the Medieval Era of secrecy?(mathoverflow.net ↗)
    109comments
  25. Why I didn’t sign the Fields medallists’ letter(gowers.wordpress.com ↗)
    371comments
  26. Apple detectives solved mystery of ancient tree and rewrote the history of fruit(scientificamerican.com ↗)
    12comments
  27. The most important product decision is what you don't build(liamnugent.me ↗)
    39comments
  28. Why Does the Universe Expand?(cosmicave.org ↗)
    60comments
  29. CrowdSec Source Code Leak(crowdsec.net ↗)
    49comments
  30. Show HN: Snapdrop: Instantly share files between devices. No setup, no signup(snapdrop.me ↗)
    39comments

Heisting $20M of Magic: The Gathering Cards in a Single Request

531 pointsby 3y agomayer.cool
132 comments
3y agoHN ↗

Ok, weird. That means that the client has to send a correctly calculated price in the purchase order, because the server validates the order by performing its own price calculation. While this left me stumped as to why the client-side calculation even exists, it meant I couldn't just tell the game to give me free cards, or cards at a negative price, or anything else.

I assume it's to detect stale data. What if the price changes while they're looking at the screen? At the very least, you want to make sure the player sees how much they're paying for something if the price changes out from under them.

Another alternative is to honor the price they saw, but that can be more complicated. It's easier to do a price check on the server side, reject the wrong price, then have the client refresh with the correct pricing.

3y agoHN ↗

When the client fetches the prices it could come with a catalog version number or some other opaque cursor which could be submitted with the purchase. If the cursor is out of date the server can simply reject it or choose to honor the old price by looking up the price in the old version pf the catalog.

3y agoHN ↗

The calculated price _is_ that version number, but smarter because it requires fewer checks and additional data. You don't really care if the catalog changed version, you care if the specific item in the catalog, for a given quantity of it, changed prices. You do lose the ability to look up the old price and apply that, but that is very rarely desirable anyways. Far easier and straightforward to just reject the transaction and have the user try again.

3y agoHN ↗

You do lose the ability to look up the old price and apply that

For certain e-commerce sites that would be a big loss. This is largely a solved distributed systems problem and I don’t see how passing the cursor back to the server is any more complex than calculating prices.

3y agoHN ↗

It's quite common in games for the store catalogue to be produced by pricing tools and handled as a static file by the server. It's then simpler overall for the client to volunteer a maximum price and the server either charges the current price in the file or refuses.

3y agoHN ↗

Did he confess to stealing $20M of merchandise?

3y agoHN ↗

No, he confessed to buying 21474837 digital packs of cards for the price computed by WotC. If you read the article closely you will see that he also reported this issue to the manufacturer and they fixed it.

3y agoHN ↗

What's more, the price is calculated by the client(!)

Somewhere between a chuckle and a facepalm.

3y agoHN ↗

The article framed it as a client-calculated price double-checked by server, but I think a better interpretation is that it was a server-calculated price with a preview price computed by client.

3y agoHN ↗

How is this any different from javascript validating input forms? The backend clearly verified the input, meaning the client would not end up paying the wrong amount due to change of conditions or discongruency between the server and client. Exceedingly smart and simple, and the objections towards it demonstrates the modern cargo culting of "let the server handle everything it always knows best".

3y agoHN ↗

As it's hidden at the very end

Except not, because I reported this vulnerability to them and it has been patched. Shoutout to the WotC security and engineering teams for being lovely to work with and patching this bug in a timely manner!

A fun writeup on a bug they properly reported. I hope WotC reimbursed them in some way though.

3y agoHN ↗

If I was running the backend for a game like MTGA, I would definitely find value in having a few of those kinds of accounts hanging around. As long as they don't terribly break things, you can use them to discover performance and scalability issues. If anything, I'd probably pull additional telemetry just for those accounts specifically.

3y agoHN ↗

I'm generally a proponent of soft limits on almost everything. It's better to hit some artificial cap than to end up chewing away on a transaction forever or crashing some service that can't allocate the memory to deal with it. In this case a limit on gems in an account, packs in a transaction, packs in an account, etc.

3y agoHN ↗

A less cool, more accurate title: "Using buffer overflow to gain infinite in-game currency locked to one account in Magic: the Gathering Arena and then disclosing the exploit to the publisher".

There are two M:tG online games, and Arena is the one with no way to transfer currency, cosmetics, or cards between accounts. The other one, M:tG Online, does allow for the ability to trade digital goods between accounts or redeem physical cards and, like grinding/botting on WoW or RuneScape, it's a way to earn reasonable money in South American countries (Brazil and Venezuela are the two I've heard about specifically).

3y agoHN ↗

This isn't a buffer overflow; it's integer wraparound.

3y agoHN ↗

It is also an integer overflow :)

3y agoHN ↗

And if that integer is used as a bit buffer... :).

3y agoHN ↗

… you still won‘t write outside the bounds of the integer, making this not a buffer overflow.

3y agoHN ↗

But you can overflow one bit into the carry flag, though :).

3y agoHN ↗

If you think of the integer as a buffer of size 31, containing an unsigned integer, the attack overflows into a different buffer of size 1, containing a sign bit for scaling that integer. ;)

But yeah, integer overflow and not buffer overflow.

3y agoHN ↗

GoatBots has an EV calculator for MTGO payouts: https://www.goatbots.com/event-calculator

One league takes about 1.5-2 hours to play, a challenge 5-8 hours depending on amount of players. 1 tix = $0.90, so you can see how hard it is to make a living.

I think there's only like 3-4,000 of us that play mtgo still, so the level of play is much higher than Arena (or even your average local FNM)

3y agoHN ↗

MTGO grinders used to often double-queue or triple-queue, running 2-3 events at a time. That should improve the EV on your time, but it's still bad.

3y agoHN ↗

Yep, still plenty of those of folks, mostly for challenges on the weekend. I'm always impressed by how they can keep two games in two different formats straight 4-5 hours into it lol

3y agoHN ↗

If it's anything like the news reports I read years ago about various mobile games, I imagine the people you're talking about are low-paid employees of a grinding company, playing on heavily streamlined and partially automated stations provided by the employer. There likely isn't even 1:1 relationship between a person and a handle.

3y agoHN ↗

I do not know, but Magic is not like poker where EV and optimal play is easy.

You only make money if you are winning, and in a pool of decent players winning consistently is hard. It is not a classic grinding opportunity

3y agoHN ↗

Why do you think optimal play in poker is easy?

3y agoHN ↗

Because the maths is known. The variables and unknowns are all clear.

3y agoHN ↗

It's just not possible to be successful in Magic doing that because the meta would quickly adapt to exploit whatever decks they had built automations for and make them losing players. Also, most trophy leaders in mtgo are well known people who all hang out in the same Discords, so we know exactly who they are.

3y agoHN ↗

Why not? Even ignoring any kind of streamlining automation, someone who plays MTG 8+ hours a day 5+ times a week is bound to eventually become a successful and adaptable player. They may not end up at the very top, but close to it, and more than enough to make positive profits for their employer, in countries with low labor costs and standards of living.

3y agoHN ↗

I wonder what the number is during vintage cube season. That’s the main reason I come back these days (never did manage to go infinite…)

3y agoHN ↗

That'll be the tradeoff with games that allow players to earn money (play-to-earn); it has to be rewarding enough to attract players, but not rewarding enough that people can turn it into a job (automated or otherwise). This is why these play-to-earn crypto/nft games aren't going to work. Or well, they work, but not the way people think they do - it'll be low wage countries doing the grinding, and people with expendable income / whales doing the buying, and I'm not sure if the two groups are aware of each other's existence.

3y agoHN ↗

A friend of mine and sometimes contractor is a venezuelan I met online in WoW classic because he was always farming dungeons we wanted to run, so we'd party with him a lot. Pretty interesting to learn about gold selling and leveling market from him.

I thought blizzard would find it easy to crack down on gold selling but I guess not, every once in a while he'd dump these massive amounts of gold to some random player he'd never interacted with and wouldn't get banned for it.

These days the way it works is he'd basically be a stringer for some big gold farming site. He'd farm, dump some big chunk to one of their sock accounts, and then they'd take that into bigger blobs of gold that would get banked or eventually parceled off into whatever amount a customer wanted.

The per hour price for his labor was pretty shit, better than in Venezuela of course but if I remember correctly not close to USA's 7$ or whatever it was at the time. It gave him access to USD though which was important, as USD can be used to buy more critical goods than venezuelan cash. Like computer components for example. And it's easily turned into local currency. So any time he could get his hands on usd he was keen.

It seemed like the better money was in levelling, where he'd log in onto your account and just level your character. In wow classic this was worth it cause the leveling gets insanely tedious around 48 to 58 (level cap 60). If you think it's silly to pay someone to play a game for you you're mostly right, but retail wow (the non classic redo) iirc sells level up potions, and so does guild wars 2, so presumably people buy them. Some people are more interested in end game than levelling.

Anyway for level up work he'd have to find a client through personal relationships, so harder to do, but more money cause no middleman. Plus he's just playing the game then which is more fun than grinding for gold.

Right now it sounds like the gold market is bereft, he's saying he can't find buyers right now, not sure what's happening there, but he hasn't grinded gold in months last I checked.

I now hire him on when I can for admin assist work, which I highly recommend doing even if you think you don't need an admin assist. I read Tim Ferris' "4 hour workweek" ages ago and remember him mentioning how an admin assist can save you time in ways you don't realize until you hire one on.

So far for me he's done asset placement in a tile map generator with data entry for a game dev contract we had, some project management related cleanup and admin work, photo editing of RAWs in Darktable (a skill he picked up in about 3 hours and became remarkably good at within two sets of photos), basic accounting and cleanup with data entry, and research with compilation. All for between 10-20usd/hour depending on what he feels comfortable charging (he wanted to charge less than 10 which is just too low for me to be comfortable with). Tldr I highly recommend exploring this sometime, I can recommend my buddy personally of course but there's also agencies and the like. Actually side note, incredibly, his venezuelan bank lets me make payments from my credit card. I have no idea what's happening in that country. I used to have to pay him in eth.

It's really remarkable the ingenuity folks in places like Venezuela have to have to make any kind of money. My buddy will be sniffing out these online working opportunities I'd never have dreamed of.

A good related book is Neal Stephenson's "Reamde," plot of which somewhat revolves around the transfer of digital games currency to real currency.

3y agoHN ↗

Aye, except the days of accurate headlines are a long long way behind us.

Makes me think that each HN submission should have two title fields: one for the exact title of the article or blog post or whatever, and one for an accurate consensus driven title!

Or if somehow content creators could be rewarded for accuracy in their headlines.

3y agoHN ↗

A less cool, more accurate title: "Using buffer overflow to gain infinite in-game currency locked to one account in Magic: the Gathering Arena and then disclosing the exploit to the publisher".

That is 76 characters too long for HN’s submit form.

3y agoHN ↗

Nice that the author was responsible about it and so was the site. This is the way.

3y agoHN ↗

Interesting how the lack of trading in Arena really keeps this bug (and most bugs) from being truly catastrophic.

If you did the same thing in MTGO, where you can actually trade those cards for event tickets, then sell those event tickets to a 3rd party for real money...well, then a bug like this has the potential to mess up that whole economy.

3y agoHN ↗

Yes, and this is the kind of things that happened with Diablo 2 back in the days in the Realms. Abusing different bugs for duplicating items ended up completely ruining the whole game economy. I know some people who made a lot of money selling those on Ebay.

Discloser: former game hacker.

3y agoHN ↗

My favourite hacks in trading have always been of the non-technical variety. For instance I remember reading of someone making an absolute fortune on the Diablo 3 auction house, because you could list items on it either for in-game gold or real money. But some people have quickly noticed that it's very easy to make a mistake and list something for 5 gold instead of 5 dollars, and people have in fact been doing it. With a bit of automation(buy anything worth less than X gold and of legendary rarity), people have made an absolute killing, tens of thousands of dollars a month just buying items for cheap and selling them for more. A little bit scummy, but no technical hacking needed, just a simple observation that the UI design of the auction house makes this kind of mistake really simple to make and no checks have been implemented to prevent it(no "this is a legendary item and you're listing it for 5 gold - proceed?").

3y agoHN ↗

What a painfully simple oversight that I’m sure the vast majority of programmers would overlook because the most popular languages are interpreted ones that natively support arbitrary precision bigints.

3y agoHN ↗

Hey all, author here - it feels pretty surreal to see my work on the front page of HN! I have done some other hacking on MTGA like creating an insta-win bug:

https://twitter.com/dan__mayer/status/1641669864460009472

As others have pointed out there are many games where the items _are_ easily converted back to dollars. Welcome to the beautiful world of game hacking! There are some really great talks about game hacking out there that you should check out, people make bank (and have a lot of fun) with it:

1) https://www.youtube.com/watch?v=ZAUf_ygqsDo 2) https://www.youtube.com/watch?v=QoNdhlLPX-g

It is not all fun and games though, game companies crack down on hackers profiting off of item duping and botting HARD. A bit related is the hacker who sold hardware to help play pirated games for the switch who has to pay Nintendo a third of his salary for eternity:

https://www.videogameschronicle.com/news/switch-hacker-gary-...

So be careful out there. Hack the planet!

3y agoHN ↗

Hack the planet!

Honestly this reads as "how do you do, fellow kids?"

You found a cool bug, then immediately reported it. That's not what the movie is about at all. Please don't corporatize hacker culture.

3y agoHN ↗

The kinds of people who do these exploits and cash in on them tend not to write blog posts about it on their personal website that links to their real-world LinkedIn.

3y agoHN ↗

It's strange this comment is being downed, because the "Hack the planet" quote from the movie (Hackers, 1995) and the tone of the entire movie is individual hacker vs corporate hacker. There is no way the main protagonist (Dade Murphy) would have disclosed a security vulnerability to the any of the companies in the movie. The quote in question is yelled by Dade while he is being dragged away by federal agents after saying "They're trashing" as a hint to the floppy disk he hid near the trash.

Disagree with what the poster is saying if you want, but he is accurate that the quote is being misused IMO

3y agoHN ↗

That's fair, although that movie is itself a little bit "how do you do, fellow hackers?"

3y agoHN ↗

You take that back, the film Hackers is a 100% accurate portrayal of the life of all hackers.

3y agoHN ↗

It's 10% exploiting zero days, 90% deploying demoscene animations

3y agoHN ↗

lol, "fellow kids" being people who get a roughly 30 year old movie reference.

3y agoHN ↗

You commented this on a site named "Hacker News" run by a venture capital firm

3y agoHN ↗

Props for fairly accurately describing what Gary Bowser actually did. Everyone just calls him a pirate when he was basically a middle-man for circumvention hardware... AFAIK he's not even a hacker?

3y agoHN ↗

That defense is not really believable given the emails that came out.

The punishment is egregious (esp. jail time), should've been something like 3x his profits, but the guy definitely sold ROMs (and other people's circumvention software!) (which apparently they added their own switch-bricking anti-circumvention to!) for profit.

3y agoHN ↗

He wasn't convicted of any of those things, though. You can look up what the actual conviction was:

The official charges are "Conspiracy to Circumvent Technological Measures and to Traffic in Circumvention Devices" and "Trafficking in Circumvention Devices", both of which are federal felonies in the United States.

Perfectly reasonable to assume the worst about the guy, but given that Nintendo is involved I will assume that anything the government couldn't prove is false.

3y agoHN ↗

Great article, thanks! I had a thought regarding something you said.

this left me stumped as to why the client-side calculation even exists

I suspect it is to validate that the price they showed you in the client was the same price they actually charged you. It seems reasonable enough anyway.

3y agoHN ↗

Gary’s story is dystopian: jail and slavery to a big corporation. Based move would be to get min wage job or live off benefits and do open source work.

3y agoHN ↗

Getting a job that pays cash in hand, or largely in non-cash benefits, would be the other obvious approach. Huge tax rates are generally counterproductive for society (even if you like big government and think the state is a better steward of money than the individual) because at some point people are no longer motivated to produce anything.

3y agoHN ↗

Or start a start up. You can pay yourself minimum wage with wealth tied up in the startup that wont be realised for a decade or more.

3y agoHN ↗

Seems pointless because he will have to pay nintendo when he gets that wealth. Draconian.

3y agoHN ↗

The idea is to moonshot: you succeed and paying nintendo is nothing. you fail and you’ve paid nintendo nothing!

3y agoHN ↗

The best would be a business that purchases his things for him.

E.g. he starts an LLC, profits stay in the company, company provides meals, vehicle, and phone+plan for the execs, plus travel expenses, and he gets a low salary from which I guess he still has to pay his rent.

3y agoHN ↗

Can't the LLC rent some flat as "company apartment" for "employees traveling on business", that happens to be in the same town as the HQ, and, since the LLC has only one employee...

Or just plain rent it and sublet it to the CEO for peanuts.

(This is all fun speculation, but Nintendo lawyers aren't idiots - the actual settlement likely covers LLCs, startups, benefits, and all other obvious workarounds. Hell, it probably makes Nintendo entitled to the 30% of unreported cash income and proceeds from crime as well.)

3y agoHN ↗

And in some countries these kind of benefits are taxed as income. And limited in amount that can be provided. But that requires sensible legistlation.

3y agoHN ↗

I assumed it was an order imposed by a judge and that there was some kind of standard process here. It's not abnormal for a judge to order you to pay X% of your salary capped at Y dollars a month, for example in child support.

It's unclear from the article what the nature of the payment is. It's described as a "fine" rather than "damages" but also mentions an "agreement with Nintendo".

3y agoHN ↗

Couldn’t I just sue his interest in the LLC in rem and now his creditors own the LLC, which they could liquidate?

He might be one tick better if someone else owned the LLC?

3y agoHN ↗

Haha, who told you that, billionaires by any chance?

3y agoHN ↗

You know that billionaires don‘t have salaries in the billions of dollars, right? They are largely paid in stocks, which are not taxed until sold. And you know they don‘t sell them if they can avoid it, because they don‘t want to pay high taxes?

3y agoHN ↗

Any source for not being liable for income taxes at the time of receiving stocks? That seems like a very obvious gap (which is not present in many EU countries at least, here we are definitely liable for income tax when RSUs vest).

I thought the reason for delaying selling of stocks is to avoid capital gains tax, not income tax.

I did a quick google, and most sources seem to support that taxes are due at RSU vesting time, e.g.

With RSUs, you are taxed when the shares are delivered, which is almost always at vesting. Your taxable income is the market value of the shares at vesting.

https://www.schwab.com/public/eac/resources/articles/rsu_fac...

Why would this be different for the salaries of rich people? Isn't it more that they usually get large amounts of stocks at low prices if they stick with the company for a long time?

3y agoHN ↗

There are different types of stock options.

ISO – no tax liability for exercising the option. You pay capital gains tax when you sell your contract or sell the stocks in your option.

As you can see, there are tax benefits to going with the ISO – you don’t pay any ordinary income tax at any point.

ISO = Incentive Stock Option

https://www.vectorvest.com/blog/options/how-are-stock-option...

3y agoHN ↗

Any source for not being liable for income taxes at the time of receiving stocks?

Depends on the details.

For founders and early employees, the 83(b) election[1] can make a huge difference. Basically, you have the option to pay taxes on the value of the stock portion of your compensation at the time of granting, rather than when it vests. For an early stage company, that's basically $0.

I'm not 100% clear on the details, so if you're interested that's 1 good place to look.

---

1. https://www.investopedia.com/terms/1/83b-election.asp

3y agoHN ↗

If you received the stocks from someone who died and devised them to you, your basis will be the fair market value at the time of death and you will not owe taxes.

(They might have if they were over the $12.02m lifetime gift limit but they probably weren’t if they had $12.02m to give away).

3y agoHN ↗

Most of the billionaire tech CEOs that I've seen get stock comp in RSUs which are taxed at time of vest. That may be different in other industries though.

3y agoHN ↗

I'm surrounded by people who produce lots of things, researchers, writers, developers, teachers, ... While money matters, I'm pretty sure it's secondary in their lives. So, not convinced about the "motivation" angle. Maybe it's a US thing?

3y agoHN ↗

I think it depends what you mean by 'money matters'

Some people clearly like consumption. Many are probably like me where income has gone up reasonably career progression but largely live the same lifestyle as where comfortable many years back. Any increasing excess goes onto the mortgage and savings type deal.

For me I'm happy wearing whatever clothes vs designer and actually like driving an older/cheaper car for zero care factor type thing and have few things I wish to splurge on.

At the same time money really matters as I never want to think about it. Once over a threshold it's low on my motivation and I'd generally choose more interesting work. Below the threshold I will become very motivated with it.

3y agoHN ↗

Maybe it's a US thing?

no. communism, wherever introduced, has never worked

3y agoHN ↗

Huh? No one said anything about communism.

3y agoHN ↗

he said that only in the US would work be disincentivized by high taxation. That is not the case.

3y agoHN ↗

That still has no visible connection to communism, unless you define "communism" as "high tax rates."

I am also curious to hear of any real-world countries where people choose not to work because taxes are too high.

3y agoHN ↗

Ask them all to work for minimum wage or less in those industries. You may get a few zealots they don’t care. Most will switch careers quickly.

My wife is a teacher, and pay is a huge concern for every single one, except for the handful that are rich, and just doing it for the fun of it.

I would highly recommend “basic economics” by Thomas Sowell. Will explain how profit motivation leads to people producing more with fewer resources. (efficiency) vs anything else that leads to less efficient use of resources.

3y agoHN ↗

Ask them all to work for minimum wage or less in those industries.

You're introducing an interesting counterpoint but I feel that it's not the question I was attempting to respond to. I was commenting on the matter of huge taxes demotivating everyone from creating anything.

I am assuming that any more or less reasonable taxation would either decrease the revenue of everyone or decrease the revenue of most of the members of the wealthier N% of the population (as usual, the richest will somehow manage to avoid most taxes). Do you believe that such a scheme would make your wife leave her career for something less creative/generally useful?

I would highly recommend “basic economics” by Thomas Sowell.

Adding to my looong list of books to read, thanks!

3y agoHN ↗

Move somewhere Nintendo doesn’t reach and go live your life again? I hear Russia’s nice this time of the year.

3y agoHN ↗

There are lots of places where you can work illegally without a contract and therefore without declaring an income.

3y agoHN ↗

Get a job he has to pay money to work at and invoice Nintendo.

3y agoHN ↗

At what point are you expecting the Pinkerton Agents to break down your door and drag you to a private black site on WotC's request? =)

3y agoHN ↗

I'm not sure if you're kidding, but Hasbro is notoriously litigious and might well do the civil equivalent. They are huge fans of the-process-is-the-punishment too.

3y agoHN ↗

Well done! Can you expand on what this means? "we can just patch our binary with the appropriate opcodes"

3y agoHN ↗

And this is why having overflow protection on by default is a good thing.

3y agoHN ↗

Reminds me of the old BASIC lemonade stand type simulation games where you have to purchase supplies and advertising to turn a profit on sales. Some of them didn't have input validation so you could order negative quantities of supplies and have your balance credited to your heart's content without selling anything.

3y agoHN ↗

Nice to see fellow HN MTG Arena players. Started playing MTG in 1995 and re-ignited the passion with Arena recently.

3y agoHN ↗

The post was interesting but the intro video is well worth the click. KNOWLEDGE

3y agoHN ↗

Not sure where that one got added or lost between the two calculations.

Your math is wrong. Instead of

    (200 * 21474837) % 0xFFFFFFFF

It should be

    (200 * 21474837) % 0x100000000

Then you get 104. The integer wrap point is 0x100000000 (because 0x100000000 is congruent to 0 in a 32 bit int). Similarly, the math to calculate the quantity should be math.floor((0x100000000/200) + 1) if a 0 total cost isn't allowed, or math.ceil(0x100000000/200) if a 0 total cost is allowed.

3y agoHN ↗

Aha, thank you! This is why we submit things to HN!

3y agoHN ↗

naive question: is this all possible because there is no real server side validation of the entire transaction ? This seems a very basic architectural overlook, or am I missing something ?

3y agoHN ↗

Second try gets stopped by the server side validation. Third try was to overflow the integer, for which there was no check on the client or the server side.

3y agoHN ↗

You missed that they engineered the request so that the validation on the server side also overflows in the same way, thereby passing validation.

3y agoHN ↗

I dunno... robbing board game shop still seems easier

3y agoHN ↗

They submit the total with each request because they don't want to show one thing to the user and then end up charging them something different, which will happen if the pricing on the backend changed, but the client didn't learn about that.

It's a common practice.

3y agoHN ↗

Ok, weird. That means that the client has to send a correctly calculated price in the purchase order, because the server validates the order by performing its own price calculation. While this left me stumped as to why the client-side calculation even exists

This is exceedingly sensible. By including the expected price, the client is saying "the user has agreed to purchase a, b, and c for tootal cost X." That price was the one being displayed to the user, and it was being calculated live on the client as the user fiddled with quantities and whatnot. The actual cost might be totally different if a card's price changes or a sale ends or who knows what, and charging a user a different value than what was displayed is totally unacceptable. It's a sanity check, or alternately a form of optimistic locking. It prevents a whole class of nasty billing bugs.

3y agoHN ↗

Yes, I wouldn't do it any other way, and it's not the cause of the bug here (except in so far as it didn't contribute to protecting the implementation details by security through obscurity).

3y agoHN ↗

There are other ways to do this, but not necessarily simpler:

- explicitly version every change to the store catalogue and require the version to be passed with a purchase, disallowing purchases from old catalogues

- make an expiring signed piece of data (like JWT) for each offer in the store catalogue and require it to be passed back with a purchase, accepting old prices briefly

- make the purchase API two-phase, locking in the price on the first phase and letting the client notice that it changed and potentially neglect to go through with the second phase

3y agoHN ↗

There is a good chance they don't even know what the price should be on the backend. The worst kind of apps are constantly running sales, special offer, limited discount, etc... Im pretty sure it's only calculated frontend side since it's very tied to if you just lost or if you are stuck in a game.

And tbh, I think they are okay with 10 hackers are ruining the game, as long as 1 thousand mothers are putting their credit card to pay for gems.

3y agoHN ↗

in the article it's explained that they do in fact check the price on the back end

3y agoHN ↗

Yep! I've noticed older games tend to utilize this trick; I spotted it in a certain Korean golf MMO from ~2004. It did have me scratching my head initially, but if I were the one designing the game, it definitely would've occurred to me that I don't want the value to mismatch. Of course, I think this is a bit old-timey now. If I were developing a game today, I'd probably make the store emulate how a typical store with a shopping cart works; do everything on the server side, and just display it to the client. I can, however, imagine coming up with this scheme if I were faced with the same problem, and I can appreciate that it is an elegant way to reduce the load/statefulness of the server without adding the risk that someone might get shafted.

3y agoHN ↗

[...] how a typical store with a shopping cart works; do everything on the server side, and just display it to the client.

The same concerns apply for a typical shopping cart design. The price can change in between the time when you sent the price to the client, and the time when the user actually decides to buy.

3y agoHN ↗

Majority of times I've seen this being solved with shopping cart items being copied from the main product table by SKU with the current price.

There is a TTL on the shopping cart itself. However, that meant for a period of time you had a frozen cost per-line-item in a shopping cart.

3y agoHN ↗

Well, in case of the server-side shopping cart, the server would have enough state to know if the price has changed since an item was added to the shopping cart, so the client wouldn't necessarily need to participate in preventing this scenario. I'm sure in practice, the checkout confirmation process for modern e-commerce sites also takes extra precautions to ensure that it can only happen exactly once and that it fails if any details change during the process of checking out.

3y agoHN ↗

Makes me think anything MtG related has wide open bugs. Remember MtGOX!

3y agoHN ↗

As an aside: Hasbro recently sent armed pinkerton agents to threaten a youtuber who legally purchased MTG cards that werent supposed to be released, after hasbro sent them out to a shop by mistake..

3y agoHN ↗

I wonder what would have happened if refunds caused your balance to overflow? Would WotC send the Pinkertons round to get those billions of gems you owe as debt off you?

3y agoHN ↗

Just because a bug is simple, don't assume that it isn't there.

That really is an interesting conclusion, because when I think about security, my mind is always like "don’t bother looking, surely there are no low-hanging fruit".

And then an article like this pops up and proves the opposite.

Well done and a nice read.

3y agoHN ↗

This is why fuzzing is so important for every system. It will throw all kind of unpredictable input at your system and check how it behaves. There are so many tools out there, just waiting to be used :)

3y agoHN ↗

I know nothing about this game, but it was a neat story. I was struck by a sense of nostalgia for an era where you could use cheat codes or trainers to get infinite money in games like SimCity or Civilization. Now such things are "vulnerabilities" and almost portrayed as "stealing" because, I assume(?), it gives you some sort of advantage in a multiplayer setting/marketplace? (I get it; the cultural shift just tickled me.)

3y agoHN ↗

That still exists for many single player games, though with the creep of ingame purchases into even single player games, there has been a reduction. But it's still plenty easy to fire up something like CheatEngine and poke around in a games memory. Many games these days also tend to have mod support, and if its halfway decent, someone will pretty quickly make a cheat/sandbox mod.

With all that said though, there's a certain trainer scene that has disappeared. From what I've seen, many have transitioned to the paid/freemium model (see things like WeMod and similar) and thus have to deal with somehow monetizing cheating; that tends to lead to some dark patterns and not so savoury behaviours. It was never the cleanest of scenes, but it feels particularly slimy these days.

I do miss the keygen and trainer chiptunes though.

3y agoHN ↗

You're right. This is going to make me sound like an old fart (my dad always said this would happen to me, too, one day) but while I appreciate living in the here and now, I do miss when every scrap of everything wasn't an opportunity to make a buck. There are more than enough indie games or old games I can continue to run to stay happy, so I think it's more the culture I'm reflecting on. Plus ça change.. :-)

3y agoHN ↗

I do miss when every scrap of everything wasn't an opportunity to make a buck.

I'm not so old that I would refer to myself as an 'old fart' in anything but jest, but I remember those times as well. I think it speaks to a broader issue that you almost _need_ to try to make a buck off everything to enjoy some comforts and luxuries.

3y agoHN ↗

The more "fun" thing these days is when you can't cheat in _single_ player, because that eats into DLC sales :)

3y agoHN ↗

Looking back at this line of code, I see two things:

    purchaseV2Req.currencyQty = client_PurchaseOption.IntegerCost * quantity;

There aren't any checks for overflows

In C#, this might actually be secure. There is a compiler option that enables overflow checking for all math in your code (but not in your dependencies). But I suppose the decompiler would have put a checked() around the operation in that case.

https://learn.microsoft.com/en-us/dotnet/csharp/language-ref... https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

3y agoHN ↗

I compile most of my C# code with integer overflow checking enabled. Better an unexpected exception, than whatever unpredictable behaviour an incorrect result causes.