Information Security Stack Exchange is a question and answer site for information security professionals. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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 defense?

Note: 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.


EDIT: Thanks for all of the answers thus far. Since there was mention of other characters being used to replace a space i.e., %20 in a URL, so I was curious if we sanitized the input to have no special characters, and only display ASCII Characters from 0 - 9 and a(A) - z(Z)?

This also might be better for another question, but if you did have a query as a URL, or with a special character, at what point would that character turn from %20 into a space? Is it possible to remove the space after it turns into a space, if we didn't sanitize the input for special characters and such?

Ultimately, as shown in a few answers, there are smaller commands that could do things, e.g. id=1 from wireghoul's answer, or OR(1=1)OR'a'=' from JimmyJames' answer.

The thing is, if I limit the characters (as mentioned above) it should prevent any of this = business, right?

Curious if there are other ways to defeat this?

share|improve this question
29  
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 Doggen yesterday
32  
this is a solved problem - just parameterize all your queries – user1666620 yesterday
3  
Nice to see the new HBGary is coming along. Very "forward thinking" guys ;-) – Alec Teal yesterday
1  
@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 yesterday
4  
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 23 hours ago

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.

share|improve this answer
    
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 yesterday
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 yesterday
    
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 yesterday
3  
+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 10 hours ago

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

share|improve this answer
    
Comments are not for extended discussion; this conversation has been moved to chat. – Rory Alsop 3 hours ago

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.

share|improve this answer
    
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 yesterday
    
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 yesterday
    
"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 yesterday
1  
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 yesterday
    
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 yesterday

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 returns all the rows from the table.

share|improve this answer
    
Thank you for this... Seems like there are a lot of little commands that do things that could possibly harm you. Thanks. – XaolingBao yesterday
1  
Tried it, and this works on MySQL as well. – Anders yesterday
    
Could you explain why does ''OR(1=1)OR'a'='' return all rows? – Utku yesterday
    
@Utku because the SQL statement basically becomes SELECT * FROM PEOPLE WHERE 1=1. As 1 always equals 1, it becomes SELECT * FROM PEOPLE. – Neil yesterday
7  
@nocomprende Why? If you disallow comparing the same integer to itself - which probably does have some purpose to somebody, somewhere - then SQL injection will just be based on some more complex always-true condition that can't be detected by the optimizer. The road to security does not involve special casing a bunch of behavior and making the DBMS harder to reason about. – Chris Hayes 22 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.