XSS 跨站脚本攻击:
Cross-site scripting(简称xss)跨站脚本。
一种网站的安全漏洞的攻击,代码注入攻击的一种。XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java,VBScript,ActiveX,Flash或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
例子:
<script>
$.ajax({
url: $(location).attr('href') + "/comments",
method: "POST",
data: { comment : { content: "啊哈哈哈~你看看你! (σ゚∀゚)σ゚∀゚)σ゚∀゚)σ" } },
dataType: "JSON"
})
</script>
url: window.location.href + "/comments" 生成"http://localhost:3000/events/1/comments"
这主要是因为在views/events/show.html.erb中:
<% raw comment.content%>这行代码中有raw()方法
这个方法会输出所有字符,不会放过tag标签。去掉raw()后,content两边加上引号变为字符串。
但这样就不能插入img等有用的tag了。这时可以使用sanitize()方法。
str.html_safe方法
跨站请求伪造 Cross-site request forgery
也称为one-click attack, 简称CSRF或XSRF.
是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
例子:
在任意位置插入恶意代码:如
<img src="/events/92/comments/522/highlight"> 伪装成是用户发送的请求。
防御方法:添加校验token
token是在非get请求中使用。因此需要看代码中关于修改数据库的请求,是否是用了get请求,如果是必须改成非get请求。这样img就不能攻击了。
Rails默认带了protect_from_forgery with: :exception ,⚠️5.2隐藏了这行code。
1. 这样在 Rails 产生的表单form中,就有带这个参数 authenticity_token。
表单的提交就会进行token验证
<form class="new_comment" id="new_comment" action="/events/2/comments" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token" value="fMv3c2b177kqsy/LuDIARp+RaQWJtBHwfQkbEV8j5wqNVFFSBqvcotvkeV07hiQpWsQY1RIEdpVMvE4vysEHiA==">
<div class="form-group">
<label for="comment_content">Content</label>
<textarea class="form-control" name="comment[content]" id="comment_content"></textarea>
</div>
<div class="form-group">
<input type="submit" name="commit" value="Comment" class="btn btn-primary" data-disable-with="Comment">
</div>
</form>
2. 如果是Rails.ajax中的请求:就会抓 meta 中的 csrf-token
参数附加到请求中。和form中的value是一样的。
Rails.ajax()方法,会抓取csrfToken。校验token。
在csrf.coffee中:
csrfToken = Rails.csrfToken = ->
meta = document.querySelector('meta[name=csrf-token]')
meta and meta.content
得到:
<meta name="csrf-token" content="fMv3c2b177kqsy/LuDIARp+RaQWJtBHwfQkbEV8j5wqNVFFSBqvcotvkeV07hiQpWsQY1RIEdpVMvE4vysEHiA==">
这样,黑客在其他网站上挖的坑因为没有这个authenticity_token或csrf-token(两者值一样),他发送的请求就会被挡住。