But what purpose would this serve? Your primary goal is to collect input, your second is to prevent SQL injection. Either your input needs to maintain spaces (so you can't do this) or it does not (in which case just remove them). You yourself are saying that this is not going to be your only defense, so set up a proper defense and forget this 'trick for the sake of security'.
– Jan DoggenJun 21 '16 at 8:28

62

this is a solved problem - just parameterize all your queries
– user1666620Jun 21 '16 at 9:34

3

Nice to see the new HBGary is coming along. Very "forward thinking" guys ;-)
– Alec TealJun 21 '16 at 13:14

10

While it's a valid theoretical question, it has absolutely no practical relevance. There's a bomb proof way to secure against SQL injection, which is usually even simpler than any alternative sanitization; just use that without having to ask whether some alternative technique actually covers all your bases.
– decezeJun 21 '16 at 18:32

3

I'm not suggesting this be my only form of defense, but just curious where this form of "Defense" fits in the spectrum of good to useless. You should not be considering it using as any form of defense. As a question purely based in scientific curiosity, there's nothing wrong with it, though.
– JasperJun 22 '16 at 12:07

6 Answers
6

No. Removing spaces would not prevent SQL injection, as there are many other ways to make the parser process your input. Lets look at an example. Imagine that you had a url which used user supplied input unsafely in a query:

Depending on the technology in use the attacker could replace the spaces with /**/%00%09%0a%0d or any number of unicodes that causes tokenization by the SQL parser. While the referenced example removed more than just spaces, the aforementioned example takes advantage of SQL comments to cause the tokenization which are not whitespace. You would still be vulnerable.

The only reliable way to prevent SQL injection is to use parameterized queries.

Thanks for the interesting answer, but at what point would that URL change into the query statement, and why couldn't you remove the spaces at that point? Also, this seems to only affect URLs, or can this be used in Applications as well? I'm not really sure if in the application something like '\n' would produce a space after trying to remove white spaces from a String... I'm also curious if you agree with the below about injections not being that big of a deal and a "thing of the past?" I believe all of my queries are prepared statements/parameterized. Thanks.
– XaolingBaoJun 21 '16 at 5:47

1

It's a generic web example, because you referenced owasp. "Imagine" how the user input ended up in the query. How do SQL injections occur is a very different question to your OP. Methods for exploiting SQL injections are applicable everywhere SQL injections occur, be it a windows application, an FTP server, music player plugin or a web page. SQL injection is very much a present issue and while developers are becoming more aware it is still a common finding.
– wireghoulJun 21 '16 at 6:25

I see, I didn't look at this properly, and didn't realize you could do just id=1 or other commands that were like that. I figured that an Application might be able to protect better against an attack than a URL query, but I'm not sure how that works in comparison. I'll have to look up this id=1 and 1=1 business though.. Thanks a lot.
– XaolingBaoJun 21 '16 at 13:51

24

+1 for "The only reliable way to prevent SQL injection is to use parameterized queries" - it seems we can't repeat this enough!
– Toby SpeightJun 22 '16 at 7:47

@TobySpeight except it seems some claim that parameterized queries don't protect against all forms of SQL Injection?
– XaolingBaoJun 24 '16 at 9:19

Lets say I post the username admin'--. That would log me in as admin, without using a single space.

As wireghoul points out, you would need to remove other blank characters like tab as well. But as Julie Pelletier points out, just use prepared statements. Trying to come up with clever schemes to stop SQLi without it might be a fun game, but it will never give you the security that prepared statements does. Everything else is just a distraction.

Thanks for the answer, but it seemed like you could enter small statements, such as in wireghoul's answer where he says id=1, but not sure if they could get passwords that way, and I'm curious where the input is returned if they did that in the URL line? In your example wit the admin, you would need to know his information to log in, so I'm a bit confused what your example is trying to show? I'm using prepared statements, but just curious hypothetically how good space removal and other similar tasks would be... Thanks!
– XaolingBaoJun 21 '16 at 13:55

In my example you only need to know a username (not the password) to login as that user. That is a very, very bad. There are many other things you could do. Whireghoul has some examples, so does Jimmy James.
– AndersJun 21 '16 at 13:59

"That is very very bad" meaning the no password for admin lol? What exactly does admin'-- mean in SQL? Yeah it seems that it would be defeated by other small commands. Thanks.
– XaolingBaoJun 21 '16 at 14:02

3

This is the SQL you get: SELECT * FROM users WHERE username = 'admin'-- AND password = ''. But since -- starts a comment, the query that is executed is SELECT * FROM users WHERE username = 'admin'. So it will return the admin user as if the password had matched, even though there was no password.
– AndersJun 21 '16 at 14:13

Thank you very much... That makes a lot of sense, and is dirty.... :)... Since I made an edit to my question about sanitizing input to only allow numbers and letters, this attack, and others mentioned with characters such as = and % should be stopped, right? Thanks a lot!
– XaolingBaoJun 21 '16 at 14:31

update aTable set someColumn='JackedUpValue' where someColumn like
and performed the operation shown in this question, wouldn't you get

updateaTablesetsomeColumn='JackedUpValue'wheresomeColumnlike which
should not execute, right?

As others have pointed out there are other ways of getting whitespace into various SQL Database implementations which you would need to account for such as tabs and \n (newline). Almost every database engine would happily accept:

update
aTable
set
someColumn='JackedUpValue'

There may be various unicode characters that work as whitespace based on localization settings in various databases but you'd really have to dig into implementation details to figure that out. There's really no reason to try and cover all these edge cases for string replacement vs just using parameterized queries.

So here is an idea. Database servers take the incoming SQL query and run it through a parser resulting in a parse tree. Then they turn the tree into a plan and execute the plan.

The essence of injection is that the parser produces a tree different from the one intended by the programmer.

So the fix is to be able to detect unusual parse trees. Walk the tree after parsing and produce a string in canonical form minus the data values. Compute a SHA hash of the string. Keep a table of known hashes for the application/database user. Warn or abort if the server sees an unknown hash.

Obviously, there is a startup problem. So the programmer would have to run the application in a testing mode, extract the hashes after exhaustive testing, and the load the server with the hashes on application startup. Then turn on abort-on-new-hash and no more SQL inject should be possible.

How will you remove the data from the cannonical form? Wouldn't that just be yet another parser that can be fooled into believing that data is code? The attacker would need to make an SQLi and then a cannonical parser mislead into the end/start of the string. That's more troublesome than plain SQLi, but not bulletproof.
– grochmalOct 6 '16 at 2:37