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.

XaolingBao
  • 897
  • 2
  • 9
  • 21
  • 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'. –  Jun 21 '16 at 08:28
  • 62
    this is a solved problem - just parameterize all your queries – user1666620 Jun 21 '16 at 09:34
  • 1
    could i use a tab instead of a space? – dandavis Jun 21 '16 at 09:42
  • 3
    Nice to see the new HBGary is coming along. Very "forward thinking" guys ;-) – Alec Teal Jun 21 '16 at 13:14
  • 2
    @JanDoggen I'm just asking a "what-if..." In my instance I don't need spaces, which is why I ask if removing spaces, would work. I'm also curious if I sanitized input to only a certain range of ASCII/unicode Characters, would protect better since there are many space unicode characters it seems... – XaolingBao Jun 21 '16 at 13:29
  • 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 '16 at 18:32
  • It's weird I'm starting to get downvotes now after all these upvotes.. I wish people would at least comment why... Maybe my edit??? – XaolingBao Jun 22 '16 at 08:50
  • 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 '16 at 12:07
  • Removing backslashes, single quotes and double quotes would most probably prevent SQL injection. It's also practical to remove NULs to prevent query parsing errors. But of course the easy-to-maintain, least-surprise solution is passing query arguments separately (and marking their position with `?` in the query), so the database client driver takes care of the escaping, or using an ORM. – pts Jun 22 '16 at 20:52
  • @XaolingBao I don't have sufficient rep to downvote, but I would if I could, because the question just seems to be saying 'I know there are all these proper methods I could use, but can I just use this lazy one instead, which cripples what my users are able to input and blatantly omits to cover almost all situations if I were to actually consider real-life SQL code and extended character sets?' – underscore_d Jun 23 '16 at 12:49
  • As has been mentioned before, always use parameterized queries. Just live by the assumption that unparameterized SQL will always be exploited, because frankly there are so many ways to abuse it that it's impossible to guard against all of them. As a simple example, consider that you filter out numbers and the attacker needs a '3' in his query for whatever reason. What does he do? `FLOOR(PI())`. – Seralize Jun 23 '16 at 17:27
  • @XaolingBao I'm guessing the downvotes are because as stated many times in response to this question, it is a solved problem – wireghoul Jun 24 '16 at 07:24
  • @Jasper I had edited that pat before I saw your comment, to make a bit more sense, but yes, I'm not actually considering it unless it worked, so I'll edit that part to make it more clear I'm just looking atthis from a hypothetical standpoint, and asyou said "scientific curiosity" – XaolingBao Jun 24 '16 at 09:21
  • 1
    @underscore_d I mentioned that I am using proper procedures, this is just a hypothetical question in order to see "what if" I were to remove spaces, not to use this as a way to defeat SQL Injection, unless it worked very well. – XaolingBao Jun 24 '16 at 09:22

6 Answers6

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.

wireghoul
  • 5,745
  • 2
  • 17
  • 26
  • 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 '16 at 05: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 '16 at 06: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 '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 Speight Jun 22 '16 at 07:47
  • @TobySpeight except it seems some claim that parameterized queries don't protect against all forms of SQL Injection? – XaolingBao Jun 24 '16 at 09:19
  • I don't even know why people continue to try and solve SQL injection without parameterized queries, as if they've never heard of them. It makes me want to rage-smash my face through a wooden table, along with that stupid Bobby Tables meme. – Mark Buffalo Oct 06 '16 at 02:29
48

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).

Julie Pelletier
  • 1,919
  • 10
  • 18
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackexchange.com/rooms/41512/discussion-on-answer-by-julie-pelletier-would-removing-spaces-in-a-string-protec). – Rory Alsop Jun 22 '16 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.

Anders
  • 64,406
  • 24
  • 178
  • 215
  • 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 '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. – Anders Jun 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. – XaolingBao Jun 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. – Anders Jun 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! – XaolingBao Jun 21 '16 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.

JimmyJames
  • 2,956
  • 2
  • 16
  • 25
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackexchange.com/rooms/41582/discussion-on-answer-by-jimmyjames-would-removing-spaces-in-a-string-protect-aga). – Rory Alsop Jun 23 '16 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.

nvuono
  • 121
  • 3
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.

user126572
  • 11
  • 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 06 '16 at 02:37