Anatomy of a SQL Injection Attack
Trailrunner7 writes "SQL injection has become perhaps the most widely used technique for compromising Web applications, thanks to both its relative simplicity and high success rate. It's not often that outsiders get a look at the way these attacks work, but a well-known researcher is providing just that. Rafal Los showed a skeptical group of executives just how quickly he could compromise one of their sites using SQL injection, and in the process found that the site had already been hacked and was serving the Zeus Trojan to visitors."
Los's original blog post has more and better illustrations, too.
One should definitely use a persistence library instead of concatenating strings to help mitigate the possibilities of being victim of SQL injections. They are pretty good at it. Hibernate is a widely used one.
Everything I write is lies, read between the lines.
...for these modern times.
Does my bum look big in this?
I for one am sick and tired of these types of attack. Whoever, in their right mind thought it was a good idea to expose SQL query inputs on the Web?
Ever heard of input sanity checking? It was very popular in the say, 60's, 70's and 80's. It means you reject fields you don't expect to be there, instead of arbitrarily passing them onto the backend database. These types of attacks illustrate what is wrong with web security: developer convenience trumps common sense everytime...
Next time we see Ballmer hopping along shouting developers, maybe could he please add the words 'SECURITY BY DESIGN', please, pretty please?
SQL injection attacks are asinine because they are so prevalent, easy for the hackers AND easy to fix. We should name and shame every site, and every web-application stack that allows these attacks to take place.
nuf said.
http://xkcd.com/327/
I have been doing a bit of work with sqlite lately and I am surprised to find that the C api is basically a way to pass in strings containing SQL commands. Now even in C I could imagine an API which allows you to build up queries to do everything SQL does without using commands in text strings.
With an OO language it should be dead easy.
http://michaelsmith.id.au
Use perl. Because the support both in java and php for applying regexes and preparing SQL statements has been late, convoluted and lacking.
Religion is what happens when nature strikes and groupthink goes wrong.
Comment removed based on user account deletion
If your code is running at the correct privilege level, SQL injections should be completely irrelevant.
If your user is connecting with the correct credentials, they should only be able to see public data and their own records, nothing else.
This is implemented by using views in the database, and only allowing users rights to views, not tables.
If your website user is connecting with credentials that allow a crafted SQL query to see priveleged data, you have set everything up wrong
If you have set everything up correctly, even a successful SQL injection will only return data the user can see
Yesterday we read about the problems of individual developers who can't get a foothold in the industry due to a shift towards accountability for software bugs. Today we read about SQL injection vulnerabilities affecting many web sites. Can anybody else see how one is the cause of the other? It is very obvious that a lot of people who should not come anywhere close to a text editor are writing public-facing code. Is there a way to remove these people from the pool other than by making programmers responsible for failing to prevent at least well known attacks? How are serious programmers, who take the time to get it right, supposed to compete when any hack can get away with abysmal code quality?
I create a security object that stores $_GET and $_POST as arrays and escapes all the contained details, once this is done i blitz both $_GET and $_POST so they cant accidentally be called within the programme.
From this point to call a get variable you need to call $security->get('name');
This object also checks for dodgy content like scripts and the like and further down the line, each input is checked for proper formatting.
Im wondering though, what else should I be doing?
This isn't a new concept, just one that people have been removed from.
If ($QUERY_STRING > $MAX_QUERY)
{
print "*Boom* Check server for smoke!"
exit;
}
# only allow characters 0 through 9 and upper/lowercase a-z
$Input = $QUERY_STRING;
$Input =~ s/[^0-9a-zA-Z]//g;
boycott slashdot February 10th - 17th check out: altSlashdot.org
If you look for a while you'll find them. The developers replied to me with "It's perfectly fine". While it seems they do parse this information isn't that screaming "Exploit me!"
You can't stop reading slashdot. Full of nonsensensical arguments, but you read on, your brain oozes, your eyes are red, dry and hurt. Still, you read on, and participate in the debate. You don't recognize your odd behavior. There's a sequel reply injected into your brain. It's a slash dot sequel brain virus injection. There's no cleaning utility, you will need to reformat your brain.
Build your own energy sources from scratch. http://otherpower.com/
I go through this all of the time. Though I call it laziness, it is actually a combination of ignorance, indignation, and laziness.
Here is a very, very, very simple and very, very, very standard way of keeping SQL injections out. Validate everything at every level. There you go. Done.
1) Client side matters. Check input, validate it and pass it through to the application layer.
2) Application layer matters. Check variable, strictly type it, validate it and pass it through to your data layer.
3) Data layer matters. Check argument against strict type, validate it, paramaterize it, and pass it off to the database.
4) Database matters. Check paramater against strict type, validate it, and run it.
You run into problems when someone only follows any one of the steps above. You could handle it with a medium level of confidence in areas 2 and 3 (and if you're asking why not 1 and 4, go sit in the corner while the grown-ups talk), but good practice for keeping it clean is validate it at every layer. That doesn't mean every time you touch the information you have to recheck the input, but every time it moves from one core area of the platform to another or hits an area it could be compromised, you do.
As I said above, the only reason for not following 1-4 is laziness, ignorance, or indignation. SQL injections aren't hard to keep out.
We're in an age where web development IS enterprise level programming and developers need to treat it as such.
There, I just saved your organization millions of dollars. Go get a raise on my behalf or something.
You're right -- because it's SQL, which has assumptions about how it's used.
LDAP, on the other hand, you can set up to bind as the individual user, and you adjust which attributes a user is allowed to see or modify in their own entry, and which entries they can see in other entries.
So, part of the solution is using the correct data store for the situation, and SQL isn't always it. (I haven't played with any of the "NoSQL" stuff yet, but much of the behaviour with replication and and flexibility of storage seem rather similar to the LDAP implementations I've worked with.
Build it, and they will come^Hplain.
learn from Scotty. always double your estimates... Especially when they ask for an honest estimate.
I'm up to a multiple of 16 now.
Deleted
Just bind!
I wanted it to be short, easy for management to understand (even non-technical). Definitely worth watching, IMHO.
http://www.youtube.com/watch?v=jMQ2wdOmMIA
Good security is based upon reality and common sense. Common sense is a function of having common knowledge.
Thanks for leading us to a list of vulnerable sites!
List of vulnerable sites
A quick google finds that the problem actually exists on hundreds of websites, all driven by RCOMX - http://www.linusinc.com/
Doubtful this will be fixed anytime soon!
Posting anon as I wouldn't want to expose our website. We had our company website designed and hosted by an outside company. Always assumed it would be secure, I check the sites I produce for this kind of thing. Parameterising, sanity checking etc. I looked over our company website for a similar avenue of attack added the tick. SQL Error! Added " or 1=1" and bingo a whole load of pages scrunched onto the one browser page. I had an interesting conversation with the producing company...
When setting up a system I always set up both a readwrite and readonly database user, granting only SELECT for the readonly user. Many web apps are "SELECT-only" that grab info out of a database and display it. By requiring these apps to use the readonly user adds another layer of protection should the web programmer code unsafely. Note that a hacker can still get info out of the database using injection, but can't put stuff in, or delete your data.
In a band? Use WheresTheGig for free.
Simply searching on google fo the tail end of the URL shows exactly which sites are vulnerable and the provider of the sites... Now the entire database of restaurants is open to attack. If the author was trying to teach their client a lesson or two (or 50)--well, good job...
Monitor bandwidth usage on IIS6 in real-time: http://www.waetech.com/services/iisbm/
No one's pointing out the smaller half of the problem. If you are displaying errors you're doing most of the hackers work for them.
I strongly disagree too with the idea (below) that libraries should include this kind of thing. This just encourages laziness and makes it harder to check the source code of the libraries. Personally I do not like Hibernate at all because it provides far too much intermediation between the database and the application, meaning that it becomes very hard to see where the boundaries are while practically guaranteeing a loss of efficiency.
In a properly written Java (or indeed any OO) application it is easy to create classes to handle database objects and encapsulate the necessary level of security and error checking. It takes a bit more work up front but it enables you to have confidence that what you are telling the SQL server to do is safe.
From scarped cliff or quarried stone she cries "A thousand types are gone, I care for nothing, no not one."
I have been doing a bit of work with sqlite lately and I am surprised to find that the C api is basically a way to pass in strings containing SQL commands. Now even in C I could imagine an API which allows you to build up queries to do everything SQL does without using commands in text strings.
So your technical indictment of SQL is based on your initial bit of work with sqllite?
And what's wrong with passing SQL command/statements via the API. That's what it's supposed to do. SQL is not just a query language, it's a control language. This is like indicting a *nix shell for letting you do "rm -rf /".
The problem is not that SQL does what it's supposed to do - you tell it to modify, it will; you tell it to delete; it will. The problem is the programmer who doesn't filter the input and allow arbitrary execution of SQL statements. The problem is the DBA who doesn't forbid execution of raw SQL statements in production. The problem is not programming defensively.
It's not fucking rocket science.
With an OO language it should be dead easy.
How naive. I'm not sure you actually know what object-orientation is, what is for and what it does and does not.
Took me 2 minutes with Google to find other sites that are apparently using the same crappy code with the same vulnerabilities. "inurl:" does wonders.
Do you have ESP?
Thanks. For giving us a list of targets.
I am not sure if the author meant to give away this information, but I would be a little upset.
It isn't too far off to find this exact site, knowing the images and basic layout of the site.
Just remind the, erm, "executive" that programming is like having a baby: the esact amount of work required to deliver one is 9 months, working harder may bring the delivery earlier but that makes it a risky situation for all parties involved.
Sounds like a problem with sqlite, not SQL in general.
So why can sql code ever be injected on other platforms?
Instead of execute_command("create table X")
I want to see create_table("X")
In a well-defined system, you see create_table("X") in the application layer that gets translated in to the SQL statement "CREATE TABLE X" (which in the sqllite API tha'ts what happen but in a more procedural manner.).
In fact, using your example, proper usage of the sqllite API would entail having an application-specific API (be it procedural or object-oriented), with an application-specific block of code like (I'll use some c-like pseudocode to illustrate):
SomeUserStruc *user = getCurrentUser();
...
/* call to low-level sqllite api, which gets translated to */
/* the SQL statement "CREATE TABLE THINGIE..." which might fail */
/* in other databases like Oracle if there were other security policies */
/* in place at the db physical server, the db server itself, at the db schema */
/* or at the db table level. Capisce? */
char * command = getCommandFromRequest();
if( ( strcmp(command,"CREATE_THINGIES_TABLE") == 0 )
&& isAuthorized(&user, "CREATE_THINGIES_TABLE") ){
errno = createThingieTable();
}
/* application-specific api */
int createTableThingie()
{
create_table("THINGIE");
return someErrno;
}
Same principles would apply whether you are accessing a DB (be it with SQL or a low-level API). Your gripe about sqllite and SQL is ignorant at best, convoluting defensive programming and plain common sense with OO methodology.
Why would you expect SQL or the sqllite API to provide application-specific security mechanisms. That's your job as an application developer to implement application-specific security to protect resources at lower layers.
Separation of concerns. Does that ring a bell? Since you mentioned OO languages, I would have imagine that you'd realize you could create an app-specific procedural layer in C (or whatever language you are using to access the raw sqllite api), with encapsulation, information hiding and all that good stuff that preceded the arrival of OO languages and stuff...
As long as websites continue to be build for the lowest amount possible, security is going to take a backseat. I have seen more then my fair share of chinese/indian/east european hack jobs where they use code straight from "Hello world" examples. Web development has always been about "deploy now, fix later", but with the coming of outsourcing this already cut throath industry has lost all sense of quality.
Really, even the most basic security measures are not there, code deployed for thousands of dollars that is a complete mess with old versions littered around, root mysql with no password open to the world, anyting to deploy quickly to satisfy a customer whose only measure of quality is the price.
There is good money to be made in fixing these messes (because by now the site has been earning money and the fixes have to be made to ensure the revenue stream) but god it is soul destroying.
MMO Quests are like orgasms:
You may solo them, I prefer them in a group.
SQLAlchemy (and SQLObject for that matter) allow you to build SQL queries from primitives, if it is really necessary, with a consistent syntax across all DB modules.
A client wanted me to size a migration job. VMS, running Oracle, very old. A lot of the application was running in DCL scripts. With embedded SQL.
In my report I noted the possibility of SQL injection attacks. The client chose not to bother "Yes, we know about that already". This was a government branch. Nearly made me cry.
Mostly because I am too ethical to exploit it to make money.
Just another "Cubible(sic) Joe" 2 17 3061
I've got in touch with a few programmers during the time of my ICT period as manager and have noticed a few interesting things:
I've been in both sides of the camp, sysadmin and programmer and have seen a few zombie corpses on the servers I've managed; ready to be hacked if not fixed.
I've read some replies in this thread where people tell everything which is considered harming should be denied. I think a better approach is sanitizing input towards a harmless string. Remove all harming characters instead of denying input is a real charm for the user and still a safety for the programmer. If special strings are used, encode. Instead of using raw SQL; use functions sanitizing input all the times.
When these actions are common, it's nothing but normal security is taken into consideration; anyone creating value in their applications should be prepared against the unknown; the Internet is a warzone and it's not getting better.
It's all a matter of routine; create the good routine and most problems will already be solved in advance.
'; update comments set date='2010-02-26 05:02:00' where id=(select max(id) from comments where user_id is null and sid=1563946); /*
My prince charming, can I marry you ? :-D
Here in Victoria, BC, Canada, most companies seem to want a Web Developer/Programmer who also a Web Developer and Photoshop/Flash expert. They want LAMP experts who also know .NET and Java plus probably Oracle. They are offering positions on contract and with no benefits. Its no wonder why its taking them a while to fill the positions, but it also sucks when you are looking for work and they want the Moon for qualification, but offer Uranus for compensation.
"The first time I got drunk, I got married. The second time I bought a chimpanzee, after that I stayed sober" Arian Seid
Hmm I wonder how one could prevent this kind of mischief? Let's see... using Rails, you could:
In your Controller:
In your View:
TFA shows an ASP site with some clear querystring id tied to a WHERE clause? Ack! You lost experience!
As GP, I use Rails migrations, and they work for most part. Unless you're changing some data in a batch, structural changes should be able to do / undo. Rake automations helps a lot http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
But for SPs I'd create a separate file for each and add to SVN, then force my migration to recreate them every time.
I also find it handy to keep your dev / test / production databases up to date. Or at least a test one (with a sample data set), so you won't screw up badly if you mess up.
Altering production databases is great responsability!