There are many cross-site scripting vulnerabilities in many domestic forums, and there are (quite a few) foreign (and many) more such examples, and even Google (also) has appeared, but was fixed in early December. (Editor's note: For cross-site scripting exploits, readers can refer to "Detailed XSS cross-site scripting attacks"). Cross-site attacks (very) easy to construct, and very subtle, not easy to be detected (usually steal information immediately after the jump back to the original page).
How to attack, not to explain here ((and) Do not ask me), the main talk about how to prevent. First of all, cross-site scripting attacks are (because of) no (strict) filtering of user input, so we have to put the possible danger before all the data goes to our website and database Intercept. For illegal HTML code including single and double quotes, etc., htmlentities () can be used.
<? Php
$ str = "A 'quote' is <b> bold </ b>";
// Outputs: A 'quote' is & lt; b & gt; bold & lt; / b & gt;
echo htmlentities ($ str);
// Outputs: A & # 039; quote & # 039; is & lt; b & gt; bold & lt; / b & gt;
echo htmlentities ($ str, ENT_QUOTES);
?>
This will invalidate the script.
However, it is important to note that htmlentities () defaults to ISO-8859-1 and may not be filtered out if your (illegal) script is encoded in any other way, but your browser can recognize and execute it. This problem I will find a few sites to test after that.
Here's a function to filter illegal scripts:
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 <javascript>
// note that you have to handle splits with
,
, and 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 = & # X40 & # X61 & # X76 & # X61 & # X73 & # X63 & # X72 & # X69 & # X70 & # X74 & # X3A & # X61 &
_ # X6C & # X65 & # X72 & # X74 & # X28 & # X27 & # X58 & # X53 & # X53 & # X27 & # X29>
$ 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
// & # x0040 @ search for the hex values
$ value = preg_replace ('/ (& # [x | X] 0 {0,8}'. dechex (ord ($ search [$ i])). ';?) / i', $ search [$ i] , $ val); // with a;
// & # 00064 @ 0 {0,7} matches '0' zero to seven times
$ val = preg_replace ('/ (& # 0 {0,8}'. ord ($ search [$ i]). ';?) /', $ search [$ i], $ val); // with a ;
}
// now the only remaining whitespace attacks are,
, and
$ 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 ' ondragase ', ondlcasetcomplete, 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 'onmouseout' onmouseout 'onmousewheel' onmove 'onmoveend' onmovestart 'onpaste' onpropertychange ' onreadystatechange ',' onreset ',' onresize ',' onresizeend ',' onresizestart ',' onrowente onrowsit`, `onrowsit`,` onrowsize`, `onrowsinserted`,` onscroll`, `onselect`,` onselectionchange`, `onselectstart`,` onstart`, `onstop`,` onsubmit`, `onunload`);
$ ra = array_merge ($ ra1, $ ra2);
$ found = true; // keep replacing as long as the previous round replaced something
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 {0,8} ([9] [10] [13]) ;?)?';
$ pattern. = ')?';
}
$ pattern. = $ ra [$ i] [$ j];
}
$ pattern. = '/ i';
$ replacement = substr ($ ra [$ i], 0, 2). '<x>'. substr ($ ra [$ i], 2); // add in <> to nerf the tag
$ val = preg_replace ($ pattern, $ replacement, $ val); // filter out the hex tags
if ($ val_before == $ val) {
// no replacements were made, so exit the loop
$ found = false;
}
}
}
}