跨域方法与防范

原文博客链接

藤原拓鞋

XSS

XSS,Cross Site Script,跨站脚本攻击。是指攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。攻击者注入恶意脚本,将隐私数据像 cookie,session 发送给攻击者,将受害者重定向到一个由攻击者控制的网站,在受害者的机器上进行恶意操作。

防范:
现在主流的浏览器都内置了如 CSP 防范 XSS 的措施,而开发者可以通过下述方法:

  • HTTPOnly 防止窃取 Cookie,浏览器将禁止页面的 javascript 访问带有 HttpOnly 属性的 Cookie
  • 输入检查,检查用户输入的数据是否包含<,>等特殊字符串,对其进行过滤或编码
  • 输出检查,在服务器变量输出到 HTML 页面时,使用编码或转义的方式防御攻击

CSRF

CSRF,Cross Site Request Forgery,跨站请求伪造,是一种劫持受信任用户向服务器发送非预期请求的攻击方式
CSRF 攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作

Cookie:是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。分为会话型 Cookie 和持久型 Cookie。按照 domain 属性指定域,只会向该域请求时才会发送对应的 Cookie,而客户端通过 javascript 也只能获取当前域的 Cookie

由于 Cookie 中包含了用户的认证信息,当用户访问攻击者准备的攻击环境时,攻击者就可以对服务器发起 CSRF 攻击。在这个攻击过程中,攻击者借助受害者的 Cookie 骗取服务器的信任,但并不能拿到 Cookie,也看不到 Cookie 的内容。而对于服务器返回的结果,由于浏览器同源策略的限制,攻击者也无法进行解析。因此,攻击者无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据

防范:

  • 验证码:强制用户必须与应用进行交互,才能完成最终请求。在私密数据操作时可选用
  • Referer Check:根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。通过 Referer Check,可以检查请求是否来自合法的来源。在私密数据操作时确定 Referer 是自身的域,即在自已网站上进行的操作
  • token 验证:CSRF 攻击之所以能够成功,是因为攻击者可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 Cookie 中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的 Cookie 来通过安全验证。而我们可以在 HTTP 请求中以参数形式加入加密了用户信息的 token,在服务器建立拦截器验证 token,如果请求中没有 token 或者解密 token 内容不正确,则认为是攻击拒绝

CORS

CORS,Cross-Origin Resource Sharing,跨域资源共享。CORS 是一种机制,它使用额外的 HTTP 头来告诉浏览器让运行在 origin(domain)上的 Web 应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
出于安全原因,浏览器限制从脚本内发起的跨源 HTTP 请求。但 html 标签发起的可以跨域(JSONP 的基础)

JSONP

JSONP 是通过 script 标签加载数据的方式获取数据当作 JS 代码来执行,只支持 GET 请求
实现如下,客户端代码:

<script type="text/javascript">
  function aa(data) {
    console.log(data); // 获取到的数据
  }
</script>
<script type="text/javascript" src="....../js/data.js"></script>

不同源的服务器上对应的 data.js 文件代码:

aa({ name: "tom", age: 18 }); // 数据在js代码里

也可以直接使用 jQuery-jsonp 进行请求:

$.ajax({
  url: "http://..../data.js",
  type: "get",
  dataType: "jsonp", // 使用jsonp跨域请求
}).done(function (data) {
  console.log(data);
});

客户端与服务端配合实现跨域

浏览器在发送请求时,检测到跨域时,会自动加上一个额外的 Origin 头部,其中包含请求页面的原信息(协议,域名和端口),以便服务器根据这个头部信息来决定是否给与响应
Origin: http://www....net
如果服务器认为这个请求可以接受,就在 Access-Control-Allow-Origin 头部中返回相同的原信息(如果是公共资源,可以发’*’)
Access-Control-Allow-Origin: http://www....net
如果没有这个头部或者与原信息不匹配,浏览器就会驳回请求

默认情况下,跨域请求和返回都不会带上 Cookie 的,如果要带上,则需要在客户端和服务端同时设置响应的字段:
(1)客户端在请求时打开withCredentials属性,指定某个请求应该发送凭据:

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

(2)服务端在响应头添加Access-Control-Allow-Credential字段且设为 true,表明服务器接受带凭据的请求:

res.setHeader("Access-Control-Allow-Credential", true);

由于 Cookie 是可以设置访问域的,可设为一个顶级域名,则达到几个子域名共享 Cookie 的效果

而很多大网站为了实现子域联动,如 qq 邮箱和腾讯 qq 共享记录用户登录状态的 Cookie,因此会将Access-Control-Allow-Credential字段设为 true,这就给了 CSRF 攻击有了可乘之机,借助用户的 Cookie 伪装用户进行攻击

结语

以上,谢谢阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值