Op phpsec.org kwam ik een beveiligingsmethode tegen welke controleert of de namen van de verzonden $_POST variabelen wel geldig zijn:
http://phpsec.org/projects/guide/1.html#1.4.2
Ik dacht laat ik dit uitbreiden door ook op type en bereik te controleren, inmiddels ben ik al een heel eind en ben ik benieuwd wat jullie ervan vinden, het is uiteraard nog wel een testversie. Je kan het script (testcase) hier downloaden als je wilt.
Om deze methode te implementeren in je eigen PHP applicaties moet je voor elk formulier waar je deze methode wilt toepassen een controle-array inbouwen waarin staat welke POST variabelen geldig zijn, alsmede in welke volgorde, van welk type, minimale lengte/waarde, maximale lengte/waarde, mogelijke waarden, mod flags en een eventuele foutmelding.
Voorbeeld:
Bij een postback moet je voor elke POST variabele de functie check_key_type_range() aanroepen, als deze true returned kan je de invoer redelijk vertrouwen, maar het verdient wel om nog verder te gaan waar check_key_type_range() stopt:
Vertrouw dus alleen op de waarden in $clean
Na deze controle kan je specifiek gaan verifiëren, bijvoorbeeld of een opgegeven e-mail adres wel daadwerkelijk een geldig e-mail adres is (gebruik hiervoor reguliere expressies).
De functie in kwestie:
Met de mod flags in het controle-array kan je aangeven welke bewerkingen uitgevoerd moeten worden, dit is alleen van toepassing op het type string:
PS.: Type 'checkbox' is overbodig vanwege type 'array'
PS2.: Met het tweede veld kan je aangeven of een veld verplicht is of niet.
http://phpsec.org/projects/guide/1.html#1.4.2
Ik dacht laat ik dit uitbreiden door ook op type en bereik te controleren, inmiddels ben ik al een heel eind en ben ik benieuwd wat jullie ervan vinden, het is uiteraard nog wel een testversie. Je kan het script (testcase) hier downloaden als je wilt.
Om deze methode te implementeren in je eigen PHP applicaties moet je voor elk formulier waar je deze methode wilt toepassen een controle-array inbouwen waarin staat welke POST variabelen geldig zijn, alsmede in welke volgorde, van welk type, minimale lengte/waarde, maximale lengte/waarde, mogelijke waarden, mod flags en een eventuele foutmelding.
Voorbeeld:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <!-- html formulier --> <form action="test.php" method="post"> Your name: <input type="text" name="test1"><br> <input type="checkbox" name="test2[]" value=0>X <input type="checkbox" name="test2[]" value=1>Y<br> <textarea name="test3" cols=40 rows=10></textarea><br> <input type="submit" name="btnSubmit" value="ok"> <input type="submit" name="btnSubmit" value="cancel"> </form> |
PHP:
1
2
3
4
5
| // Het controle-array: $allowed = array( 'test1' => array('string', true, 0, 30, 0, _UCWORDS, 'Please enter your name.'), 'test2' => array('array', true, 0, 3, array(0,1), _NONE, 'Select one or two valid options.'), 'test3' => array('string', false, 0, 400, 0, _NL2BR | _UCWORDS | _HTMLENT, 'Your story was too long.'), 'btnSubmit' => array('submit', true, 0, 0, array('ok', 'cancel'), _NONE, 'Wrong button') ); |
Bij een postback moet je voor elke POST variabele de functie check_key_type_range() aanroepen, als deze true returned kan je de invoer redelijk vertrouwen, maar het verdient wel om nog verder te gaan waar check_key_type_range() stopt:
PHP:
1
2
3
4
5
6
7
| $sent = $_POST; $clean = array(); foreach ($allowed as $key => $value) { if (check_key_type_range($key, $sent[$key])) $clean[$key] = $sent[$key]; } |
Vertrouw dus alleen op de waarden in $clean
Na deze controle kan je specifiek gaan verifiëren, bijvoorbeeld of een opgegeven e-mail adres wel daadwerkelijk een geldig e-mail adres is (gebruik hiervoor reguliere expressies).
De functie in kwestie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
| function check_key_type_range($key, &$value) { global $allowed; // Ignore anything that is both empty and not required: if ( (is_null($value)) && (!$allowed[$key][_REQ])) return true; // Check type and range switch ($allowed[$key][_TYPE]) { case 'string': if (is_string($value)) if (strlen($value) > $allowed[$key][_MIN]) if (strlen($value) < $allowed[$key][_MAX]) { apply_mod($key, $value); return true; } break; case 'int': if (is_numeric($value)) if ($value > $allowed[$key][_MIN]) if ($value < $allowed[$key][_MAX]) if (is_array($allowed[$key][_ALLOWED])) { if (in_array($value, $allowed[$key][_ALLOWED])) return true; } else return true; break; case 'array': if (is_array($value)) { if (sizeof($value) > $allowed[$key][_MIN]) if (sizeof($value) < $allowed[$key][_MAX]) { if (is_array($allowed[$key][_ALLOWED])) for ($i=0; $i<sizeof($value); $i++) if (!in_array($value[$i], $allowed[$key][_ALLOWED])) return false; return true; } else return false; } else return false; break; case 'checkbox': if (is_array($value)) { for ($i=0; $i<sizeof($value); $i++) if (!in_array($value[$i], $allowed[$key][_ALLOWED])) return false; return true; } break; case 'submit': if (is_string($value)) if (in_array($value, $allowed[$key][_ALLOWED])) return true; break; } return false; } |
Met de mod flags in het controle-array kan je aangeven welke bewerkingen uitgevoerd moeten worden, dit is alleen van toepassing op het type string:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| function apply_mod($key, &$value) { global $allowed; if ($allowed[$key][_MOD] & _TRIM) $value = trim($value); if ($allowed[$key][_MOD] & _UCWORDS) $value = ucwords(strtolower($value)); if ($allowed[$key][_MOD] & _HTMLENT) $value = htmlentities($value); if ($allowed[$key][_MOD] & _NL2BR) $value = nl2br($value); if ($allowed[$key][_MOD] & _ADDSLASH) $value = addslashes($value); } |
PS.: Type 'checkbox' is overbodig vanwege type 'array'
PS2.: Met het tweede veld kan je aangeven of een veld verplicht is of niet.
[ Voor 25% gewijzigd door risr op 09-02-2005 22:41 ]