Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: mysql_query käyttämään mysql_real_escape_string funktiota

arclite [04.11.2006 21:18:53]

#

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";
?>

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta