Bekijk Volledige Versie : Intresting case of SQL Injection
IMPORTANT INFORMATION FOR ALL DEVELOPERS OF PHP.
I recommend that never leave to insert special characters in input box.
Normally in Input Box only is necessary numeric or alphanumeric data
For solution this SQL Injection you can use these functions:
ctype_alnum -- Check for alphanumeric character(s)
ctype_alpha -- Check for alphabetic character(s)
ctype_cntrl -- Check for control character(s)
ctype_digit -- Check for numeric character(s)
ctype_graph -- Check for any printable character(s) except space
ctype_lower -- Check for lowercase character(s)
ctype_print -- Check for printable character(s)
ctype_punct -- Check for any printable character which is not whitespace or
an alphanumeric character
ctype_space -- Check for whitespace character(s)
ctype_upper -- Check for uppercase character(s)
ctype_xdigit -- Check for character(s) representing a hexadecimal digit
Normally you verify data with Javascript in Client but you must verify data
in file that receive POST Form. In the file that receive the POST data you
can use these functions.
ADDITIONAL INFO:
http://es2.php.net/manual/en/ref.ctype.php
For use these functions you must discomment library in php.ini file:
;Windows Extensions
extension=php_ctype.dll
Javier Morueco
Scovetta, Michael V
05/12/03, 22:00
Martin,
I've run into this, and my solution for MSSQL was to use Java
PreparedStatements). It ties the data to a particular=20
field, so you can pass in whatever you'd like, extra quotes, slashes,
escape characters, and it doesn't make a difference. I actually pass
that into a stored procedure, but that's more of just a good programming
practice in an enterprise environment (IMHO). I'm not sure what
other languages have something like a PreparedStatement, but I think
it would be a big help to ending this SQL Injection thing. As soon
as you can say:
$x =3D new PreparedStatement("select * from table where username =3D =
?");
$x->setString(1, $_GET['username']);
then I don't see where the SQL Injection can come into play. Bad data,
sure, but you can't jump out of the '?' area.
Michael Scovetta
-----Original Message-----
From: Martin Sarsale (runa@sytes) [mailto:runa@runa.sytes.net]
Sent: Thursday, December 04, 2003 2:39 PM
To: bugtraq@securityfocus.com
Subject: Intresting case of SQL Injection
Yesterday, we found an interesting case of SQL Injection.
The application was developed under PHP 4.2.1, Apache and MSSQL.
We started our tests by adding a ' (single quote) to the POST info.
Since PHP escapes ' and " , turning the ' into a \' but SQL Server uses =
2
single quotes ('') to escape a quote (') we were allowed to execute our
code:
select * from users where username=3D'\'; sql code to execute here;--
Then, we wanted to insert a record on the "users" table (fields username
and password, both varchar).
We found that the application used md5 to store the user passwords but
there was a problem: since PHP was auto escaping quotes, we couldn't set
the md5 password as a string because sending:
insert into users values ('username','password');
would be escaped into
insert into users values (\'username\',\'password\');
resulting in a sql error.
So, we had to figure out how to insert the username and password as
numeric values. Since both fields are varchar, when inserting a number =
SQL
server will cast the number into a string.
This is:
inserting 123 (numeric) into a varchar field is the same as inserting
'123' (string).
The username part is easy, we could insert '12345' as the username (any
number will work here), but we found a problem with the password: We =
need
a known string which it's md5 hash is ALL NUMERIC.
Then, we coded a simple PHP script and found that md5(1518375) =3D
93240121540327474319550261818423
After that, we sent to the app:
'; insert into users (username,password) values
(12345,93240121540327474319550261818423);--
which escaped became into:
\'; insert into users (username,password) values
(12345,93240121540327474319550261818423);--
(valid SQL)
Finally, we logged into the webapp using '12345' as username and =
'1518375'
as password.
The main problem here was that developers where trusting in PHP auto
escaping which worked in MySQL (and probably PostgreSQL) but not in =
MSSQL.
Alejandro Pomeraniec (apomeraniec at buenosaires.gov.ar)
Martin Sarsale (msarsale at buenosaires.gov.ar)
Florian Weimer
05/12/03, 22:45
Scovetta, Michael V wrote:
> I've run into this, and my solution for MSSQL was to use Java
> PreparedStatements).
Unfortunately, there appears to be a misconception surrounding Java
prepared statements. Many developers assume that the only reason to use
them is performance, and are extremely reluctant to switching (even if
the application architecture would allow for that with a reasonable
delevelopment effort).
I believe that the relative fragility of database gateways written in
PHP is a result of the late availability of higher-level database
interface libraries (comparable to JDBC or Perl's DBI) and thus the
large amount of hand-written SQL statement generation code.
Markus Fischer
05/12/03, 23:15
On Thu, Dec 04, 2003 at 04:39:15PM -0300, Martin Sarsale (runa@sytes) wrote :
> Yesterday, we found an interesting case of SQL Injection.
[...]
> The main problem here was that developers where trusting in PHP auto
> escaping which worked in MySQL (and probably PostgreSQL) but not in MSSQL.
The main problem in fact are developers who do not read the manual
for their language of choice[tm]. It is documented that
magic_quotes_sybase = true
uses the alternate escaping style needed by non-MySQL alike
databases (eg. MSSQL).
regards,
- Markus
Nick FitzGerald
06/12/03, 00:45
Sys Sec <syssec@sysigsa.com> wrote:
<<snip>>
> Normally you verify data with Javascript in Client ...
I just _love_ seeing this kind of advice...
NOT!
It amounts to you (or your even more security-ignorant client)
effectively saying to your clients (or to the clients of your even more
security ignorant client) "we know better than you about how to secure
_your_ client computers and thus you should trust our judgement that it
is safe for you to enable JavaScript in your web browser despite you
having no frigging idea at all who we are, where this code is actually
hosted, whether the sysadmins of the hosting servers have two clues
about securing their machines and so on".
Please _stop_ thinking it is reasonable to assume you can make such
decisions for folk. Just because the braindead default configuration
of popular browsers is "ream me seven ways to Sunday" (also known as
"multiply the effect of many security flaws in this browser several
fold by enabling JavaScript") does not mean you should assume
JavaScript is available, and if your web pages should happen to be
rendered on a sensibly configured machine, fercrissakes do not assume
you know better than the person who set the machine up -- in such cases
the odds are not that they are running some ancient or otherwise non-
scripting client version but that they know a lot more than you about
the acceptable security exposure of _that machine_.
> ... but you must verify data
> in file that receive POST Form. In the file that receive the POST data you
> can use these functions.
Exactly. The input can be delivered to your server-side app through
all manner of other channels than your client-side code, so why even
bother thinking about designing, writing, debugging and maintaining
client-side sanity-checking code? The odds -- from a huge repository
of popular and widely deployed web apps -- that the programmer or team
behind the app is too retarded to understand the security implications
of _just_ the server-side of the app, so they should concentrate on
getting that part better and maintaining that rather than trying to
dictate their security policies to the clients of the web app.
Regards,
Nick FitzGerald