Die Antwort: aus dem gleichen Grund, warum "register_globals" abgeschafft wurde.
Ich war noch nie ein freund von register_globals zu und habe es schon immer abgelehnt damit zu arbeiten.
Weshalb ich dies Gloablen immer in einem $aParameter = array() gespeichert hatte und
die Globalen geleert hatte.
Nun das prinzip war mir schon klar, die Frage zielte lediglich darauf hin, warum man nach dem
Cleanen der variablen POST + GET, diese in getrennten arrays ablegt.
Ich sehe hier keinen Vor-/Nachteil ob diese nun in einem oder in 2 containern gespeichert werden.
Sinn macht es da eher, die Parameter auszulesen, zu prüfen und zur weiteren Nutzung zu speichen.
Idealerweise löscht man die Globalen Variablen nachdem man diese in ein array gespeichert hat und füllt sie neu.
GET und POST in einem Parameter Array zusammenzufassen käme ja dem alten Verfahren gleich.
Kommt auf die Sichtweise an, ist ja nur für den Entwickler eine vereinfachung.
Es wird hier ja keine Globale mit GET und POST daten vermischt befüllt.
Wie gesagt wenn man die actions immer trennt nach add/edit/save/delete spielt das keine Rolle.
Save ist POST, der rest immer GET. Nutzt man nur eine action, dann muss man halt erst GET dann POST checken.
Ich kann damit leben, muss mir halt angewöhnen die actions zu trennen

Für einen Angreifer ist es doch hier egal ob GET + POST nun in 2 arrays geschrieben werden oder in einem.
GET + POST existieren nach wie vor und können überall genutzt werden. Eine Sicherheit ist das nicht.
Hier sollte aber GET + POST geprüft und bereinigt werden.
IDS prüft ja nur und bricht bei detection mit weiser Seite und IDS Meldung dann ab.
Die Reihenfolge sollte anders sein:
- GET und POST bereinigen in arrays speichern
- Globale Variablen löschen und neu mit den geprüften daten füllen
- mit IDS prüfen
Der Vorteil ist der, das man dadurch evtl. den Abbruch durch das IDS vermeiden kann,
wenn evtl. schadcode vorher entfernt werden konnte.
Beispiel:/**
* Secure URL : Entfernen von Splitting (Injection) sowie Javascript-Urls aus einem zu prüfenden String
* @param string url
* @return string filtered url
*/
private static function secureURL( $sUrl, $JS=true ) {
if ( $JS ) $sUrl = self::removeJavascriptURL( $sUrl );
$sUrl = self::filterHTTPResponseSplitting( $sUrl );
return $sUrl;
}
/**
* Remove potential javascript in urls
* @param string url
* @return string filtered url
*/
private static function removeJavascriptURL( $sUrl ) {
$HTML_stripJavascriptURL = 'javascript:[^"]+';
$sUrl = preg_replace("/$HTML_stripJavascriptURL/i", '', $sUrl );
return $sUrl;
}
/**
* Filter URLs to avoid HTTP response splitting attacks
* @param string url
* @return string filtered url
*/
private static function filterHTTPResponseSplitting( $sUrl ) {
$dangerousCharactersPattern = '~(\r\n|\r|\n|%0a|%0d|%0D|%0A)~';
return preg_replace( $dangerousCharactersPattern, '', $sUrl );
}
private static function RemoveXSS( $val )
{
// remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
// this prevents some character re-spacing such as <java\0script>
// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
$val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val);
// straight replacements, the user should never need these since they're normal characters
// this prevents like <IMG SRC=@avascript:alert('XSS')>
$search = 'abcdefghijklmnopqrstuvwxyz';
$search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$search .= '1234567890!@#$%^&*()';
$search .= '~`";:?+/={}[]-_|\'\\';
for ( $i = 0; $i < strlen($search); $i++ )
{
// ;? matches the ;, which is optional
// 0{0,7} matches any padded zeros, which are optional and go up to 8 chars
// @ @ search for the hex values
$val = preg_replace('/(&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
// @ @ 0{0,7} matches '0' zero to seven times
$val = preg_replace('/(�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
}
// now the only remaining whitespace attacks are \t, \n, and \r
$ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
$ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
$ra = array_merge($ra1, $ra2);
// keep replacing as long as the previous round replaced something
$found = true;
while ( $found == true ) {
$val_before = $val;
for ( $i = 0; $i < sizeof($ra); $i++ )
{
$pattern = '/';
for ( $j = 0; $j < strlen($ra[$i]); $j++ )
{
if ( $j > 0 )
{
$pattern .= '(';
$pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?';
$pattern .= '|(�{0,8}([9][10][13]);?)?';
$pattern .= ')?';
}
$pattern .= $ra[$i][$j];
}
$pattern .= '/i';
// add in <> to nerf the tag
$replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2);
// filter out the hex tags
$val = preg_replace($pattern, $replacement, $val);
if ( $val_before == $val )
{
// no replacements were made, so exit the loop
$found = false;
}
}
}
return $val;
}
z.B.
$_SERVER['QUERY_STRING'] = secureURL($_SERVER['QUERY_STRING'], true);
GET und POST in einer schleife durchlaufen und die values auf RemoveXSS() testen
dann in das jeweilige array get_parameters/post_parameters schreiben.
GET und POST löschen und aus get_parameters/post_parameters neu befüllen.
$doorKeeper->runIDS();
Es ist klar das es keine 100% Sicherheit gibt.
Im moment wird lediglich eine dedection durch das IDS durchgeführt.
Das problem beim IDS ist, das man unter umständen zuviele freigaben in der config definieren muss.
Bei diversen tests mit unterschiedlichen Sprachen hatte ich sehr oft einen IDS Abbruch mit Detection Warnung ausgabe. Nur weil in den texten reservierte Wörter wie z.b. like vorkam.
Ich hab nicht analysiert welche Worte im einzelnen das System zum stillstand brachten, aber es waren eine menge.
gruss
paul