How Prevalent Are SQL Injection Vulnerabilities?
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.
destroys thousands of lives a year. Sure, it starts small - a SELECT there, a few INSERTS on the weekend. Eventually, though, you're using stored procedures and trying to score triggers in the middle of the night.
Just say no, kids.
This is a possibility that was obvious back when I was developing web applications as far back as 1996 using CGI. The approach in TFA was a similar approach we used "back when" to demonstrate the need for (a) not using GET, (b) turning off verbose error reporting, (c) controlling *how* queries were made (e.g. architecture of the app and DB I/O), and (d) storing sensitive data encrypted. The sad part is that it is *still* a problem. I guess it underscores the need for a decent architect as opposed to letting whiz-bang do-it-yourselfers start coding without design, and the need for security analysis, et. Al. Just my 2 cents.
The simple solution is to use parameterized queries. I don't know why more books don't know why more books don't push this methodology, as it makes you program faster, easier to read, and also makes you invulnerable to SQL injection attacks.
Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
The fact that tools can be used to put up insecure sites is not exactly a failing of the tool. The tool will have had a spec (even an informal spec) - which may have been "put sites up fast and let users sort out the security".
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 disclaimer of what it does or doesnt do and a guide to helping you with the rest of the steps.
When those things exist the fault is with the user and not with the tool - elitism aside. It's like using a hammer to kill a man (despite the do not kill people with this hammer label and 100 page guide to not killing people with hammers - now with pictures!) and blaming people killed with hammers on the hammer designer.
Think of the Children; Sleep with your Sister
This is exactly why I use NanoBlogger.
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.
Won't work. The same 'novices' who leave gaping SQL injection holes will now be writing pages that need to access the file system. Now instead of accessing the DB, script kiddies will be traversing the filesystem. Yes, this can be mitigated through file permissions, but there are a lot of servers out there (set up by these same novices) where processes run as root and would have full access to read and write files. So, a bad script could allow them to write to /etc/passwd and have all sorts of fun.
Stupid application construction isn't a good reason to make the design of the app even stupider.
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 for this kind of attack), to provide extra checks at the database level (for integrity issues, perhaps in the form of constraints, etc. dependent on the scale and structure of the database), and to develop tools/libraries for data access that make this kind of thing hard to do accidently.
Why convert to an entirely different structure when just implimenting proper code standards will suffice? Using parameterized stored procedure calls instead of dynamic SQL will not only protect you from the vast majority of SQL Injection attacks, but will also improve the performance of your web page.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
How do a) and b) help?
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 annoyed with "click ok to repost" prompts.
Of course one shouldn't use GET when confidential parameters are being sent (since it could appear in url histories etc), but GET allows users to bookmark a page or query, and in many cases that's a plus.
In short, trusting the client (i.e. the web browser) to not send bad values - either through the INPUT tag's maxlength attribute, JavaScript scrubbing or whatever - is entirely the wrong way to go. The web script must check all user input for validity along with properly escaping everything from the database that's getting sent back via HTML.
Ita erat quando hic adveni.
That's a valid point, but doesn't contradict mine. If the server, by default, doesn't accept special characters in a password field, then that fixes most of these problems. Obviously, the password field isn't the only place where you can muck with the SQL, but if you're getting malformed fields from a valid userid and password, then you are much further along the path to shutting out the problem user who misused or had his access compromised. Cheers.
"Don't you know you're going to shock the monkey?"- Peter Gabriel
I don't think you understand SQL Injection at all.
:)
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 whatever every time I use my car or get home. But I do.
Luckily you can create pretty safe code by making nice code. It's amazing how many side-effects "nice" has. But yes, you'd need to be a good programmer to make nice code.
There should be some kind of government run website somewhere.
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.
Beep beep.
Hello? Has the Net gotten so crime-ridden that instead of blaming criminals for doing illegal things, that we're now blaming developers? I mean, sure developers need to do all they can, but at what point do we, as a society say, "Hey, let's prosecute some of these assholes that are making life online a royal pain in the ass?" It's pretty absurd that today, you can still do whatever you'd like online (hack sites, networks, steal information), and there are really no repurcussions. We see what, one person getting jail time every 6 months? That's fucking insane. It's time for our government's law enforcement to step up to the plate, learn what the fuck a mouse is, and start prosecuting some of these people. Email is already useless. The web is getting there pretty quickly. SQL injection, firewalls, blah, blah blah.
If I have somebody who is constantly trying to break into my house, to the extent that I have to pay a security professional just to keep them bastards out, I'd be down at the police station talking to the police chief, angry as hell. As is, people have come to accept that there's almost more crime than legitimate traffic on the Net these days. That's insane. Something has to be done about this mess before the entire Net is just useless.
This 11% was determine by a weak testing mechanism. For every site that baltently spews sql errors to the user there are two that silently return a generic sanitized error, and another two that return no error at all. It would produce more results if you take it a step further and ask yes no questions, such as:
?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%.
From the article:
...
* 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 exposed the customers to the posibility of serious financial damage.
So far, the stupidest work arounds i've seen have been:
Developer: It's ok, I'll switch to post instead of get so the user can't forge the request.
Developer: It's ok, I'll write a method that removes sinlge quotes for every string i get from the user.
Developer: It's ok, I'll write some java script that will validate user input.
Writing secure software is never easy.
moi
There's no need to go back to the stone age. Just use prepared statements/parameterized queries (along with the usual stuff like validating user input client *AND* server-side)
///<sig
If the server, by default, doesn't accept special characters in a password field, then that fixes most of these problems.
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 getting malformed fields from a valid userid and password, then you are much further along the path to shutting out the problem user who misused or had his access compromised.
You can hit SQL Injection problems by using the system exactly as you are ment to, for example if your name is O'Reily.
No worries. First, let me say IANAWD (I am not a web developer). It would not surprise me at all if my understanding of SQL injection vulnerabilities is less than yours. My understanding is that a SQL injection vulnerablity is when a user submits input to an interpreter that subverts the original intent of the script and produces a different result. I.E. I enter ' or '' = '' as the password field and that is passed through to SQL interpreter to read "where userid = 'user' and password = '' or '' = ''" I'm sure this is just one example of injection vulnerabilities, but by my understanding it's the most common form. What's your understanding? Instead of saying I'm ignant, edumacate me! I'd do the same for you. I'd bet any misunderstandings I have on the matter matches a sizable percentage of slashdot readers, hopefully mostly people in the same boat as myself who don't really need to the knowledge, just try to keep up with things. Cheers.
"Don't you know you're going to shock the monkey?"- Peter Gabriel
If anything, I'd question how FEW sites they claim are vulnerable to SQL injection. It's an insidious problem that just creeps up on you anytime you don't think about it sufficiently (as when writing something quickly, on a deadline... not that this ever happens!). I know that at my workplace we fell victim at one point to a SQL injection attack on one of our (many) custom PHP scripts. We eventually found out how it worked through the web logs and were able to fix it, but honestly even after we did our best to clean things up... I'm dead certain that there are still probably hundreds of places that we're still vulnerable. This is due to a number things including the sheer volume of PHP code in use, the fact that the code has been written at various points in time over a period of six years or so, and the fact that this code has been written by at least twenty different people. It's like trying to plug holes in a dam.
Isn't that called XML?
As some others have pointed out, there are tools to get around that sort of thing. You should be validating all input server side, whether it's validated client side or not. There are also very easy ways to deal with SQL injection already, such as parameterized stored procedures. Doing what you suggest would involve a hell of a lot of recoding, break a hell of a lot of existing sites, and proceed to punish good coders by making them work around the "safe-guard". Programmers who don't take steps to protect against SQL injection deserve to have their sites hacked. And guess what? If they have their sites hacked, they'll probably remember to do something about it in the future, or hire someone who already knows how.
I may sound like an elitist by saying the following, but secure programming should not be "easy" for the "masses". It should be reserved for those who know what the hell they're doing, and they should be paid accordingly. I do not believe it's wise to give the average Joe the tools to make even slightly sophisticated programs. We've seen what happens when we do this; take a look at most websites from the dotcom bubble.
Everything I say is a lie. Except that... and that... and that, and that, and that, and that... and that.
This is kind of like saying we can prevent buffer overflow exploits by having the windows API not allow people to enter shellcode into textboxes.
All the HTML standards in the world won't stop an attacker with a copy of telnet.
/vulnerable_app.php?id=%2310 HTTP/1.1
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.
For a blog with 15,000 entries and 5 MB of data, why does it matter? It fits in memory either way, and doing stupid mechanical queries is going to be 'fast enough', and not terribly complicated in the code. Sure, if you know SQL it's dandy, but it smacks of overengineering for a blog app.
Nerd rage is the funniest rage.
Why are the point and click or turn key solutions so vulnerable to SQL injection in the first place? I had a friend with a PHPBB site that got shot to all hell when some cracker came along and defaced it. Why wasn't it secure out of the box? Second of all, why is it that every website has to worry so much about security. I know about databases but I don't know the first thing about preventing an SQL injection attack and why should I have to. There is nothing sensative on my sites. Let me throw out this analogy.
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?
For a blog with 15,000 entries and 5MB of data, use Blogger or Typepad.
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.
I've worked in web development a while and I find a SQL injection vulnerability in about 90% of the sites I've seen.
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.
Absolutely. Here are some rules to defend at multiple layers against SQL injections (using SQL Server as an example; YMMV on other DB servers):
- 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. and force all developers to communicate with the DB through those functions/objects
- Inside the functions/objects, use parametrized queries for calling all SPs and SELECTs on views in order to avoid any potential for evil
This way, if someone messes something up at one level, the other two levels are hopefully there to protect against any potential vulnerability. Also remember to, if possible, never store DB authentication information in plain text.
I claim first use of "Error No. 0B" - or "No. 0B error." It'll be the new ID 10T!
Alright, back to my PHB duties, but if we only proposed solutions for things we know about, then we'd all still be picking termites out of logs with twigs. I still hold to my fundamental belief that some things are meant for professionals, ie installing ATM machines, and some things are meant for everyone, ie posting websites, and the level of safeguards has to take that into account. Some people may feel that the web should belong to the trained professionals, but personally, I'd rather see a lot of crappy personal and community webpages than a few properly formed and secured corporate and government sites. You may disagree, and probably do, but I'm right. :)
"Don't you know you're going to shock the monkey?"- Peter Gabriel
That, and/or bind, bind, bind. Concatenating user input into your SQL statements is bad on both security and performance.
There's nothing wrong with the Joe Sixpack building his own website. The web wouldn't be what it is today, if it weren't for that. However, there is a problem with him developing software on systems open to the world.
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.
This certainly seems to me to be a problem that needs to be addressed at the html standard level
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 file upload dialog or any other HTML form control. An HTTP POST is an HTTP POST.
And without knowing what the server plans to do with the data once submitted (which the client has no reason to need to know), how does one define what "special characters" are? A string that's going to be inserted into an SQL database has a different set of special chars than one that's going to be used as part of a filepath on a Windows box, which is different than one that's going to be used as part of a filepath on a Unix box, which is different than one that's just going to be compared against another string.
Business logic does not belong on the client side.
There are a lot of new programmers [...] who are not naturally paranoid and sensitive to the exploitation of their code. They shouldn't need to be.
The hell they shouldn't.
Programming consists of more than just typing out some PHP code that doesn't cause a fatal error when executed. A programmer needs to be conscious of the expected inputs and outputs of any piece of code he/she is responsible for, and aware of the ramifications when those expectations are not met.
A person who does not exercise such diligence should not be considered a programmer.
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 wants to fuck with your server.
"The way we can tell it's C# instead of Haskell is because it's nine lines instead of two." -- wadler
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: people are confusing arbitrary data with fragments of SQL. The former should be passed in through bind variables - or escaped if you're hellbent on destroying your performance - while the latter should be executed directly. It's fortunate for the O'Malleys out there that this mistake is a huge security hole, or they would be rejected by any kind of automated system. People barely care about security; they certainly don't care about "lesser" bugs.
I often see people claim you just check for bad characters - either specific lists of punctuation or anything outside the alphanumeric range - because you can't possibly get all of your database code right. That's an incredibly wrong idea:
Going through my bachelors, we all learned the same things, yet there were always people that had unsecure code. It didn't come down to "just not getting it". It was more that they were lazy and wanted it done fast.
I use parameterized SQL queries so the notion of having to check/escape something as simple as single quotes hadn't occured to me. I was thinking more along the lines of ensuring user entries match the necessary encoding and maximum length. For instance, if my web forms want UTF-8 encoded output, is the user sending me UTF-8 encoded data? Or if I want the name field to be a maximum of 50 chars in the database, does the encoded string fit?
A little automated input fuzzing doesn't hurt, either.
Ita erat quando hic adveni.
Your post made me curious about how Google does it via their Search by Number feature. For example, if you search Google for "usps " plus your tracking number (or just the number), the results will be preceded by a link to "Track USPS package..." I suppose your widget could use Google's custom redirect script, but why is the functionality restricted to Google?
Sounds like even more incentive to use a good object to relational framework like Toplink or Hibernate.
ATM = Automatic Teller Machines
"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)
"But this one goes to 11!"
What I don't understand is how an SQL error message makes you vulnerable to a SQL Injection attack? Even if you are able to find out some of the tables and fields in a web-accessible database, you don't have the password to be able to execute your own queries...Is there just an assumption here that anybody stupid enough to allow a verbose error message like that would also have a database password like '12345'?
ZuluPad, the wiki notepad on crack
In the case of .Net languages... Parameterized Queries. should note, that the parameter formatting is slightly different for other database systems.
Michael J. Ryan - tracker1.info
Basically, your code will send an SQL query like this:
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 DATABASE DBNAME;
This would have the effect (with poetic license) of performing the first query as expected and then deleting the database, destroying the website.
The way to get around this basic instance would be to convert the userID parameter to an integer, forcing a failure before the SQL is reached. This could be done in java with Integer.parseInt(userID). However, this does not protect against bad characters in Strings so is not a total solution.
The total solution is to use a parameterised statement (preparedstatements are very useful for other reasons and are one of the ways to get this advantage too). In a preparedstatement for instance, you would say:
thisstatement = "SELECT * FROM USERS WHERE USER_ID=?";
thisstatement.setInt(1,userID)
which sanitises the query using setInt setString setDate or whatever. This will escape the invalid chararacters (such as ') so you can still have any character in a field, like O'Hare for a name, but it will not lead to an SQL injection.
On a related note, another vulnerability I see a lot is when people do updates or deletes using a table with multiple keys. If for instance you have multiple sites sharing a common database such as:
SITE_ID, USER_ID, USERNAME
with the 2 IDs as a PK, doing a simple update on USER_ID is not secure. Even if USER_ID comes from a hidden form field it is still easy for a malicious user to manipulate and change to something else. If you have a multiple PK, you must practically always use both fields when updating/editing/adding.
Note that I have over simplified things but this should give the general gist of the problems.
Warhammer forums
SELECT * FROM USERS WHERE USER_ID=1; DROP DATABASE DBNAME;
simple copy and paste error there oops
Warhammer forums
Well, I have verbose error messages turned on on my local dev server to make debugging easier, but we log all errors on the live site, returning an "oops! something went wrong" generic error to users. Verbose errors can give you a lot of information, depending on what the error is.
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. If i'm making reads to the filesystem or requiring files and I screw up the path, verbose error reporting will spit that path out. Now the hacker knows what your file system looks like, and possibly what kind of system you're using. Also, while the hacker is busy trying out various methods to inject SQL, verbose errors may spit out the entire failed query, giving them full knowledge of how to edit it to make it work...
All around, it's just a very bad thing.
The trick to exploiting SQL injection is being able to figure out the right sequence of input characters needed to gracefully terminate the intended SQL command, while also being able to craft a subsequent SQL query that does what you intend. Alternatively, you may want to modify the intended command. For example, "SELECT orderstatus FROM table where orderid = $FORM{'orderid'}" expects the orderid form field to be some value that's in the table somewhere. If instead you enter "1 OR 1=1" as your input, you'd get every row back since 1=1 for all rows. Using this example, you could also try to append a new query, by entering something like "1; drop database;". Many times an attacker will need to find various escape characters, quotes, etc. to get their input crafted properly to exploit the app.
SQL errors in web apps are what web crackers like to see for the same reason that exploit authors like to see segfaults where EIP=0x41414141.. it means that they were able to get their input down to the execution point in a program that got past the boilerplate protections that the app had in place (if any).
I am pretty new at PHP development, but not new to programming. I had to learn SQL on-the-spot and I'm aware of SQL injection attacks and the risks they pose.
We have implemented a DB wrapper that "escapes" user input for things like ' that would break out of the input. I also check the length on the server side to make sure they're not trying to overflow any of the variables. By the looks of many of these posts, that isn't an "acceptable" amount of protection and that procedures are a must.. Anyone care to inform me or refer me to a good website?
I went to eat some animal crackers and the box said, "Do not eat if seal is broken." I opened the box and sure enough..
If you search for "mdb" you can download the entire database without too much trouble.
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.
Once I was a four stone apology. Now I am two separate gorillas.
I've written about this before. Basically, SQL injection vulnerabilities would completely disappear if better APIs were used. The problem is that queries are composed as strings, which have no intrinsic structure. The programmer creates structure by inserting certain characters (in particular, single quotes) in the string. However, the exact same mechanism is used to add user-supplied data to the queries. Unless the programmer is very careful, this allows the user to affect the structure (and thus the effect) of the query. An example is in the essay I linked to.
Please correct me if I got my facts wrong.
Repeat after me kids: "GET and POST are equally tamperable and equally (in)secure. The only thing they are not, is equally logged".
Correct, SPs will not fix every possible exploit, but they will prevent someone from sticking a trunc command in to the middle of your dynamic select statement.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
Blame MySQL.
MySQL is not a database. It does not support Transactions. It doesn't use normal syntax. Why? Because it's easy. So a programmer who has better things to do than learning some arcane syntax can just get the job done and move on. Good? No!
It is because of this laziness that such attacks occur by someone who did take the time to learn the syntax. If people want a quick and dirty solution, so be it, but don't pretend to be a database and open all sorts or vulnerabilities.
The ease of SQL is made for people who take the time to learn it, and naturally code it securely. For those who don't have the time, just don't use SQL.
So, i blame MySQL (and its ilk) for this. And i can only laugh at the sites that get attacked because of their own laziness.
Have you read my journal today?
For instance, if my web forms want UTF-8 encoded output, is the user sending me UTF-8 encoded data? Or if I want the name field to be a maximum of 50 chars in the database, does the encoded string fit?
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!
Tedious Bloggy Stuff - hooray?
Comment removed based on user account deletion
>Even if you are able to find out some of the tables
>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.
It would not surprise me at all if my understanding of SQL injection vulnerabilities is less than yours.
;-)
:)
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
The solution is a combination of several good practices in software development. First of all: Make sure you know which data you can trust. Everything that comes from the user: Don't trust! Allow anything coming thru the front door, because you can't prevent it anyway,
First you validate the data. Let's assume worst case: You allow anything, there's nothing to validate.
Next: Insert it into the SQL in a way that can't hurt. (Escape it correctly...)
An extra way to take care of this: Separate your software in layers. Have all database/SQL-stuff in it's own layer. Study "Layers pattern", sorry no links.
Then you can define exactly how data should look with traversing thru the layers, and it's a lot easier to make sure that everything is validated, transformed, converted etc. at the right time.
SELECTing `userID` when it's undefined really isn't a problem. Had you WHERE'd correctly (`userID` again, not just `user`), though, it'd have been a perfect demonstration of one of the most fundamental injection attacks.
Remember kids, NEVER trust user input. Escape things until the key is broken, then make the computer do it for you automatically.
How are sites slashdotted when nobody reads TFAs?
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:
You can do far, far better than that in Lisp. A SQL query is essentially a list of column expressions (the SELECT), a list of table expressions (the FROM), and a predicate over the tables/aliases named in the FROM (the WHERE). It's pretty straightforward to represent these as embedded language in Lisp that constructs three-part objects that represent queries with symbolic expressions, and then write a little interpreter to generate SQL statements from the objects in question.
Once you have this, you get the really, really big win: you can write an operation to merge multiple query objects into one, that works as follows:
This approach allows you to write code that generates really complex queries in a piecemeal fashion; you can generate separate query objects for individual parts of your query in separate parts of the code, and then merge all the bits at the end into the finished query object, which you translate into a SQL string just before execution. Your embedded language can also take care of escaping automatically for you. You never deal with queries as strings at all.
And this is of course an approach that is limited by the need to support SQL as your target query language; if you didn't have that, you could do a much better query language embedded within Lisp to start with.
Are you adequate?
I'd mod you up, but I spent too much time telling other people to get a clue.
PS: try Spring framework or Hibernate, if you don't already and use Java...
some errors will return information from the table...like username and password. Others allow you to control the data from the attack and other give you root access after the error.
The Kruger Dunning explains most post on
I've seen Good sysadmins running a webserver in the debuger and tracing the entire process, while connecting to it with telnet to trouble-shoot particulary nasty problems.
Apocalypse Cancelled, Sorry, No Ticket Refunds
I just can't imagine that many web developers being so careful. Popular sites are relatively secure, and open source code like online forums are secure, but the security of write-once code you find on average sites is just horrible. Just search google for things like 'allinurl: "isadmin=0"' and you'll know what I mean.
Magic quotes! No more problem\'s!
henry -- the human evolution news relay
Which database and version are you using???
For the past 10 years in all the major mainstream databases you have not gotten a performance boost for using stored proceures with standard CRUD statements. In truth the use of stored procudures in CRUD with all the coaleses and if statements is actually is around 20%+ slower, when you start hitting 5+ possible variables, then a dynamic SQL statment using parameterized variables.
For login scripts:
"' or 1=1 --" -- can force a login to succeed in some systems
"' or password='' --" -- works on some systems where that doesn't
For data retrieval scripts:
"' or 1=1 --" -- retrieve all data from the database, not just the record asked for; this is a useful one.
For data update scripts:
"' or 1=1 --" -- update all records in the database, not just the one that's identified
There are many other variations on these.
Yes, not allowing multiple statements mitigates the vulnerability a little. But not a lot.
SPs? Stored procedures?
He's not talking about using stored procedures, he's talking about using bind parameters. You can still use "normal" SQL, it just prevents injection attacks.
It's official. Most of you are morons.
But anyway, web developers should not be using SQL any more, except in some very rare cases. We now have things like EJB3 and Hibernate which remove 99% of the need for any SQL within an application.
There are good reasons for using SQL over and above an object persistence layer (which is what I believe both of these are, although I've never used either). SQL is easier to search, easier to analyze in arbitrary ways, and easier to edit by hand if something goes wrong and the system needs fixing.
Hit Parent a few times. My first post was on using Store Procedures. An Anon Coward responded. The post you replied to was in response to the AC, not the guy talking about binding which yes, is another way to limit injection. Note that neither of these techniques will get you 100% protection however.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
If you ever find yourself writing SQL queries without prepared statements and bind variables, erase the code and rewrite it with prepared statements and bind variables.
If you still find yourself writing SQL queries without prepared statements and bind variables, slap yourself twice across the face--once for each cheek--and then erase the code and rewrite it with prepared statements and bind variables.
If you still find yourself writing SQL queries without prepared statements and bind variables, obtain a hammer and smash all of the fingers on one hand until they are no longer usable. Find a friend to smash the fingers on your other hand until they are no longer usable. Then, you can write no more lousy, insecure code.
They don't grade fathers, but if your daughter's a stripper, you fucked up. --Chris Rock
The fact is, code vulnerable to SQL-injection is database platform-independent. The vulnerability is at a higher level. Do you really think forcing these lazy people to use a "harder" database that takes more time to administer and learn will make them write secure front-end code? Hardly. It'll probably make the front-end code even more rushed.
You want no more SQL-injection? Use prepared statements and bind variables. If you roll your own input-escaping code, you'll foul it up. Doesn't matter what database you're using on the backend. If you foul it up, your Oracle database will be just as vulnerable as your MySQL database.
But please don't let that stop you from mindlessly ranting about MySQL.
They don't grade fathers, but if your daughter's a stripper, you fucked up. --Chris Rock