应对策略 1:采用token的形式。 采用token是指让请求所带的参数变的不可猜测。即,每次需要保护的请求都要带上一个额外的参数,该参数可以是sessionid(一定要是额外的参数,但是其值可以为sessionid),也可以是另外的无法被猜测的一个值。然后,服务器在得到这个请求后,再验证该值是否匹配。 可能有人会进一步提出,不是sessionid也是可以非法得到的吗,或者说用户的sessionid是没有授权被操作的?答案是没错,但是,那又是另外的攻击方法(涉及到会话劫持和权限欺骗)了,在这里,仅仅防御的是CSRF攻击。 不过为了保险起见,我们可以用sessionid+salt,然后散列的方式来生成这个token。 采用token的形式,我们还需要考虑该token,也就是客户端所带的这个参数的保存问题。从CSRF的本质考虑,token的保存首先不能保存在cookie中,因为cookie本身就是在发送请求的时候可以被带上。 其次,token可以保存在服务器端吗,如,我们可以为当前请求设定一个唯一标识,然后保存在session中。答案当然也是不行的,我们可以假设完成一次请求包含两个部分:发起请求的URL(或程序),处理请求的URL(或程序),诚然,这种方式我们防住了单独请求”处理请求的URL”的CSRF攻击。但是,既然攻击者得到了处理请求的页面,那么,他在伪造CSRF的时候,只要带上了发送请求的页面,就依然可以完成一次攻击。 所以,token的保存只能是保存在发送到客户端的页面中,然后客户端在接下来发送的请求的时候,带上这个参数就可以了。当然,如果页面本身已经被XSS攻破,那么攻击者仍旧可以伪造一次合法请求,但这已经不是防范CSRF的范畴了,而是防范XSS。 2:每次需要被保护的请求发送时,都要求用户输入密码; 3:每次需要被保护的请求发送时,都带上referrer。不过这并不是应对的最佳策略,因为referrer是可以被轻易伪造的。 具体措施 以下具体措施针对token的形式。 n 遍历前台所有发送请求的地方 1:文件查找前台所有的”svc”,”ajax”,”.aspx”,”.html”,”.htm” 2:文件查找前台所有的”form” 根据以上的查找,汇总到如下的表格:
| 序号 | 文件 | 代码行 | GET/POST | 处理完成否 |
| 序号 | 文件 | 代码行 | 处理完成否 |
| 代码如下 | |
|
protected void Page_Load(object sender, EventArgs e)
protected void ButtonDosomething_Click(object sender, EventArgs e)
private string GetTokenFromRequest()
private void PutTokenToClient(string token)
private void SaveTokenInServer(string token)
private bool TokenIsOK(string token) public string _salt = "asdfkl@,.;#sss13131313";
public string CreateToken()
private void ClearToken()
private string MD5(string p) |
|

发表评论