this post was submitted on 25 Nov 2025
349 points (99.4% liked)
Programmer Humor
27673 readers
720 users here now
Welcome to Programmer Humor!
This is a place where you can post jokes, memes, humor, etc. related to programming!
For sharing awful code theres also Programming Horror.
Rules
- Keep content in english
- No advertisements
- Posts must be related to programming or programmer topics
founded 2 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
Java webapp. Customer facing. E-commerce application, so in PCI scope and dealt with credit card info and such.
There was one specific cookie that stored some site-wide preference for the customer. (Why not just put that preference in the database associated with the user? Because that would make too much sense is why.)
But the way they encoded the data to go into the cookie? Take the data, use the Java serialization framework (which is like Python's "Pickle" or Go's "Gob") to turn that into a string. But that string has binary data in it and raw binary data is kindof weird to put in a cookie, so you base64 encode the result. (The base64 encoding was the only sane step in the whole process.) Then you do the reverse when you receive the cookie back from the browser. (And no, there was no signature check or anything.)
The thing about the Java serialization framework, though is that decoding back into Java objects runs arbitrary object constructors and such. As in, arbitrary code execution. And there's no checking in the deserialization part of the Java serialization framework until your code tries to cast the object to whatever type you're expecting. And by that point, the arbitrary code execution has already happened. In short, this left a gaping vulnerability that could easily have been used to extremely ill effect, like a payment information breach or some such.
So all a malicious user had to do to run arbitrary code on our application server was serialize something, base64 encode it, and then send it to our servers as a cookie value. (Insert nail biting here.)
When we found out that there was a severe vulnerability, I got the task of closing the hole. But the existing cookies had to continue to be honored. The boss wasn't ok with just not honoring the old cookies and developing a new cookie format that didn't involve the Java serialization framework.
So I went and learned enough about the internal workings of how the Java serialization framework turned a Java value into a binary blob to write custom code that worked for only the subset of the Java serialization format that we absolutely needed for this use case and no more. And my custom code did not allow for arbitrary code execution. It was weird and gross and I made sure to leave a great big comment talking about why we'd do such a thing. But it closed the vulnerability while still honoring all the existing cookies, making it so that customers didn't lose the preference they'd set. I was proud of it, even though it was weird and gross.
The value that was serialized to put into the cookie? A single Java int. Not a big POJO of any sort. Just a single solitary integer. They could just as well have "serialized" it using base-10 rather than using the Java serialization framework plus base64.
Gson in the corner murdered: