web2py 中的 CSRF 保护

CSRF protection in web2py

我从 web2py 文档 (http://web2py.com/books/default/chapter/29/01/introduction#Security) 中了解到

web2py prevents CSRF as well as accidental double submission of forms by assigning a one-time random token to each form. Moreover web2py uses UUID for session cookie.

鉴于随机令牌是针对 web2py 生成的页面上的表单完成的,是否有人可以向我解释上述内容如何防止 CSRF?此外,cookie 中的 UUID 不会阻止 CSRF,因为 cookie 会自动随恶意请求一起发送,对吧?

据推测,恶意站点可以通过外部形式执行 https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) 中描述的攻击:

... the vulnerable request looks like this:

POST http://bank.com/transfer.do HTTP/1.1
acct=BOB&amount=100

Such a request cannot be delivered using standard A or IMG tags, but can be delivered using a FORM tag:

<form action="http://bank.com/transfer.do" method="POST">
  <input type="hidden" name="acct" value="MARIA"/>
  <input type="hidden" name="amount" value="100000"/>
  <input type="submit" value="View my pictures"/>
</form>

This form will require the user to click on the submit button, but this can be also executed automatically using JavaScript:

<body onload="document.forms[0].submit()">
<form...

这些表格不会有随机令牌保护,或者我误解得很厉害?

此外,标准 GET 请求(不改变状态但 return 敏感信息)是否也容易受到 CSRF 攻击?

Would someone be so kind as to explain to me how CSRF is prevented by the above, given that the random token is done for forms on web2py generated pages?

CSRF 被阻止正是因为随机令牌在 web2py 生成的页面上可用。因此,如果攻击者试图从非 web2py 生成的页面(即攻击者拥有的页面)发起表单提交,表单提交将不包含随机令牌,web2py 将拒绝表单提交。

当web2py生成token时,它还在服务器上的用户会话中存储了一份副本(用户会话是根据会话cookie识别的)。提交表单时,提交的令牌必须与存储在服务器会话中的令牌相匹配。如果没有token或者token不匹配,则拒绝提交。

Also the UUID in the cookie does not prevent CSRF as cookies get sent with the malicious request automatically, right?

是的,单独的 UUID cookie 并不能防止 CSRF(它只会使劫持会话变得更加困难)——保护需要 CSRF 令牌。

Presumably a malicious site could perform the attack described on https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) via external forms:

不,如上所述,外部表单将不包含 CSRF 令牌,因此将被 web2py 拒绝。换句话说,阻止CSRF的不是存在令牌,而是不存在令牌。

In addition, won't standard GET requests (which don't change state but return sensitive information) also be vulnerable to CSRF attacks?

不,因为攻击者没有收到服务器返回的响应——最终用户在浏览器中获得该响应。这就是浏览器不允许跨源 Ajax 请求的原因。您可能会想到跨站点脚本 (XSS) 攻击(web2py 防止这种攻击的一种方法是自动转义写入视图的任何内容)。