|Keep It Simple, Stupid|
Use placeholders. For SECURITY!by tilly (Archbishop)
|on Nov 14, 2003 at 00:46 UTC||Need Help??|
This won't be a terribly long meditation. But it is an important one.
I was bothered by Re: Re: (OT) SSL Certificates: Self-Signing and Alternative Solutions because it shows a fundamental misunderstanding of how easy it is to steal credit card databases. And Re: Perlmonk's "best pratices" in the real world bothered me more because someone came out and said openly that if you haven't used placeholders it is probably because you didn't need them yet. (For those who don't know what placeholders are, DBI lets you just put ? in your SQL, bind inputs to the query, and then the driver takes care of sending data to the database.)
These are both dangerously wrong, and they are wrong for connected reasons. Furthermore the responsibility for their being wrong rests squarely on developers' shoulders. Nobody may have told you that it matters, but it does.
I won't go through all of the details because I don't want this to be a HOWTO Steal Credit Cards guide. But the problem is what is known as an SQL injection attack. You have code that interpolates form data directly into the string. The cracker submits form data that closes off the quoted field, ends the query, and adds another query. The other query can do virtually anything. Depending on the database it can give the cracker a remote login, can determine the schema, can return all credit cards you have, can drop tables, etc.
Finding these is easy. Just walk through some complex forms and enter ' or " into each field until you find one that causes a crash. After that escalate the initial hole into better and better exploits using standard procedures that good crackers are very familiar with. When you are bored with that victim, seek another.
What is more, having the database securely locked behind a firewall won't help - anyone who can reach the poorly coded web page can nail the database. You also can't depend on there being any trouble in figuring out passwords. The attacker doesn't need to know passwords and accounts - you are handing them the login to wreak havoc with. OK, a good DBA can lock things down to limit how much damage having a completely compromised account can cause. But the odds that it has been done with yours are slim to none.
So, what can a developer do about this?
There is little that I can do to comfort users about the seriousness of this problem. My guess is that most of us have had our credit cards stolen already, likely multiple times. Few of us would have any reason to know it though. Credit cards are readily available on the black market in bulk (premium prices if they have been tested for validity). Our main protection is that there are too many potential victims and too few crooks.
UPDATE: Fix the link on tainting and fixed a typo (both caught by BazB).
UPDATE 2: Added explanation of placeholders per comment by AM below.