How Prevalent Are SQL Injection Vulnerabilities? 245
Krishna Dagli writes to tell us of an investigation, by Michael Sutton, attempting to get an estimate of how widespread SQL-injection vulnerabilities are among Web sites. Sutton made clever use of the Google API to turn up candidate vulnerable sites. You might quibble with his methodology (some posters on the blog site do), but he found that around 11% of sites are potentially vulnerable to SQL injection attacks. He believes the causes for this somewhat alarming situation include development texts that teach programmers insecure SQL syntax, and point-and-click tools that allow the untrained to put up database-backed sites.
The abuse of SQL injection (Score:5, Funny)
Just say no, kids.
Re: (Score:3)
Re:The abuse of SQL injection (Score:5, Insightful)
Unfortunately: Not Surpirsing (Score:5, Insightful)
Re:Unfortunately: Not Surpirsing (Score:5, Informative)
Re: (Score:3, Insightful)
Using POST doesn't make it any harder. It just makes the address bar less ugly.
IMHO, any web application should be written to accept both GET and POST. I'm very annoyed with USPS.com for this very reason. I have a small Dashboard widget that I use to track packages. Short of writing some custom redirect script on a server somewhere, I cannot construct a URL that I can use to create a clickable link to the tracking results.
I sent an email to the USPS webmaster and asked if there was anything they cou
Re: (Score:2)
Re: (Score:2)
You can't send a URL to another application with a POST request. If it isn't in the addressbar, it can't be part of a URL, so a Dashboard Widget can't make Safari display the page. So you only have three choices:
Re: (Score:2)
or even have java script go get the damn thing and return it back
What about Google's Search by Number? (Score:2)
Re:Unfortunately: Not Surpirsing (Score:4, Insightful)
No. Web applications should use GET and POST where appropriate - GET for idempotent requests (showing database records, search results, those kind of recurring, non-database-changing things) while POST should be used for things which actually change data, user state, and so on.
Using GET in the wrong places [slashdot.org] can lead to all kinds of irritations and miniature security problems. Imagine sending an email to your web application administrator containing something like the following: <img src="http://example.com/webapp/user_admin?action=
Many web applications do get the two horrendously mixed up (I've seen search results done via POST, which is subtly, incredibly annoying) but they're definitely not interchangeable.
For simply displaying a non-password-protected package shipment page, GET would probably be the best solution. But blindly accepting both isn't a good alternative.
Re: (Score:3, Insightful)
You are confusing idempotence and safety. "Idempotent" merely means that repeated requests have the same effect as a single request. You should use GET because it is safe, not because it is idempotent. For contrast, DELETE is an idempotent method, but it's certainly not a safe method. For
Re: (Score:2)
This seems to work:
http://trkcnfrm1.smi.usps.com/PTSInternetWeb/Inte
Re: (Score:2)
Thank you. Now why the &^#$^@ couldn't they have told me that instead of saying "Sorry, no GET url exists"!?! :-)
*sigh*
Re: (Score:2)
Re: (Score:2)
Just make $requestcontent what USPS expects and change the URL as appropriate a
Re: (Score:2)
And there's a good, good reason (which many of you probably already know). If your site is indexed by a search engine, and you don't have a proper robots.txt file in place (or the search-bot ignores it), the bot can trigger data changes. Ouch!
RFC 2616 doesn't say anything about proper use (Score:2, Informative)
Re: (Score:3, Informative)
"SELECT `userID`,`user`, `password` FROM `table` WHERE `user` = 'trim($_POST['user'])'"
Ack! Nice demonstration of the code that is vulnerable to attacks!
My user id is '; drop database; --
Not a problem (Score:2)
Remember kids, NEVER trust user input. Escape things until the key is broken, then make the computer do it for you automatically.
Re: (Score:2)
Re: (Score:3, Informative)
Huh? (Score:2)
Which "decent architect" designs a system where verbose error logs are sent to untrusted public users.
And which "decent architect" writes web apps where GET would inherently causes security problems.
In fact, post causes more problems if the target page doesn't issue a redirect, because then the form could be reposted. This shouldn't be a security problem of course (unless it's a login page), since duplicate posts should be handled gracefully. However with most browsers, users would be
Re: (Score:2)
WTF? GET has uses just as POST has uses. If a request is to be idempotent (read-only query), then it's a GET. Otherwise it's a POST (or a PUT, or a DELETE).
The fact that PHP fails at understanding HTTP doesn't mean that others do so too. For example, the web.py Python microframework behaves this way: you map URLs to classes, and these classes have any of 4 methods: GET, POST, PUT, DELETE (they can have others, but the others are not important). Each method is called when th
Re: (Score:2)
If you follow elementary "safe" coding conventions in Perl, Python or Ruby and use prepare() statements it is nearly impossible to write injectable code. I am saying "nearly" because there will always be an inventive idiot to write a code which can allow injection in any language.
Re: (Score:2)
At this point, I realized you didn't know what you are talking about, and stopped reading your comment.
Re: (Score:2)
Re: (Score:2)
whoo that was hard; all using POST is going to do is get you a slightly
Simple solution (Score:5, Insightful)
Re: (Score:2)
The other side of the coin, that people still forget about, also, is data that is queried and made for display in HTML browsers. Without
Re: (Score:2)
Re: (Score:2)
I guess it's because they're cumbersome. I found this example:
Re: (Score:2)
Re: (Score:2)
PHP is quite probably the single biggest cause of SQL injection attacks on the web.
Re: (Score:2)
It's quite possible to escape characters and be certain that they won't be bypassed.
but it is staggering how many choose not to do at lease strSQL.Replace(";","BLAHBLAH - SIMPLEINJECTDEFEAT"); before executing SQL. Nobody needs to allow ";" in any query.
Which is just retarded. There are many cases where the semi-colon ";" is perfectly legitimately used. For example, this comment contains a number of them. This comment will be saved to a database. Thus, the SQL statement contains
Point and click tools (Score:2)
It's only a failure of the tool, or the developer of the tool, if the tool is marked as being a one step solution. Of course a lot are, there is no shortage of snake oil salesmen, and in that case they take 100% of the blame. However most rapid deployment tools contain a clear disc
Some kind of software checklist (Score:5, Funny)
You would answer questions and it would give you license keys to software that you were qualified to use. For example, I might tick:
Engineer (check)
Artist ( )
Manager (check)
Linux (Check)
Mac ( )
Windows ( )
And it would issue keys for website point and click installation software, Vi, apache and Latex - but deny me keys to powerpoint thereby saving the lives of people who might otherwise have to gnaw off their own leg to survive my 8 hour presentation on optimising synergisyms in a web 3.0 environment by sub molecular interactions.
testing methods (Score:4, Insightful)
?id=99999' OR '10
and see if the page returns the results of id=10 as expected. It's also common for people to use weak regexp (regexp should NEVER be used to protect against sql injection, see mysql_real_escape_string) and miss some characters:
?id=99999)
or fail to sanitize non us language encoding. Also, get variables are often the most protected. It is much more common to find sql injection in <input type=hidden variables, or in cookie data. The number 11% is extremely low. I'd guess more like 80%.
Re: (Score:2)
Re: (Score:2)
In Perl and Ruby, variables are "tainted" if they come from outside, and can't be used in sql or system. Running a string through a regex is the preferred way to untaint it. Your mysql_real_escape_string is the equivalent of a simple regex anyway (replacing characters with \characters).
Does Python have a taint mode? I know that PHP doesn't (shame)
The "Oh-Sh*t" face... (Score:2, Insightful)
* Many development texts actually teach programmers insecure SQL syntax.
* Many sites are exposed to SQL injection attacks but don't know it.
I agree completely! I've seen the texts, I've seen the hordes of VB+SQL programmers that learned from said texts moving to the web porting the same "vices" to the new platform.
And I've seen the "oh-sh*t" face on a couple of developers after demonstrating to them that their software is vulnerable to SQL Injection. In both cases the vulnerabilities e
Re:The "Oh-Sh*t" face... (Score:4, Insightful)
Re: (Score:2)
Dunno why anyone would not use ObjectDataSources for their data in
Re:The "Oh-Sh*t" face... (Score:4, Informative)
It's easy if you use good tools. PHP is not a good tool. Rather than hacks like mysql_replace_the_string_with_things_that_wont_co
Some ideas:
Perl's DBI, whose docs tell you to ALWAYS write SQL like:
$sth = $dbh->preprare('SELECT foo,bar FROM baz WHERE something=? AND another = ?')
$sth->execute(q{''Some\ things"'}, 10);
Notice that the programmer can't forget to escape the SQL -- because there's no escaping.
Even better is something like DBIx::Class, which lets you write
$resultset = $table->search({something => q{''Some\ things"'}, another => 10});
Again, no opportunity for the programmer to fuck up the SQL in any way. It's just like getting data out of the hash... DBIx::Class will generate the SQL (for any backend), run the query, stream in the results as needed, etc. It's easier and it's better!
Ruby on Rail's ActiveRecord is similar, but it's impossible to do certain types of joins. DBIx::Class is better in this regard. (And Perl is faster than Rails, and Catalyst is more complete rhan Rails
PHP makes it easy to write insecure code. Perl makes it hard! (With taint mode, a selection of ORMs, 10000+ well-tested modules, and nicities like Moose, Moose::Autobox, etc.)
Re: (Score:3, Insightful)
Re: (Score:2)
I don't understand how this magically fixes things.
In your example (yes, I realise it is just that, a quick example) you have 10 which is a constant. Now clearly if you were just doing queries with constants then there is no danger in doing a straight SELECT * FROM table WHERE something=10!
So your example obviously needs to replace "10" with "$numeric_var", ie $sth->execute(q{''Some\ things"'},
Re: (Score:3, Informative)
Prepared statements aren't there to guarantee that every datum you insert is the "correct" type for what you're trying to do. What they do is guarantee that nothing in your variables will be interpreted as part of the SQL command.
If I have "10; <naughty stuff>" in $numeric_var, it will attempt to insert (or select, or whatever) exactly that string, without interpreting it. The data may be useless, but it will not be executed.
Re: (Score:3, Interesting)
Have you seen the 'oh, that's not a problem, we're using SSL so it's completely secure' face yet?
As for stupidest work-arounds - a site I was doing a vague security audit for (sans source-code, alas) was (is) rife with SQL injection vulnerabilities. On attempting to expl
Massively widespread problem (Score:4, Insightful)
Re: (Score:2)
If SQL injection attacks are creeping up on you, than you are using the wrong tools. If you are using any halfway decent database access library (and suing it correctly) SQL injection is a non-issues. Example, using Perl:
I know the same thing is possible in PHP (via PEAR:DB), although
Turn Key solutions broken? (Score:3, Insightful)
Let's say I own a house and around Christmas time I put out an inflatable snow man. Then some vandals come along and pop it. Are you going to walk up to me while I'm sulking over my snow man and say "Don't you know you have to wrap your snow man in kevlar to prevent vandalism and then put up an electified fence with constantine wire on it."? I would give you the strangest look if you did. Then I'd probably say something pertaining to the fact that the police should catch these bastards and presecute them.
So why is it with technology that no emphasis is put on catching vandals and bringing them to justice and a ton of emphasis is put on protecting your site from attack?
Re: (Score:2)
So why is it with technology that no emphasis is put on catching vandals and bringing them to justice and a ton of emphasis is put on protecting your site from attack?
Because currently the latter is FAR easier than the former.
While I generally agree with the sentiment that it's not the web developer doing anything wrong, it's the hacker who's wrong... I would also argue that while, by not caring enough about security, the developer may not be "wrong," he is perhaps being "unwise."
Re: (Score:2, Informative)
Re: (Score:2)
Which would you rather have: people vandalize your website, but they get caught, or people don't vandalize your website?
Re: (Score:2)
Re: (Score:2)
With PHP, virtually anyone can write a web forum. And lots of people do. Unfortunately, not all these people are good coders. Not all of them are aware of the security risks. And PHP doesn't provide particularly secure APIs for SQL (or at least it didn't when I last
This is way low (Score:2)
It is extremely common to have people just cut and paste the bare-bones tutorial code they find on the web and reuse that same pattern on every page in the site rather than centralizing it in a wrapper. So not only is the string not being cleaned, but it's also a huge pain to fix.
You don't need to bother with SQL Injection (Score:4, Interesting)
I recently came across a commercial site where you could substitute, for instance, "(select first_name from users where id=1)" into the page url and a nice error screen came up telling you that it couldn't convert "George" into an Integer.
It's not the SQL Injection per se that is the biggest problem, but the nice error messages you get back giving you, more or less, a SQL command line interface. Errors should be detected and redirected to a sanitized page, or if you can't be bothered, an unceremonious crash.
I notified the owners of that site by the way.
Better APIs (Score:2)
Re: (Score:2)
PHP doesn't.
Re: (Score:2)
SQL where the SQL statement is managed/handled separately from the
parameter values. It is more complicated and requires more programming
than just shoving a hand built query at the database but it much more
secure. ''
That's not the only option. In my essay it shows a Lisp macro that
allows you to write queries pretty much as normal, but that still
escapes any data that comes from variables. More convenient than the
parameterized query APIs I've
Re: (Score:2)
Re:Return of the Flat File (Score:4, Insightful)
No. That's a stupid idea. (Score:3, Insightful)
In the old days, everyone used flat files, because that's what there was. Then someone (several someones, most notably Codd and some others at IBM) realized that breaking the flat data into sets of discrete data that related to each other reduced redundancy and allowed for an overall better quality of data. And it wasn't app specific.
The answer to SQL injection is to test apps more completely (including tests f
Re: (Score:2)
- Run your web application as a user that connects to the database server and has rights only to SPs and views on the database; this works because the SPs and views have full access to database data, but the user can't access the data except through those pre-defined means
- Encapsulate calls to those SPs and views inside carefully constructed functions/objects/etc.
Re: (Score:2)
And, frankly, I don't think learning how to use the tools properly and how to test one's code is "overengineering." I think of it as competently programming the application. But I'm old fashioned.
Re:Return of the Flat File (Score:4, Insightful)
-Rick
Re:Return of the Flat File (Score:5, Informative)
Re: (Score:2)
Re: (Score:2)
-Rick
Re: (Score:2)
Re: (Score:2)
If the obvious fix is to exclude special characters from password fields, then why allow them by default to begin with?
Because that won't stop a wily hacker from using a tool such as curl to use those special characters as if they'd entered them in the password field. This has to be fixed at the server end, not the client end.
Re:Sure, blame the "untrained" developers.... (Score:4, Insightful)
Re: (Score:2)
Indeed, people need to understand that Javascript validation of forms is and should always be a courtesy to the user. It can always be avoided, and this means that client-side validation is done solely for the comfort of the user (so that he doesn't waste time making useless errorneous queries to the server).
This means that obtrusive client-side validations generating popups and shit everywhere are beyond stupid. Keep your JS error messages clear yet unobtrusive, because they will never stop someone who wa
Re: (Score:2)
It's not just "bad" values, unless you believe that all people with names like O'Malley are out to destroy your website. SQL Injection is a very simple problem: peopl
Re: (Score:2)
Try harking back to the good old days of programming, when men were real men, women were real women, and small furry creatures from Alpha Centauri knew how to write functions. Write something like this:
sql_string_sanitise( $string, $encoding, $max_length );
And you can do stuff like that, easily!
Re: (Score:2)
Likewise, so neither of us have the problem this article is talking about. CVE's #2 error (which accounts for 14% of all reported security problems, and is present in at least 11% of this guy's web site sample) is really that basic.
As for your checks, I do things a little differently:
Re: (Score:2)
Re: (Score:2)
But then you couldn't make good passwords. Also, the password field isn't the only... oh wait, you said that:
Obviously, the password field isn't the only place where you can muck with the SQL
Exactly. So maybe you can't write "O'Hare" as a password, but with your method you couldn't enter it as your name. You just can't disallow special characters as a generic solution.
but if you're gettin
Re: (Score:3, Informative)
If the obvious fix is to exclude special characters from password fields
It's not. First of all, it wouldn't work. Second, it makes to sense at all at any level. Sorry if I seem rude.
There are a lot of new programmers (or whatever we're calling people who make websites these days), who are not naturally paranoid and sensitive to the exploitation of their code. They shouldn't need to be.
I agree, but it's a dreamworld. I shouldn't need to fiddle with keys or
Re: (Score:2)
Re: (Score:2)
SELECT * FROM USERS WHERE USER_ID=3;
This might be assembled like this:
"SELECT * FROM USERS WHERE USER_ID=" + userID;
userID might be taken as a direct parameter from the front end and not sanitised. Even if user ID is a hidden form field, it would still be possible for someone to enter this (simplified for the sake of argument):
someurl.jsp?userID=1; DROP DATABASE DBNAME;
which would go through to your DB as:
SELECT * FROM USERS WHERE USER_ID=3; DROP DATABAS
Re: (Score:2)
SELECT * FROM USERS WHERE USER_ID=1; DROP DATABASE DBNAME;
simple copy and paste error there oops
Re: (Score:2)
It seemes that you understand the basics, but not the implications.
Instead of saying I'm ignant, edumacate me!
Here's some education: Don't get your education from slashdot!
But if you want to make sure you understand the basics of SQL Injection: http://en.wikipedia.org/wiki/Sql_injection [wikipedia.org]
The solution is a combination of several good practices in software development. First of all: Make sure you know whi
Re: (Score:2, Insightful)
Re: (Score:3, Funny)
Re: (Score:3, Insightful)
bash$ telnet example.com 80
GET
Two things to note here: (1) there's no HTML involved in the actual transaction at all (2) like another poster said: you can't trust the client to send valid data.
Stick to purposing solutions for things you know about.
Re: (Score:2)
Re: (Score:2)
Once you add executable code, and a database, it's not 'just a website' anymore. It's a program. And running amateurs' programs on the open internet is dangerous.
Re: (Score:3, Funny)
"ATM machines" = Automatic Teller Machines Machines - definitley leave it to the pros, otherwise you may screw up on your "PIN number"
(Apologies for being a pseudo-grammar Nazi)
Re: (Score:2)
I'm not following you. Why would a server-side exploit like SQL injection be addressed in a client-side display standard like HTML?
The 'type="password"' attribute of the HTML input element is nothing more than a style hint for the renderer -- characters typed into such an input should not echo back to the screen. Otherwise there's nothing that distinguishes it from a value taken from a text input, a checkbox, a
Re: (Score:2)
Considering somebody can break into your site from any one of a million unsecured WiFis from New York to Bangkok, i'd say prosecution is not going to be an effective method of deterrance.
Re: (Score:2, Informative)
It isn't hard to secure an online application against SQL injection. So there's no excuses for the developer to write 'SELECT blah FROM table WHERE field='$forminput';' directly in their code is there?
Your example should be about you going to the police station complaining because you don't have a lock on your door, not because you need a paid security guard.
Yes, I agree that hacking crimes should
Re: (Score:2)
Re: (Score:2)
The internet is like the Wild West, the Sherrif is a bit crooked, and the Marshal is over worked. The no-good dirty rotten cattle russelers have gotten to good at keeping a border between them and the law so sometime you just have to get yourself a hired-gun to even things up for a while. Of course if you've brought up a gun-slinger for a job, it helps to point'em in the right direction. So to do that I'm collected the domains and websites that
Re: (Score:2)
Re: (Score:2, Informative)
First of all, it's going to tell a hacker what kind of system you're using. They'll probably find out anyway if it isn't apparent, but who wants to give them any help along the way? And then it all depends on what the error is.
Why errors are good for crackers (Score:2, Insightful)
The trick to exploiting SQL injection is being able to figure out the right sequence of input characters needed
Re: (Score:2)
>and fields in a web-accessible database, you don't have
>the password to be able to execute your own queries...
If you can inject SQL, then *you* don't need the password. The web page sends the SQL to the database server.
Re: (Score:2)
Rookie mistake. But little do they know that will end up spending orders of magnitude more time trying to "fix" it in the future.
Although the context is different. The best programmers I know are the laziest ones. Not in that they don't do much work, but that they have extensive knowledge of tried and true libraries. They don't reinvent the wheel.
To bring this back full circle, being able to use both a modular AND mature filtering process would be a GIANT le