Ohjelma käy hakemiston kaikki tiedostot läpi ja muokkaa mysql_query funktiot siten, että sisällä olevat muuttujat viedään sisälle, kuten php.netissä on kuvattu mysql_real_escape_string funktion manuaalisivulla.
Tein skriptin omaan käyttöön ja se näyttää toimivan minun tiedostoilleni. Skripti tosin kyllä epäonnistuu, jos php koodissa olevat mysql_query funktion kutsut ovat kovin erilaisia kuin minulla.
Linkki php.netin kuvaukseen mysql_real_escape_string funktiosta: https://www.php.net/manual/fi/function.mysql-real-escape-string.php
<?php
/**
* This php script will iterate through a given
* directory and check if it will find mysql_query()
* functions that include php variables. If such
* function calls are found they will be replaced with
* a sprintf formatted query where mysql_real_escape_string()
* function will be used to encapsulate the string.
*
* This will make it much harder to use SQL-injection
* techniques to break your site.
*
* I made this script to go through about 10k lines
* of php code that was used in a web page I had
* to check for known weaknesses.
*
* This script assumes that mysql_query() calls are like:
* -mysql_query("delete from t1 where a='b'", $link)
* -$result = mysql_query("select a,b from t1", $link)
* -if(!mysql_query("delete from t1 where a='b'", $link)){ ... }
* -if(!result = mysql_query("select a,b from t1", $link)){ ... }
*
* This script seems to have done my job very well. However
* Your needs may (and most probably will) differ so use
* as you like... but remember to backup your data first
*
*
*
* @author Petrus Pietilä <petrus@pietila.info>
* @version 1.0
*
* date: Sat 4th. November 2006
* requires: php >= 5.0
* license: GPL-2
*
*/
define("DEBUG", 0); // 0->no debug; 1->little; 2-> debug a lot
$dir = "classes/"; // the directory to be checked and overwrited
$data=array(); // array containing file lines
$lineNumber=0; // current line number -1
$line=0; // data for current line
$matches=0; // temp array for preg_* functions
$resultVariable=0; // variable used to retrieve mysql_query() return value
$sqlVariables = array(); // variables that are passed to mysql_query()
$query = 0; // sql query
$newQuery = 0; // new more secure sql query
$newMysqlQuery = 0; // mysql_query($newQuery, $link)
$link = 0; // link identifier
$somethingDone = false; // was current line modified
$containsIfNotStatement = 0; // was if(! used
$lineCounter = 0; // count processed lines
$lineCounterTot = 0; // count all lines
$fileCounter = 0; // count processed files
// Let's start the iterator
$files = new DirectoryIterator($dir);
foreach ($files as $file) {
$fileCounter++;
$data = file($dir.$file);
foreach ($data as $lineNumber => $line) {
$lineCounterTot++;
// does this line include a mysql_query()
if(strstr($line, "mysql_query(")){
if(DEBUG >= 1){
echo "found mysql_query function from line: $lineNumber<br />\n";
}
// Is there any variables inside the sql query
// if not => we don't need to modify it
if(preg_match("/\".*(\\\$[a-zA-Z]{1}[->a-zA-Z0-9_]*).*\"/", $line, $matches)) {
$query = $matches[0];
if(DEBUG >= 1) {
echo "Sql-query include variables...<br />\n";
}
// Is the line like if(!...
if(strstr($line, "if(!")){
$containsIfNotStatement = true;
}
if($containsIfNotStatement) {
// let's find the possible result variable
if(preg_match("/\([ ]*![ ]*(\\\$[a-zA-Z]{1}[a-zA-Z0-9_]*)/", $line, $matches)) {
$resultVariable = $matches[1];
if(DEBUG >= 1){
echo "mysql_query() return value $resultVariable from line: ".($lineNumber+1)."<br />\n";
if(DEBUG >= 2){
echo $line."<br />\n";
}
}
}
}
// line didn't contain if(!
else{
if(preg_match("/[ ]*(\\\$[a-zA-Z]{1}[a-zA-Z0-9_]*)[ ]*=[ ]*.*/", $line, $matches)) {
$resultVariable = $matches[1];
}
}
// let's find mysql link identifier
preg_match("/.*(\\\$[a-zA-Z]{1}[->a-zA-Z0-9_]*).*/", $line, $matches);
$link = $matches[count($matches)-1];
/**
* @todo modify upper preg_match to handle object
* style links self::$link and parent::$link
*/
if(strstr($line, "parent::".$link))
$link = "parent::".$link;
elseif (strstr($line, "self::".$link))
$link = "self::".$link;
if(DEBUG >= 2){
echo $link."<br />\n";
}
// find variables inside query
preg_match_all("/(\\\$[a-zA-Z]{1}[->a-zA-Z0-9_\[\]]*)/", $query, $matches);
$sqlVariables = $matches[0];
if(DEBUG >= 2){
print_r($sqlVariables);
}
// create new query
$query = preg_replace("/(\\\$[a-zA-Z]{1}[->a-zA-Z0-9_\[\]]*)/", "%s", $query);
if(DEBUG >= 2){
echo $query."<br />\n";
}
$newQuery = "\$query = sprintf($query";
foreach ($sqlVariables as $line){
$newQuery .= ",mysql_real_escape_string(".$line.")";
}
$newQuery .= ")";
$newMysqlQuery = "if(get_magic_quotes_gpc()){\n";
foreach ($sqlVariables as $variable){
$newMysqlQuery .= "$variable = stripslashes($variable);\n";
}
$newMysqlQuery .= "}\n";
if($resultVariable != ""){
if($containsIfNotStatement)
$newMysqlQuery .= $newQuery.";\nif(!$resultVariable = mysql_query(\$query, $link)){";
else
$newMysqlQuery .= $newQuery.";\n$resultVariable = mysql_query(\$query, $link);";
}
else{
if($containsIfNotStatement)
$newMysqlQuery .= $newQuery.";\nif(!mysql_query(\$query, $link)){";
else
$newMysqlQuery .= $newQuery.";\nmysql_query(\$query, $link);";
}
$resultVariable = "";
$containsIfNotStatement = false;
if(DEBUG >= 2){
echo $newMysqlQuery."\n";
}
$data[$lineNumber] = $newMysqlQuery;
$somethingDone = true;
}
}
}
// line was modified let's update it
if($somethingDone){
$lineCounter++;
$fp = fopen($dir.$file, "w");
fputs($fp, join($data));
}
}
echo "Number of processed files: ".$fileCounter."<br />\n";
echo "Number of processed lines: ".$lineCounterTot."<br />\n";
echo "Number of edited lines: ".$lineCounter."<br />\n";
?>Aihe on jo aika vanha, joten et voi enää vastata siihen.