[PHP-BUG] Req #61708 [NEW]: Untrusted input variables tagging to detect and prevent SQL injection

2012-04-12 Thread forphponly at hostultra dot com
From: 
Operating system: 
PHP version:  Irrelevant
Package:  MySQL related
Bug Type: Feature/Change Request
Bug description:Untrusted input variables tagging to detect and prevent SQL 
injection

Description:

I propose that PHP tag bytes in variables that come from untrusted sources
such as user input (eg. $_GET $_POST $_COOKIE $_REQUEST etc..) or read from
the database.
For each php variable, there would be a piece of metadata that defines the
byte ranges in that variable containing bytes from untrusted sources.
This metadata would be updated whenever any php code or function changed
the contents of a variable.
This is a very simple concept in theory, but I am not sure how difficult it
would be to implement in php.

The mysql functions such as mysql_query() can then use the metadata to
differentiate between bytes that come from untrusted sources from the part
of the query that the programmer wrote.
eg. in my test script below, mysql_query() would know that the $username
and $password parts in the $query variable are untrusted and must be
escaped.

The php mysql functions can then alter the query to automatically add
escaping before passing it on to mysql database thus making all SQL
injection exploits obsolete without needing to rewrite any php code.

This would work similar to magic quotes, without the problem of double
escaping or display errors when the variables are displayed on a webpage
instead of used in a database.

A color diagram should make my idea more clear.
http://img690.imageshack.us/img690/3313/mysqlinjection.png

Test script:
---
http://server/test.php?username=john&password=' OR 1=1
--

$username = $_GET['username'];
$password = $_GET['password'];

$query = "SELECT * FROM `users` WHERE `username` = '$username' AND
`password` = '$password' ";
$result = mysql_query ( $query );

?>

Expected result:

mysql_query() would change the query to
SELECT * FROM `users` WHERE `username` = 'john' AND `password` = '\' OR 1=1
--' 

Actual result:
--
The query that gets executed
SELECT * FROM `users` WHERE `username` = 'john' AND `password` = '' OR 1=1
--' 

-- 
Edit bug report at https://bugs.php.net/bug.php?id=61708&edit=1
-- 
Try a snapshot (PHP 5.4):
https://bugs.php.net/fix.php?id=61708&r=trysnapshot54
Try a snapshot (PHP 5.3):
https://bugs.php.net/fix.php?id=61708&r=trysnapshot53
Try a snapshot (trunk):  
https://bugs.php.net/fix.php?id=61708&r=trysnapshottrunk
Fixed in SVN:
https://bugs.php.net/fix.php?id=61708&r=fixed
Fixed in SVN and need be documented: 
https://bugs.php.net/fix.php?id=61708&r=needdocs
Fixed in release:
https://bugs.php.net/fix.php?id=61708&r=alreadyfixed
Need backtrace:  
https://bugs.php.net/fix.php?id=61708&r=needtrace
Need Reproduce Script:   
https://bugs.php.net/fix.php?id=61708&r=needscript
Try newer version:   
https://bugs.php.net/fix.php?id=61708&r=oldversion
Not developer issue: 
https://bugs.php.net/fix.php?id=61708&r=support
Expected behavior:   
https://bugs.php.net/fix.php?id=61708&r=notwrong
Not enough info: 
https://bugs.php.net/fix.php?id=61708&r=notenoughinfo
Submitted twice: 
https://bugs.php.net/fix.php?id=61708&r=submittedtwice
register_globals:
https://bugs.php.net/fix.php?id=61708&r=globals
PHP 4 support discontinued:  
https://bugs.php.net/fix.php?id=61708&r=php4
Daylight Savings:https://bugs.php.net/fix.php?id=61708&r=dst
IIS Stability:   
https://bugs.php.net/fix.php?id=61708&r=isapi
Install GNU Sed: 
https://bugs.php.net/fix.php?id=61708&r=gnused
Floating point limitations:  
https://bugs.php.net/fix.php?id=61708&r=float
No Zend Extensions:  
https://bugs.php.net/fix.php?id=61708&r=nozend
MySQL Configuration Error:   
https://bugs.php.net/fix.php?id=61708&r=mysqlcfg



Req #61708 [Nab]: Untrusted input variables tagging to detect and prevent SQL injection

2012-04-13 Thread forphponly at hostultra dot com
Edit report at https://bugs.php.net/bug.php?id=61708&edit=1

 ID: 61708
 User updated by:forphponly at hostultra dot com
 Reported by:forphponly at hostultra dot com
 Summary:Untrusted input variables tagging to detect and
 prevent SQL injection
 Status: Not a bug
 Type:   Feature/Change Request
 Package:MySQL related
 PHP Version:Irrelevant
 Block user comment: N
 Private report: N

 New Comment:

Although I was not aware of the taint project before submitting this.
I believe my suggestion is substantially different.

Taint is subject to many false positives such as if input validation was done, 
but the variable was not cleaned with real_mysql_escape_string(), or the 
variable does not contain any unsafe characters.
Taint is also just taints the entire variable, and without knowing which 
specific bytes in the variable are tainted its not possible to automatically 
escape it.

Taint looks good for a programmer to detect bugs in a php app, but my 
suggestion was for more like something that can be installed on a production 
web server (eg. by a web hosting company) to protect all php applications from 
SQL injections, and without needing any changes to the php scripts being 
protected.


Previous Comments:

[2012-04-13 02:01:44] s...@php.net

See https://wiki.php.net/rfc/taint and http://pecl.php.net/package/taint


[2012-04-13 01:52:27] forphponly at hostultra dot com

Description:

I propose that PHP tag bytes in variables that come from untrusted sources such 
as user input (eg. $_GET $_POST $_COOKIE $_REQUEST etc..) or read from the 
database.
For each php variable, there would be a piece of metadata that defines the byte 
ranges in that variable containing bytes from untrusted sources.
This metadata would be updated whenever any php code or function changed the 
contents of a variable.
This is a very simple concept in theory, but I am not sure how difficult it 
would be to implement in php.

The mysql functions such as mysql_query() can then use the metadata to 
differentiate between bytes that come from untrusted sources from the part of 
the query that the programmer wrote.
eg. in my test script below, mysql_query() would know that the $username and 
$password parts in the $query variable are untrusted and must be escaped.

The php mysql functions can then alter the query to automatically add escaping 
before passing it on to mysql database thus making all SQL injection exploits 
obsolete without needing to rewrite any php code.

This would work similar to magic quotes, without the problem of double escaping 
or display errors when the variables are displayed on a webpage instead of used 
in a database.

A color diagram should make my idea more clear.
http://img690.imageshack.us/img690/3313/mysqlinjection.png

Test script:
---
http://server/test.php?username=john&password=' OR 1=1 --

$username = $_GET['username'];
$password = $_GET['password'];

$query = "SELECT * FROM `users` WHERE `username` = '$username' AND `password` = 
'$password' ";
$result = mysql_query ( $query );

?>

Expected result:

mysql_query() would change the query to
SELECT * FROM `users` WHERE `username` = 'john' AND `password` = '\' OR 1=1 --' 

Actual result:
--
The query that gets executed
SELECT * FROM `users` WHERE `username` = 'john' AND `password` = '' OR 1=1 --' 






-- 
Edit this bug report at https://bugs.php.net/bug.php?id=61708&edit=1