Live data from Hacker News

Hidden Messages in Emojis and Hacking the US Treasury

slamdunksoftware.substack.com

31–40 of 82 posts

Re: Hidden Messages in Emojis and Hacking the US Treasury

#31

Earlier quoted context omitted.

The only reason BeyondTrust implemented that was it wasn't untrusted user commands . They sanitized the data, so it should have been fine. The unfortunate problem was that the sanitizer didn't sanitize. Systems are built on a set of expectations. Undermine the expectations and you undermine the system.

> They sanitized the data, so it should have been fine. This is a 101 rookie level approach to SQL or injection defense. It's dumb for exactly the same reason why this is dumb "SELECT * FROM foo WHERE bar=" + sanitize(userInput) The correct way to do something like this will always be parameterized input which looks something like this "SELECT * FROM foo WHERE bar=?" bindParameter(1, userInput); Why? Because that the…

His argument is that you are building on the assumption that this is safe:

    "SELECT * FROM foo WHERE bar=?"
    bindParameter(1, userInput);
But what happens when it turns out that isn't safe?

Re: Hidden Messages in Emojis and Hacking the US Treasury

#32

Earlier quoted context omitted.

> They sanitized the data, so it should have been fine. This is a 101 rookie level approach to SQL or injection defense. It's dumb for exactly the same reason why this is dumb "SELECT * FROM foo WHERE bar=" + sanitize(userInput) The correct way to do something like this will always be parameterized input which looks something like this "SELECT * FROM foo WHERE bar=?" bindParameter(1, userInput); Why? Because that the…

His argument is that you are building on the assumption that this is safe: "SELECT * FROM foo WHERE bar=?" bindParameter(1, userInput); But what happens when it turns out that isn't safe?

Then you, or someone else, fix the underlying library.

This being Postgres, that process was likely completed decades ago.

Anticipating the next question, "but what if it is still unsafe?", the answer is that there is no fundamental reason why this can't be safe code. Security exploits like this require a cooperation between the receiving code and the incoming data, and it is in fact perfectly possible for the receiving code to be completely safe. There is no such thing as data just so amazingly hackerish that it can blast through all protections. There has to be a hole, and this is among the best-tested and most scrutinized code paths in the world.

Re: Hidden Messages in Emojis and Hacking the US Treasury

#33

Earlier quoted context omitted.

> They sanitized the data, so it should have been fine. This is a 101 rookie level approach to SQL or injection defense. It's dumb for exactly the same reason why this is dumb "SELECT * FROM foo WHERE bar=" + sanitize(userInput) The correct way to do something like this will always be parameterized input which looks something like this "SELECT * FROM foo WHERE bar=?" bindParameter(1, userInput); Why? Because that the…

His argument is that you are building on the assumption that this is safe: "SELECT * FROM foo WHERE bar=?" bindParameter(1, userInput); But what happens when it turns out that isn't safe?

That is not what's happening. You can't bind parameters in psql.

What beyond trust did was in fact what I said, constructing the entire query as one string and sending that on to psql. The sanitization method failed, but that's not what you should use anyways when dealing with user input.

If you are using a postgres client, then the message breakdown to postgres when you bind looks something like this (not the actual message stream format, just the jist of what it ends up looking like)

    SELECT * FROM foo WHERE bar=$1
    BIND 1 escape(userInput)
    ENDBIND
There isn't the same opportunity to create malformed data that can cause an injection attack in the Postgres message stream. There are far fewer things that need to be escaped in order to put in the full message. (I skimmed through the protocol, one improvement I'd make to it is adding a length to the bind instead of having a termination like it appears to do. That would, however, preclude streaming data)

These yahoos took a different route to running a command than what everyone does and should do and they were bit by it.

EDIT Actually, yes you can bind parameters with psql. However, it's there mostly as a way to test postgres and not something users are expected to use.

Re: Hidden Messages in Emojis and Hacking the US Treasury

#34
post #7

> Now, all of this might have been fine had Beyond Trust not written a feature which allowed users to directly, programmatically interact with psql (the postgres command line interface). That's the buried lede. Yes, there was a vulnerability in psql... but that's so much less a problem than the huge gaping hole of allowing users to directly interact with psql. No DB can be safe if you are turning untrusted user comma…

Giving untrusted users ssh access... You mean like every shared hosting company or shell provider?

Re: Hidden Messages in Emojis and Hacking the US Treasury

#35

Fun fact: MySQL (and I'm sure many other databases?) lets you pass in values directly as hexadecimal strings. I've avoided SQL injection since ancient times not by escaping strings, but by transforming any given input via "0x" + bin2hex(value) and plopping that into the query. No quotes needed, no code buried deep in included libraries needed, handles any kind of data possible, and also no funny business sneaking in…

Cool idea. Genuinely. But it does not in any way guarantee that an injection attack like used here won’t work - unless it’s maintained as hex through the whole pipeline. In this case the (malformed) Unicode was sent to a command line call - if your hex text needed to be parsed to be understood on the command line, then your security plan would have failed.

Re: Hidden Messages in Emojis and Hacking the US Treasury

#36

Earlier quoted context omitted.

His argument is that you are building on the assumption that this is safe: "SELECT * FROM foo WHERE bar=?" bindParameter(1, userInput); But what happens when it turns out that isn't safe?

That is not what's happening. You can't bind parameters in psql. What beyond trust did was in fact what I said, constructing the entire query as one string and sending that on to psql. The sanitization method failed, but that's not what you should use anyways when dealing with user input. If you are using a postgres client, then the message breakdown to postgres when you bind looks something like this (not the actual…

They aren't saying that's what is happening but the underlying assumption is similar to that.

Re: Hidden Messages in Emojis and Hacking the US Treasury

#37

Fun fact: MySQL (and I'm sure many other databases?) lets you pass in values directly as hexadecimal strings. I've avoided SQL injection since ancient times not by escaping strings, but by transforming any given input via "0x" + bin2hex(value) and plopping that into the query. No quotes needed, no code buried deep in included libraries needed, handles any kind of data possible, and also no funny business sneaking in…

Cool idea. Genuinely. But it does not in any way guarantee that an injection attack like used here won’t work - unless it’s maintained as hex through the whole pipeline. In this case the (malformed) Unicode was sent to a command line call - if your hex text needed to be parsed to be understood on the command line, then your security plan would have failed.

Totally agree on my tip not being a silver bullet for all situations, just wanted to pass it along in case somebody finds themselves needing to sanitize input for queries rather than constructing prepared statements.

I was a bit perplexed by the final destination of command line for data and/or queries -- seems like an odd choice when they could've just interfaced directly with the database like a civilized human hahaha

Re: Hidden Messages in Emojis and Hacking the US Treasury

#38
post #19
post #5

I learned about the breach a few days ago but I didn't know that you could "adopt" an emoji: https://aac.unicode.org/sponsors That's a neat tidbit.

Does "adopting an emoji" mean something other than "appearing on that page"? From the adoption page: Each adoption comes with a digital badge and certificate that you can proudly display.

It's just a way to donate, similar to lots of "adopt a xxx" programs.

Re: Hidden Messages in Emojis and Hacking the US Treasury

#39
post #7

> Now, all of this might have been fine had Beyond Trust not written a feature which allowed users to directly, programmatically interact with psql (the postgres command line interface). That's the buried lede. Yes, there was a vulnerability in psql... but that's so much less a problem than the huge gaping hole of allowing users to directly interact with psql. No DB can be safe if you are turning untrusted user comma…

Giving untrusted users ssh access... You mean like every shared hosting company or shell provider?

Which is why shared hosting companies get hacked relatively more.

Re: Hidden Messages in Emojis and Hacking the US Treasury

#40
post #32

Earlier quoted context omitted.

His argument is that you are building on the assumption that this is safe: "SELECT * FROM foo WHERE bar=?" bindParameter(1, userInput); But what happens when it turns out that isn't safe?

Then you, or someone else, fix the underlying library. This being Postgres, that process was likely completed decades ago. Anticipating the next question, "but what if it is still unsafe?", the answer is that there is no fundamental reason why this can't be safe code. Security exploits like this require a cooperation between the receiving code and the incoming data, and it is in fact perfectly possible for the receiv…

There's some nuance here. Even the most battle-tested system, with distinct slots for executable code and primitive values, might have a way in which an untrusted primitive input can overrun a buffer, or be split in an unsafe way, and cause unexpected behavior. But there's a vast difference in attack surface between that, and "just give us a string, don't worry we'll sanitize it on our end."

It's all about defense in depth. Even a system that's tested all the way through with Coq or similar is still at the mercy of bugs in the specification or in underlying system libraries. But intentional API design can make it materially less likely that a security issue will arise, and that's worth a heck of a lot.

Post reply on HN