Malicious Injection — It's Not Just For SQL Anymore 119
nywanna writes "When most people think of malicious injection, they think of SQL injection. The fact is, if you are using XML documents or an LDAP directory, you are just as vulnerable to a malicious injection as you would be using SQL. Bryan Sullivan looks at the different types of malicious code injections and examines the very basics of preventing these injections."
pr0n (Score:5, Funny)
Come on now, considering your audience, you might want to re-think that statement.
Re:pr0n (Score:5, Funny)
Yeah. Malicious Injection was a pretty good flick. I can't wait for Malicious Injection: The SQL.
Re: (Score:1)
Re: (Score:3, Funny)
Available soon on VHS, DVD and ODBC...
Re: (Score:1)
That has to be the funniest thing I have heard all day. I can just see that on a T-Shirt.
Re: (Score:2)
Seriously (Score:1)
Re: (Score:3, Insightful)
This has been true since the dawn of programming. NEVER trust the user. Oh before it was just entering text when the program expected an integer, or a negative value when it expected a positive etc. Now we don't get "? Redo from start" errors that crash the BASIC programs. But it's essentially the same thing. Never expect the user will cooperate with the program. Especially a program that is available to potentially
Re: (Score:2)
Re: (Score:2, Troll)
Re: (Score:2)
This statement is almost always wrong. While there are occasionally cases where certain information simply cannot be represented in a particular (poorly-designed) system, most of the time you need to properly encode the data, rather than "checking" it for "dangerousness".
Re: (Score:2)
Old news (Score:4, Insightful)
More old news (Score:4, Insightful)
From TFA:
Seems simple enough, but it's amazing how often this is ignored or implemented badly.
Re:More old news (Score:4, Informative)
If your parameter is a VALUE, it must remain a VALUE when you compose a command and proper escaping is the correct, reliable way.
Validating input may be helpful as another layer of security, but it's not the "only right way", it's not even the *right* way (in most cases).
Re: (Score:1, Informative)
Re: (Score:1, Informative)
Here's my tips for preventing SQL injection.
1) Use stored procedures!!!!!!!
2) escape your escape characters. i.e. in most statments a "'" is stored as "\'" so escape the \ so its stored as "\\'", it will invalidate the SQL statment because SQL will read it as "\'" instead of just "'"
2.5) an alternate to escaping characters is to just strip characters unnecessary to be passed with your stored procedure. i.e. strip all quotes, strip all double quotes, strip all equals signs, bash sig
Re: (Score:1, Interesting)
Re: (Score:3, Informative)
Using POST instead of GET doesn't make *any* difference. You can fake a POST request just as easily as a GET request. Please stop telling people that a POST is more secure...
Re: (Score:2)
Re:More old news (Score:4, Informative)
Here are mine that aren't garbage:
> 1) Use stored procedures!!!!!!!
"EXEC dbo.stored_procedure 'Oops'; DROP DATABASE foo; --'"
> 2) escape your escape characters. i.e. in most statments a "'" is stored as "\'" so escape the \ so its stored as "\\'", it will invalidate the SQL statment because SQL will read it as "\'" instead of just "'"
Not sure what you're talking about, but a literal apostrophe is quoted by doubling it in SQL. ' -> ''. However, don't quote -- you'll get it wrong. Use a proper mechanism instead, like prepared statements.
> 2.5) an alternate to escaping characters is to just strip characters unnecessary to be passed with your stored procedure. i.e. strip all quotes, strip all double quotes, strip all equals signs, bash signs, etc.
That's a great idea, until you need to store unicode or have a customer named "O'Reilly".
> 3) Do not send SQL parameters to your page in GET statements!!!!!! Either use session variables or POST statements, session variables are best.
Right, there's no way anyone can see hidden form fields! They're magical! (Also, session variables aren't "best". If you find the need to store SQL in a variable, your program is terribly designed and you need to rethink it. In this day and age of stored procedures and ORMs, you probably shouldn't have ANY SQL in your code.)
4) You should be secure, but if your not comfortable doing that, then provide additional validation.
Always validate -- it saves work later. If a user types 2-1234 as his phone number, and you store that, you won't be able to call him later, completely defeating the purpose of asking him for the data.
If you're not sure that you can remember to validate everything, use a language that taints incoming data and kills the program when you use it. In perl, turning on taint mode will prevent the common pattern of:
my $value = CGI->param('foo');
$dbh->do("SELECT * FROM foo WHERE bar = $value");
and even:
$sth = $dbh->prepare('SELECT * FROM foo WHERE bar = ?');
$sth->execute($value);
Since you didn't validate $value, you can't use it (correctly or incorrectly).
Hope this helps.
Comment removed (Score:4, Informative)
Re: (Score:2, Informative)
Yeah...PHP.
Don't worry about injection vulnerabilities in LAMP -- just don't forget to use mysql_real_escape_string() and not mysql_escape_string()!
The next rev will no doubt include mysql_really_real_escape_string().
Re: (Score:1)
Since the dawn of time, there have been positional markers for SQL. SELECT * from bar where baz=? . This way, You not only allow the ' and \ and other characters to enter the DB unaltered (as they should!), but also You protect yourself from trivial SQL injection by not composing queries.
However, people assume (the ass-You-Me), that once it's in SQL server, it is safe. Many stored procedures use dynamic queries (EXECUTE 'SELECT * from bar where baz='''||somevalue'''';) and do not do escaping (pg has
Re: (Score:1)
Using bound parameters, as the previous post suggested, is the correct way to mitigate SQL injection.
Re: (Score:2)
Re: (Score:3, Informative)
Escaping values only brings up new vulnerabilities. In database servers these are known as SQL truncation, and are the byproduct of buffer overruns in system functions (such as QUOTENAME and PATINDEX in T-SQL). These truncation attacks affect even parameterized queries, and the ubiquitous sp_executesql system stored procedure. I won't go into the details. All the info you need is is BOL
Re: (Score:2)
Oh please... if you really were a "senior programmer" you wouldn't do this kind of jokes, let alone of writing the stuff you wrote.
A DBMS which silently truncates an SQL statement is simply buggy. The vulnerability is in the DBMS, not in the interface. If the SQL statements is b
Re: (Score:1)
Re: (Score:2)
Re: (Score:2, Interesting)
Forget making quotes illegal (the irish will thank you) and forget trying to second-guess every possible problem by escaping the all the stuff YOU are smart enough to forsee problems with (leaving holes for people smarter than you).
Just ensure that your programs and user inputs never get mixed together. For example, use parameterized SQL. Or put user input into a file and
My rock-solid solution to the injection problem... (Score:5, Funny)
Re:My rock-solid solution to the injection problem (Score:2)
He thought of that... (Score:2, Funny)
know your system (Score:2, Insightful)
How come they are not well known to developers. Last time I checked if I dont use ldap somewhere along my lines
of codes I'm not in trouble of a ldap injection. Know your systems and check yours inputs! god damn!
Re: (Score:3, Insightful)
Personally I have never understood why people try to hack utilities like XPath into database equivalents. But I guess if you learn how to use a hammer and screwdriver, you might well refuse to learn how to handle a wrench because you can "make" things work with the wrong tools.
Or perhaps it's a negative side-effect of object reuse fanatics who don't consider that reusability does not necessarily mean eliminating alternate implementations, but enforcing an appropriately designed and narrowed interface in
XML Logic Is Flawed (Score:5, Informative)
Bob
Re:XML Logic Is Flawed (Score:4, Insightful)
Re:XML Logic Is Flawed (Score:4, Insightful)
Bob
Re: (Score:1, Informative)
Validate this (Score:4, Insightful)
RE: validating input fields...
I can't help but feel that most developers have at least a little common sense and do something along those lines anyway.
I often write little validate_input(char *string, char *format) that checks all input string from a user are simple, but more often than not very effective. How is this any different from using white and black lists. Any coder worth their salt would do something to stop malicious input, but no one in completely infallible.
Security of anything in this world is near on impossible. Hackers will get around anything given time.
Re: (Score:2)
Maybe most do, but there's been TONS of unvalidated input in programs since the dawn of time and there are no signs that will stop any time soon.
Re:Validate this (Score:5, Informative)
> I can't help but feel that most developers have at least a little common sense and do something along those lines anyway.
I hope that most developers have the common sense to take the correct approach: avoid injection problems by proper quoting! There is no need to validate the data, you just have to make sure that it stays data when you parse it on. Just use the proper library functions, and you will be fine (especially if you use hex encoding
White lists are a good idea if you don't trust you quoting, or if you need to verify the input for another reason. Black lists are most certainly not a good idea. Just imagine that the web shop tries to sell a product called "Selecta[tm]", but you block all attempts to buy it because it matches your black word "SELECT"
P.S.: Anybody with an apostrophe in their name naturally develops an unsatisfiable urge to kill web programmers.
Re: (Score:2)
And I would hope that developers (especially language developers) would realize that the really correct approach is not to glue SQL statements together from fixed strings and quoted arguments, but to use prepared statements with placeholders and arguments passed as a list.
This is no problem with languages providing a full API to SQL, but in kludges like PHP it has been difficult for a lo
Re: (Score:1)
http://www.php.net/pdo [php.net]
Re: (Score:2)
Re: (Score:1)
The reason it didn't have it from the start is probably due to the same factors that led to nearly all of the major exploit classes... no one thought of the issue that resulted in the exploits. If we start way back in the beginning ("Smashing the Stack for Fun and Profit") there just wasn't much consideration given to the idea that data could result in malicious code execution.
Re: (Score:2)
Re: (Score:2)
To be fair, the original article is about XPath and LDAP injection. As far as I know, there is no alternative to "brutal" string operations here. Around SQL you have a number of (not nice but) working data binding APIs, but for many new languages you do not have that (yet).
Sometimes you have to use quoting, and you
Re: (Score:2)
The client was having problems editing a certain record in the db, and after much investigation I discovered that any record that had the words "insert into" in it would make the submit form die completely. Annoying to say the least.
I'll leave it to your imaginations as to what kind of web site would have the term "insert into" in news articles so as to leave my client's anonymity re
Re: (Score:1)
Re: (Score:2)
If you do it with uncommon sense, though, it can go horribly wrong [thedailywtf.com]...
I think DOS attacks are more common (Score:1)
By the looks of the server, I would say DOS attacks are more common
It may sound trite, but... (Score:4, Interesting)
I recently attended a Microsoft-sponsored seminar on web site security at the DeVry Institute in Decatur, GA.
One of the speakers was a man from SPI Dynamics (sorry, forgot his name). He demonstrated how Microsoft's tools make it very easy to expose a database to the web, but how the same tools make exploiting the database very easy. He demonstrated an application that used SQL injection to first reverse-engineer the schema of an exposed database, and then the data in the database. It was quite a revelation.
Comment removed (Score:5, Insightful)
Re: (Score:2)
I think the point is that... (Score:3, Informative)
Hope this helps.
Re: (Score:3, Interesting)
Actually, you can't. There are several things about SQL-Server databases that makes buttfucking them particularly easy:
Re: (Score:1)
--Ram
I agree (Score:2)
Re: (Score:3, Insightful)
Call it code injection (Score:1)
Re: (Score:1)
Except, of course, the problem of too many levels of indirection makeing either coding or running the code to slow.
Re: (Score:2)
But that's not a problem in computer science - it's a problem in software engineering. :P
If you only knew the POWER of languages (Score:4, Informative)
Heh, remember when we had binary file formats and protocols, fixed-length fields (didn't need delimiters), and there was no parsing or worrying about "escaping" data? We didn't have these problems.
Anyway, I like this article because it admits that whitelists are better than blacklists. You have to validate data: make sure it is known to be non-harmful, rather than looking for whatever problems that you have imagined so far. You'll never guess all the things that can go wrong; you just know what is right.
Re: (Score:1, Insightful)
That's not exactly true. There are multiple ways to break parsers by entering bogus data even into fixed length fields. For example, there were several bugs in password and user configuration utilities that took advantage of the parser not correctly handling delimiters embedded in user input. Some even took advant
Re: (Score:1)
No kidding. I remember when everything in the world didn't need to be an "Application Framework" and code was fast and small and reliable and easy to fix.
This is a VERY important validation lesson (Score:1)
Negative matching is relatively infinite. Negative matching is why most spam filters can't stop spam reliably. Blacklists collapse under their own weight.
Phishers like frame injections (Score:5, Interesting)
Re: (Score:2)
Re: (Score:2)
Phishers have been known to use frame injections to insert their content into framesets, allowing them to grab login info from within the bank's own web site [netcraft.com]. It's not nearly as fancy as an SQL injection, but it's sure malicious and quite difficult for victims to recognize.
Quite difficult for victims to recognize, but easier for the bank to spot in their logfiles (... and fix, before the fraudsters can make much money from it)
Defensive Programming (Score:3, Funny)
Ignorance (Score:1, Insightful)
Re: (Score:2)
One should only attempt that when the language provides a quoting function like addslashes in php, so that you at least can leave the task of identifying the quotation marks to someone who knows a bit about thinks like UTF and other tricks to hide them.
Re: (Score:2, Interesting)
Re:Ignorance (Score:4, Insightful)
I suppose an apt analogy would be saying that it's ok to allow infectious material into a building as long as it is first correctly sealed in a bio-safe container - well that's true as long as you're sure the janitor isn't going to open it up later that evening and use it for a cookie jar.
Re: (Score:2)
So what would you propose as a solution to that? Not allowing any quotes in any strings?
In the scenario you describe the fault clearly lies with the "trainee down the hall", and the fix should be to his code, not to the code that correctly inserted the data in the first place.
Validation is important, but it's for ensuring data integrity not for security.
Re: (Score:1)
Re: (Score:2)
Certainly you should constrain input to valid values, but if quotes are valid then it's not going to do you much good on its own. Validation of user input is primarily for data integrity, not security. Sometimes it helps with security by coincidence, but you can't rely on that.
Re: (Score:2)
In the case of SQL, a much better solution is using bind variables. In addition to being totally invulnerable to injection attacks, they improve the efficiency of your queries (since the database engine can recognize when queries differ only in data, and cache its plan).
Email header injection attack (Score:5, Interesting)
A webmaster hosts a contact form on his website that allows users to fill out a form to contact him. He allows the user to specify a subject and a message but the recipient is hard coded to webmaster@example.com.
The message ends up looking like this:
Where $subject and $message are captured from the user on the website.If the $subject is not properly sanitized, a bot could submit it with a new line in it and be able to start a new line in the headers of the email. That new line could be, for example, a large CC list of people to spam with his message:
Which is why I would suggest using a contact form such as the one that I have written [ostermiller.org] that has already thought about this sort of thing.
Re: (Score:2)
Re: (Score:2)
Of course, it would make the email look ugly, but it wouldn't actually go to the spammed people.
Wash it before you eat it (Score:4, Interesting)
It's a simple matter of hygiene:
Wash it before you eat it.
All data read from external sources must be validated before being used. In some languages/frameworks this is as hard as nails (ie. I programmed a pretty large web application with only straight CGI programs written in pure Unix/C), in some you have help (Perl with taint), in some it's kinda-sorta-almost not an issue (PHP with Agavi and Creole).
If I had to choose, I would have to say that the middle way, the Perl way, is the best. It does not pretend to solve all your problems for you, even when it can't really. Rather it brings the problems at hand to your attention. Problems surface, fix problems, code gets better.
Untrusthworthy user shocks millions; news at 11 (Score:1)
> Many people mistakenly think that they are safe from malicious code injection attacks because they have firewalls or SSL encryption.
> While establishing a list of "bad" input values that should be blocked (a blacklist) may seem like an appropriate first step, this approach is extremely limited.
I laughed at these two sentences. Are there really people who need to be told this?
Re: (Score:2)
Run away! (Score:2)
What about AJAX injection? (Score:1)
Simple solution... (Score:2)
Obviously make sure data is scrubbed prior to putting it anywhere near a query, but make sure you have an account which can only read, an account which can only write/update tables, and a final one which can delete records in tables.
The end result is that even if an ingenious user finds a way to get a DROP statement past your scrubbing, they won't be able to do anything useful in most cases since the account running the query only has permission to
Developers (Score:1)
Check All User Input w/Regular Expressions (Score:3, Informative)
It Has Never Been Just For SQL (Score:2)
Malicious injection has never been just for SQL. Format string vulnerabilities (where format strings are passed into a program from untrustworthy sources), cross-site scripting vulnerabilities, and many other injection vulnerabilities have existed for a long time, probably longer than SQL injection vulnerabilities have.
Good article, but... (Score:1)
Validation Is Not the Solution (Score:3, Insightful)
The solution I've been championing is structured composition. Instead of verifying that the input won't alter the structure of whatever you're composing, you use APIs that ensure that this won't happen. Some examples of this, as well as other bug-eliminating language/library features, can be found in my essay Better Languages for Better Software [inglorion.net].
I fail to see how this CANNOT be avoided! (Score:1)
No matter what sort of input devide you use, does the following not seem to hold true:
Lets say you are running a simple capture of FName,LName,Address,City,St,Zip, let each be an input to a PHP Script beased on a web form.
Your SQl statement will consist of the following in the PHP Script: .= "values($FName,$LName,$Address,$City,$State,$Zip)" ;
$Query = "insert into NewContact (Firstname,Lastname,Address,City,State,zip)";
$Query
Now scrubbed or unscrubbed how can this insert result in anything other the
Re: (Score:2)
Precisely what you'd do to conduct an attack depends on your DB access API and the DBMS in use, but let's assume for a moment that we're using an API that allows us to have multiple queries in one call. This would be daft design, but it's true of many. Now imagine that your variable $Zip contains the following:
This ends the insert query, which will presumably complete successfully, and then inserts a completely different query.
Even if your API doesn't allow multiple
How I'd do stuff (Score:4, Informative)
Anyway, my suggestion has always been to do something like the following:
Inputs to your program
|||
Corresponding Input filters
|||
Your program
|||
Corresponding Output filters
|||
Outputs from your program
|||
Stuff receiving the outputs
You have a different "input filter" for each class of input so that your program can handle those inputs correctly.
Then you have a different output filter (e.g. SQL bind vars, HTML, XML) so that the stuff receiving your outputs (browser, database, viewer, etc) will handle them correctly.
NEVER do stuff like magic quotes (PHP is one of the worst and most braindead language in popular use) - mixing input and output filtering is so wrong it isn't funny (there are so many other things PHP does wrong that it's almost criminal).
Depending on the circumstances your program could output a single quote ' differently e.g. %27 for a cgi parameter, '' for Oracle data and \' for MySQL data (BTW MySQL is the PHP of databases). So it should be obvious that "one size fits all" doesn't work.
By filtering I mean quoting/encoding sanity checking etc - whatever it takes to get the data in a suitable form (with hopefully minimal data loss/corruption).
Re: (Score:1)
A lot of poorly coded applications dynamically assemble SQL statements with user supplied input - for example, when asking for their user name. E.g. (in pseudo-SQL:)
SET @StatementToExecute = "SELECT FullName FROM Users WHERE UserName ='" + @UserNameInputByUser + '"'
EXEC @StatementToExecute
If a user just supplies a username here, the statement that is assembled will do the ri