反射型xss
Low:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
没有任何过滤,<script>alert(document.cookie)</script>直接弹框
Medium:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
过滤了<script>
要么双写绕过,要么大小写绕过
High:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
黑名单,那就不用script标签,反正xss payload一大堆
<img src=1 one rror=alert(document.cookie)>
<a href=# ><img src="" one rror="alert('xss')"/></a>
<input type="text" name="test" onclick="alert('xss')">
<input type="text" name="test" onm ousedown="alert('xss')">
。。。。。。
等等
Impossible:
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
Htmlspecialchars实体编码转义字符,用在某些标签如script、input里某些情况下还是可以绕过的,这里不行
htmlspecialchars(string,flags,character-set,double_encode)中
flags可选引号类型有三个选项:
ENT_QUOTES时会过滤单引号和双引号
ENT_COMPAT为默认,仅过滤双引号(单引号是漏网之鱼)
ENT_NOQUOTES不会过滤任何引号
例如:
<?php
$name=$_GET[“name”];
$name=htmlspecialchars($name);
?>
……
……
<input type=’text’ value=’<?php echo $name ?>’>
lcx' onclick='alert(1)'
可绕过
还有很多场景可以绕过,不一一列举了