跨站脚本×××(XSS)是客户端脚本安全中的头号大敌。OWASP TOP 10 威胁屡次把 XSS 列在榜首。php
1.XSS 简介
html
跨站脚本×××(Cross Site Script),原本缩写是CSS,可是为了和层叠样式表(Cascading Style Sheet,CSS)有所区别,因此在安全领域叫作 “ XSS ”。前端
XSS ×××,一般指×××经过 “HTML 注入” 篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种×××。在一开始,这种×××的演示案例是跨域的,因此叫作 “ 跨站脚本 ”。现今,因为 Javascript 的强大功能以及网站前端用的复杂化,是否跨域已经再也不重要。可是因为历史缘由,XSS 这个名字却一直保留下来。正则表达式
2. 本身搭建个 DVWA (因为个别缘由,此次就写反射型 XSS)跨域
反射型 XSS浏览器
面对四种级别的代码进行分析。安全
LOW服务器
服务器端核心代码
session
<?php // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Feedback for end user echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; } ?>
能够看到,代码直接引用了name参数,并无任何的过滤与检查,存在明显的XSS漏洞。
xss
漏洞利用
输入<script>alert(/XSS/)</script>,成功弹框:
Medium
服务器端核心代码
<?php // 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>"; } ?>
能够看到,这里对输入进行了过滤,基于黑名单的思想,使用str_replace函数将输入中的<script>删除,这种防御机制是能够被轻松绕过的。
漏洞利用
1.双写绕过
输入 <sc<script>ript>alert(/xss/)</script>,成功弹框:
2.大小写混淆绕过
输入<ScRipt>alert(/xss/)</script>,成功弹框:
High
服务器端核心代码
<?php // 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>"; } ?>
能够看到,High级别的代码一样使用黑名单过滤输入,preg_replace()函数用于正则表达式的搜索和替换,这使得双写绕过、大小写混淆绕过(正则表达式中i表示不区分大小写)再也不有效。
漏洞利用
虽然没法使用<script>标签注入XSS代码,可是能够经过img、body等标签的事件或者iframe等标签的src注入恶意的js代码。
输入<img src=1 onerror=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(); ?>
能够看到,Impossible级别的代码使用htmlspecialchars函数把预约义的字符&、”、 ’、<、>转换为HTML实体,防止浏览器将其做为HTML元素。