Scripts

Input checken

Dit is een functie die je het best kan gebruiken voordat er iets met input van een gebruiker gedaan word. Ook is dit script gemaakt om voor enige output gebruikt te worden, zodat je geen errors krijgt als je zou gaan redirecten als er iets fout is. De functie veranderd superglobals net iets, dat ze automatisch gecontroleerd worden en veiliger zijn. (d.m.v. htmlentities [htmlentities nu alleen nog maar met de check: html] en addslashes ) De checks, die ik erop heb gemaakt zijn: num: controleert of de waarde een getal is. mysql: zet mysql_real_escape_string over de waarde heen (dit is niet echt een controle) length: controleert de lengte van de waarde (aantal tekens), maar je kan deze ook zo instellen dat hij, bij een getal controleert of dit getal tussen 2 waardes inzit. aantal mogelijkheden: Als er maar een aantal mogelijkheden zijn (bijvoorbeeld selectboxen, checkboxen of radiobuttons), kan hier ook op gecontroleerd worden. html: haalt een htmlentities over de waarde De checks moet je op deze manier in een array zetten: Je kunt natuurlijk zelf nog allerlei controles verzinnen. Zet die dan wel op de goede plek in de functie ;-) ik hoop dat dit een nuttige functie is. Ik heb het zo gemaakt dat die functie helemaal niet nodig is. Ik bedoel: Dit is een functie die kan helpen bij de beveiliging van een script (voornamelijk tegen SQL injection, maar het kan voor meer dienen). Met deze functie is je script niet per definitie veilig!

input-checken
<?php

// 2 variabele die gezet moeten zijn om de functie te laten werken.

// $userinput bevat de superglobals die gecheckt moeten worden ($_COOKIE hoeft bijvoorbeeld niet altijd gecheck te worden)
// Onthoud: Zet als key ALTIJD neer welke global het is (GET, POST of COOKIE)
$userinput = array('GET' => $_GET, 'POST' => $_POST, 'COOKIE' => $_COOKIE);

// $checks bevat een paar extra checks voor bepaalde inputvariabelen.
$checks = array();

// Deze functie word gebruikt als er iets niet klopt in de checks:
// Voorbeeld: Er staat een letter in een waarde die alleen uit cijfers mag bestaan.
function abort ($soort = '', $key = '')
{
	global $userinput;
	// Hier zou je de fout kunnen noteren (in een .txt bestand of DB ofzo)
	$logfile = fopen("errorlog.txt", "a");
	fputs($logfile, htmlentities('$_'.$soort.'['.$key.'] = '.$userinput[$soort][$key])." : ".date("Y-m-d H:i:s").", ".$_SESSION['memberid'].", ".$_SERVER['REMOTE_ADDR'].", ".$_SERVER['PHP_SELF']." \r\n");
	fclose($logfile);
	
	// Hier kan je ook een melding echoën, of redirechten of includen of iets anders
	echo 'De inputwaarden zijn gemanipuleerd!';
	
	// Een exit(); om te voorkomen dat er iets gedaan word met de foutive data.
	// Dit wil je natuurlijk niet in een SQL hebben.
	exit();
}

function check_input($userinput = 'x', $checks = array())
{
if ($userinput == 'x') {
$userinput = array('GET' => $_GET, 'POST' => $_POST, 'COOKIE' => $_COOKIE);
}
	// De $userinput goed zetten (al je get hebt staan veranderen naar GET)
	foreach ($userinput as $key => $value)
	{
		if ($key != strtoupper($key))
		{
			unset($userinput[$key]);
			$userinput[strtoupper($key)] = $value;
		}
	}	

	// Beginnen met checken
	// De checks zoals NUM zijn NIET hoofdlettergevoelig!
	// Als er niet aan de checks word voldaan, word het hele script gestopt! (zie de functie abort)
	foreach ($checks as $input => $array)
	{
		foreach ($array as $key => $value)
		{
			// Als NUM in de check gevonden word, MOET de waarde een nummer zijn! Anders stopt het script!
			if (eregi('num', $value) && (!is_numeric($userinput[$input][$key]) && !empty($userinput[$input][$key])))
			{
				return abort($input, $key);
			}
			
			// Als MySQL in de check gevonden word, Word er mysql_real_escape_string() over de waarde gezet!
			// Onthoud dat je een MySQL waarde NIET kan echoën! Dus als je de waarde ook moet echoën,
			// Dan moet je dit niet gebruiken en later alsnog mysql_real_escape_string() in combinatie met stripslashes()
			$mysql = false;
			if (eregi('mysql', $value) && !empty($userinput[$input][$key]))
			{
				$mysqlvalue = $userinput[$input][$key];
				if (get_magic_quotes_gpc() == true)
				{
					$mysqlvalue = stripslashes($mysqlvalue);
				}
				$userinput[$input][$key] = mysql_real_escape_string($mysqlvalue);
				
				// Als $mysql op true staat, dan word er later geen addslashes meer overheen gedaan
				$mysql = true;
			}
						
			// Html uitschakelen, zodat er niks kan ge-parsed worden door een input.
			
			if (eregi('html', $value) && !empty($userinput[$input][$key]))
			{
				$userinput[$input][$key] = htmlentities($mysqlvalue);
			}
			
			// Als length(parameter1, parameter2, parameter3) in de check gevonden word, word dit gedaan:
			// parameter1: Minimaal aantal tekens / getal
			// parameter2: Maximaal aantal tekens / getal
			// paramater3 is Optioneel:
			// Als deze op int staat, moet de waarde tussen parameter1 en parameter2 zitten
			// Als deze op string staat (staat hij standaard), moet het aantal tekens tussen parameter1 en parameter2 zitten
			if (eregi('length\(([0-9a-z ,])+\)', $value, $search) && !empty($userinput[$input][$key]))
			{
				// Alle data goed krijgen
				$search = str_replace(' ', '', $search);
				eregi('\(([0-9a-z,])+\)', $search[0], $length);
				
				$param1 = substr($length[0], 0, 1) == '(' ? 1 : 0;
				$param2 = substr($length[0], (strlen($length[0])-1), 1) == ')' ? (strlen($length[0])-1) : strlen($length[0]);
				$length = substr($length[0], $param1, ($param2-$param1));
				$params = explode(',', $length);
				$params[2] = count($params) == 3 ? strtolower($params[2]) : 'string';
				
				// De check eindelijk uitvoeren
				if ($params[2] == 'string' && (strlen($userinput[$input][$key]) < $params[0] or strlen($userinput[$input][$key]) > $params[1]))
				{
					return abort($input, $key);
				}
				elseif ($params[2] == 'int' && ($userinput[$input][$key] < $params[0] or $userinput[$input][$key] > $params[1]))
				{
					return abort($input, $key);
				}
			}
			
			// Als de check een array is, moet de waarde binnen deze array staan.
			// Oftewel: Beperkt aantal mogelijkheden, handig voor selectboxen enzo.
			if (is_array($value) && !empty($userinput[$input][$key]))
			{
				$found = false;
				foreach ($value as $opties)
				{
					if ($opties == $userinput[$input][$key])
					{
						$found = true;
					}
				}
				if ($found == false)
				{
					return abort($input, $key);
				}
				
			}
			
		}
	}
	
	// Hier word de input dan gevalidieerd
	foreach ($userinput as $input => $array)
	{
		foreach ($array as $key => $value)
		{
			$newvalue = $value;
			
			// Eerst mogelijke oude slashes verwijderen en daarna weer toevoegen (zodat je nooit \\\\\\' kan krijgen)
			// Dit gebeurd alleen als er geen mysql_real_escape_string() overheen is gedaan!
			if ($mysql == false) {
			$newvalue = stripslashes($newvalue);
			$newvalue = addslashes($newvalue);
			}

			
			// Alle vernieuwde waarden terugstoppen in de juiste superglobal.
			if ($input == 'GET')
			{
				$_GET[$key] = $newvalue;
			}
			if ($input == 'POST')
			{
				$_POST[$key] = $newvalue;
			}
			if ($input == 'COOKIE')
			{
				$_COOKIE[$key] = $newvalue;
			}
		}
	}
}

// De functie aanroepen:
check_input($userinput, $checks);
?>

Reacties

0
Nog geen reacties.