| 
	
 | 
 Posted by Steve on 03/01/07 17:18 
"kenoli" <kenoli.p@gmail.com> wrote in message  
news:1172767406.944492.255670@s48g2000cws.googlegroups.com... 
| Steve -- Thanks.  The article looks good and "injection" seems like 
| the term of art I needed to know.  This is great for finding sql 
| issues which I hadn't thought of. 
| 
| It is pointed out as an issue in the php manual that Strip_tags() has 
| trouble knowing what to delete when one or more "<" or ">" are input 
| by themselves, and not as an actual tag with opening and closing 
| carats.  I have managed to cause some problems when I did some trial 
| runs inserting these characters myself. 
 
make a page with a form that has a textarea. next, try and write some  
javascript in it like: 
 
<script type="text/javascript"> 
 alert('hello world'); 
</script> 
 
save the record to a dummy table you've created for this test. then, pull  
the record back up. i get you get a message saying, of course, 'hello  
world'. 
 
| Is this ever enough of an issue to be concerned about? 
 
no, that's why people NEVER do it. of course it is enough of a reason! i've  
hacked sites that used ajax and had their db queries stored in javascript.  
that means i could look at it. it also means i could bypass all business  
logic they had in place and store anything in their db that i wanted to.  
changing alert('hello world') to something more destructive is far from  
difficult. 
 
| I suppose a regular expression filter, in 
| addition to strip_tags() could be used here, though it seems like it 
| might be overkill and a little hard to apply in combination with strip- 
| tags. 
 
not overkill nor is it hard. here's a quick db class that encapsulates mysql  
functionality. look closely at the encode/decode and prepare statements.  
those will help. when performing any query where input is involved, just  
call db::prepare($value)...which replaces ' with '' and strips slashes,  
optionally it can encode the data as well...changing things like < to <  
also, the db::execute statement can decode this for you when you select data  
for display (however doing so would not avoid the javascript injection). 
 
here's the class - assumes php 5: 
 
<? 
class db 
{ 
  static private $_instance       = null; 
  static private $_lastStatement  = ''; 
 
  private function __clone(){} 
 
  private function __construct(){} 
 
  static function connect($server, $user, $password, $catalog = null) 
  { 
    try 
    { 
      mysql_connect($server, $user, $password); 
      if (!is_null($catalog)){ mysql_select_db($catalog); } 
    } catch (exception $ex) { 
      print "<pre>\r\n"       . $ex->getMessage() . "\r\n" . 
            ' in file '       . $ex->getFile()    . "\r\n" . 
            ' on line '       . $ex->getLine()    . "\r\n" . 
            '</pre>'; 
      return false; 
    } 
    return true; 
  } 
 
  static function getInstance() 
  { 
    if (is_null(self::$_instance)){ self::$_instance = new db(); } 
    return self::$_instance; 
  } 
 
  static function getLastStatement(){ return self::$_lastStatement; } 
 
  static function decode($string) 
  { 
    $translation  = get_html_translation_table(HTML_ENTITIES); 
    $translation  = array_flip($translation); 
    $string       = strtr($string, $translation); 
    return $string; 
  } 
 
  static function describe($table) 
  { 
    $columns  = array(); 
    $records  = self::execute('DESCRIBE `' . $table . '`'); 
    foreach ($records as $record) 
    { 
      foreach ($record as $column => $property) 
      { 
        if ($column == 'FIELD'){ continue; } 
        $columns[strtoupper($record['FIELD'])][$column] = $property; 
      } 
    } 
    return $columns; 
  } 
 
  static function encode($string) 
  { 
    $translation = get_html_translation_table(HTML_ENTITIES); 
    $string      = strtr($string, $translation); 
    return $string; 
  } 
 
  static function execute($sql, $decode = false, $returnNewId = false) 
  { 
    self::$_lastStatement = $sql; 
    $array                = array(); 
    $key                  = 0; 
    $records              = mysql_query($sql); 
    $fieldCount           = @mysql_num_fields($records); 
    $translation          = get_html_translation_table(HTML_ENTITIES); 
    $translation          = array_flip($translation); 
    while ($row = @mysql_fetch_array($records, MYSQL_NUM)) 
    { 
      for ($i = 0; $i < $fieldCount; $i++) 
      { 
        $value = $row[$i]; 
        if ($decode){ $value = strtr($value, $translation); } 
        $array[$key][strtoupper(@mysql_field_name($records, $i))] = $value; 
      } 
      $key++; 
    } 
    if ($returnNewId) 
    { 
      $array = array(); 
      $array[0]['ID'] = mysql_insert_id(); 
    } 
    @mysql_free_result($records); 
    return $array; 
  } 
 
  static function prepare($string, $encode = false) 
  { 
    if ($encode){ $string = self::encode($string); } 
    $string = stripslashes(str_replace("'", "''", $string)); 
    return $string; 
  } 
} 
?>
 
[Back to original message] 
 |