22

I was curious if it's possible to protect against an SQL injection attack by removing all spaces from an String input?

I have been reading up on SQL Injection at OWASP, but they don't mention anything about removing spaces, so I was curious why it would, or would not work?


I was looking at this question, which asks about trim, and the top answer says this:

No, adding a trim will not prevent sql injection. trim only removes space on the outside of your string.

Select * from aTable where name like '%'+@SearchString+'%'

If you @SearchString held something like

'' update aTable set someColumn='JackedUpValue' where someColumn like '

Then when you put it all together and execute it dynamically you would get

Select * from aTable where name like '%' update aTable set someColumn='JackedUpValue' where someColumn like '%'

However if you took that search string

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?

I'm curious if there is any form of SQL injection that could defeat this? Are there one word dangerous commands? If this can be defeated, would removing spaces at least help a bit with defense?

Note: I'm asking this question purely out of curiosity, not as way to circumvent using the "proper" methods of SQL Injection Prevention.

14
  • 40
    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'.
    – user13695
    Jun 21, 2016 at 8:28
  • 62
    this is a solved problem - just parameterize all your queries Jun 21, 2016 at 9:34
  • 3
    Nice to see the new HBGary is coming along. Very "forward thinking" guys ;-)
    – Alec Teal
    Jun 21, 2016 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.
    – deceze
    Jun 21, 2016 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.
    – Jasper
    Jun 22, 2016 at 12:07

6 Answers 6

119

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:

http://example/index.php?id=1 => SELECT * from page where id = 1

In your example the attacker would use spaces:

http://example/index.php?id=1%20or%201=1 => SELECT * from page where id = 1 or 1=1.

Removing the spaces would collapse the injection into a string.

Now let's imagine that the attacker used another form of white space, i.e. tabs:

http://example/index.php?id=1%09or%091=1 => SELECT * from page where id = 1 or 1=1.

Removing the spaces would still allow the injection through.

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.

6
  • 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.
    – XaolingBao
    Jun 21, 2016 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.
    – wireghoul
    Jun 21, 2016 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.
    – XaolingBao
    Jun 21, 2016 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! Jun 22, 2016 at 7:47
  • @TobySpeight except it seems some claim that parameterized queries don't protect against all forms of SQL Injection?
    – XaolingBao
    Jun 24, 2016 at 9:19
49

We're in 2016! SQL injections are a thing of the past unless you use insecure code.

Whatever language you use, if you want to prevent any and all SQL injections, use prepared statements or any other type of data binding.

Prepared statements separate the query from the data, making it impossible for the data to affect the query.

To directly answer your question, removing spaces would reduce SQL injections (when using outdated code and libraries), but would surely limit your input text (no spaces anywhere).

1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Rory Alsop
    Jun 22, 2016 at 15:07
17

It would limit the problem, but not eliminate it. Consider the following situation:

$un = str_replace(" ", "", $_POST["username"]);
$pw = hash($_POST["password"];
$sql = "SELECT * FROM users WHERE username = '$un' AND password = '$pw'";

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.

5
  • 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!
    – XaolingBao
    Jun 21, 2016 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.
    – Anders
    Jun 21, 2016 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.
    – XaolingBao
    Jun 21, 2016 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.
    – Anders
    Jun 21, 2016 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!
    – XaolingBao
    Jun 21, 2016 at 14:31
13

No. Let's say you have this as your SQL:

"select * from people where last_name = '" + surname + "'"

If I enter: 'OR(1=1)OR'a'=' into the input it turns into:

select * from people where last_name = ''OR(1=1)OR'a'=''

Which executes in Oracle and MySQL (at least) and returns all the rows from the table.

1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Rory Alsop
    Jun 23, 2016 at 21:24
2

However if you took that search string

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.

1

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.

1
  • 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.
    – grochmal
    Oct 6, 2016 at 2:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .