back to article Is HONK nothing sacred HONK? It's 2019 and an evil save file can pwn much-loved HONK Untitled Goose Game

Fans of Untitled Goose Game should update their copy of the indie smash-hit following the discovery of a bug that can lead to malicious save files hijacking players' systems. Pulse Security bug-hunter Denis Andzakovic took credit for finding and responsibly disclosing the vulnerability, which does not appear to have been …

  1. Unbelievable!

    Honk you very much for another informative article. :)

    thanks for injecting some humour in the article. :)

    I'm bereft of suitable comment (arguably not for the first time!) but cheers and thanks for the warning.

  2. sbt

    Honk if you want to go faster

    It could be time to update Postel's law: "...implementations should follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others."

    Too liberal* and you get f*cked.

    * Not talking politics here, obviously

    1. Richard 12 Silver badge

      Re: Honk if you want to go faster

      Seems many people misunderstand that advice.

      "Be liberal in what you accept" means to assume you might be sent anything.

      So you must deal with incomplete, partially corrupt and unexpected input appropriately, and should try to correct them where possible.

      - ECC, checksums, sensible defaults, skip over unexpected input...

      1. Michael Wojcik Silver badge

        Re: Honk if you want to go faster

        That's a fine sentiment, but it's pretty clear from context that Jon Postel intended the Interoperability Principle as a recommendation for the liberal interpretation of malformed data. That has frequently created security issues, as with, for example, permitting non-canonical UTF-8 sequences, which may bypass special-character blacklists but then be interpreted by parsers.

        The Interoperability Principle was invaluable in promoting the spread of the Internet, TCP/IP, and many application protocols and languages (perhaps most notably HTTP and HTML). Over the past couple of decades it's increasingly become a liability.

  3. oldtaku Silver badge

    How it might work

    How the heck can a save file run arbitrary code? Well, I haven't looked at this vuln in detail, but there's a known class of exploits that affects almost any framework that allows you to deserialize arbitrary classes, like PHP, C#, Java, Ruby, etc etc.

    - Find a class in the program which does something in its Dispose() method (called when the object should release its resources), say the HonkBonk class.

    - If the Dispose() method includes a callback, you're wide open, but there are several things you can exploit.

    - There are a lot of .NET classes too, you can abuse those as well as the program's own classes.

    - In your malicious save file you put a saved object for the HonkBonk class - for the callback field, put a lambda with your arbitrary code.

    - Program tries to read the SaveData class from the save file

    - Instead of the SaveData class, the BinaryFormatter sees a HonkBonk object - it creates it (it's a known class!) and reads the fields into it

    - When the program tries to cast HonkBonk object to SaveData class, this fails, so you get a cast exception.

    - The HonkBonk object is 'lost' (there are no references to it)

    - The HonkBonk object gets garbage collected

    - Dispose() is called on the HonkBonk object

    - Your arbitrary code is executed

    - * HONK*

    You can use the SerializationBinder in .NET to stop it from attempting to handle completely arbitrary data.

    1. Glen 1

      Re: How it might work

      So a bit like running eval() on JSON then?

      1. Michael Wojcik Silver badge

        Re: How it might work

        Yes. Or using an eval operation on anything else that provides it.

    2. Robert Helpmann??

      Re: How it might work

      I am a bit confused on what makes a flaw that allows execution of arbitrary code "more amusing that [sic] scary." It might have limited applicability due to what is being exploited, but that's still pretty nasty.

      1. Michael Wojcik Silver badge

        Re: How it might work

        Well, in terms of vulnerability risk assessment, as we do for CVSS scoring, you have to look at the threat model. A couple of mitigations:

        * UGG is not a common application in the same sense as, say, Microsoft Word. The target population is not enormous.

        * User interaction is required, and typically some social engineering. Users don't habitually open game-save files from untrusted sources. Again that limits targets, and complicates automated or bulk exploitation.

        * Users should be running with normal privileges. Of course we know that users often run with excessive privileges, but in this case the vulnerable application doesn't have any good reason to do so, unlike with some targets.

        * The target doesn't have direct access to sensitive data, so an exploit has to be chained with, or followed by, at least a pivot maneuver to get anything of value. That's not an obstruction for a determined attacker but it increases the attacker's work factor to do anything useful, and so discourages casual exploitation.

        I still don't know that I'd rate this as "amusing", but it probably pushes it from Critical down to High or even Medium importance, depending on the user aspects of your threat model. (In my case, since I don't have to worry about any UGG users, it doesn't matter at all.)

    3. Loyal Commenter

      Re: How it might work

      That's an interesting exploit. Off the top of my head, I'd mitigate that sort of thing by:

      Having your save data classes in their own namespace.

      Make these plain classes that don't implement IDisposable (or your language specific equivalent)

      Not having callbacks in destructor or dispose code (in C# at least, there's a well-known pattern for implementing IDisposable that allows for disposal chains without callbacks).

      Type-checking the objects when deserialised to ensure they are the type you are expecting, and if possible enforcing a type in the deserialiser (i.e. Deserialiser.Deserialise<Goose>(payload)).

      Make sure you have don't use polymorphism in your save data classes (i.e. don't have a Goose class that derives from a Bird class) - this mitigates the fact that if you wanted to call Deserialise<Bird> you might get a Goose object back, and this would be valid.

      It sounds to me that this specific exploit comes about because it is using a library for (de)serialisation that allows configuration of the serialiser in the file itself (I've not read the technical details, but this sounds likely). The mistake here is to allow the file to override the default. To be honest, that's a bit of a security flaw in the library itself (at least allowing such behaviour by default). It doesn't surprise me that Microsoft would write it this way. I'm willing to bet you that the documentation for its behaviour is less than great as well.

    4. Brewster's Angle Grinder Silver badge

      I must be getting old.

      Whoever thought it was a good thing to allow code (lambdas) in a data file? What situations are there where this isn't a security flaw? Is there really justification for this being in the core libraries?

      1. 9Rune5

        Re: I must be getting old.

        allow code (lambdas) in a data file?

        The problem is serializing the type information. is quite fond of using

        So... They instantiate an object of type ObjectDataProvider and this object happens to take a method name (and parameters) as a property value leaving only the task of binding to the ObjectDataProvider instance.

        1. Brewster's Angle Grinder Silver badge

          Re: I must be getting old.

          I was willing to give generic deserialization a pass, in case I was being a old fogey. ("Bah! Deserialization! Use proper file formats, you punks!")

          But the verdict is bad as my instincts feared. You cannot include arbitrary data schema in the file format and let the software reconstruct the data according to that schema.

    5. Michael Wojcik Silver badge

      Re: How it might work

      The classic presentation on the subject is "Marshalling [sic] Pickles from AppSecCali 2015. It's a good one; anyone interested in further detail on how this sort of thing is exploited in various languages and contexts might want to watch the video or at least browse the slides.

      In the MITRE CWE scheme, it's CWE-502.

  4. Anonymous South African Coward

    Mess with the Honk

    You get the Bonk

  5. Aristotles slow and dimwitted horse

    Honkity honk!!!

    Better a honky goose than generic Angry or Flappy birds.

    1. GrumpyKiwi

      Re: Honkity honk!!!

      All geese are angry and flappy. Oh, and evil. At least 0.67 of a Hitler on the Hitler scale as this game so aptly demonstrates.

  6. Anonymous Coward
    Anonymous Coward

    Pedant alert

    "Windows PCs, Macs, and the Nintendo Switch"

    Macs ARE PCs, so this should read "Windows, MacOS and Nintendo Switch".

    1. Captain Scarlet Silver badge

      Re: Pedant alert

      But Mac machines are not IBM Compatible :P

      Ok neither is anything these days.


      1. Teiwaz

        Re: Pedant alert

        IBM haven't been particularly PC compatible in a while

        Or human compatible, come to that.

  7. Antron Argaiv Silver badge


    More a Goat Simulator man myself...

    1. David 132 Silver badge

      Re: Butt

      I'd not heard of the game before this article, but will now give it a gander.

  8. detuur

    Exciting.. Or it used to be

    Save file vulnerabilities used to be a prime method of running unsigned code on consoles in order to jailbreak them. Unfortunately modern consoles do not make save games user accessible anymore.

  9. Claptrap314 Silver badge

    Never learn..

    I immediately recalled this issue: Which inevitably lead to this one:

    Deserialization of more-or-less arbitrary data CAN be handled securely, but you cannot be an idiot about it. In the case of Rails, the problem was that the standard Ruby YAML library co-oped the [] method. That's bad enough, but a) this was (and IS!) undocumented, and b) it could be triggered by any document. The maintainer of the library never accepted that this is a problem, so the last time I checked, YAML cannot be used in Ruby with standard libraries to load data from files that are not fully trusted if you have classes which do interesting things with [].

    Both the library provider and the application developer have to do their jobs.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Other stories you might like