环境:

后台使用的python - flask

前台使用angular框架

1.一个跨域post的样例:

跨域post有多种实现方式:

1.CORS:http://blog.csdn.net/hfahe/article/details/7730944

2.利用iframe

3.server proxy:https://en.wikipedia.org/wiki/Proxy_server

样例使用的为iframe,想要证明,在没有进行csrf防御时,随意攻击者能够利用javascript发送 post 请求。从而简单的提交或获取数据资料;

1.本地test.html页面

<html>
<head>
<title>POST</title>
<script type="text/javascript" src="jquery-2.1.4.min.js"></script>
</head>
<body>
<input type="button" onclick="test();" value="test"/>
<script type="text/javascript">
function test() {
crossDomainPost({
url: 'http://localhost:5000/test',
param: {a: '1', b: '2'},
onSubmit: function (e) {
console.log(e);
}
})
}
function crossDomainPost(config) {
var def = {
url : '', //提交的地址
param : {}, //提交的參数
delay : 1000, //延迟获取參数的时间。单位为毫秒
onSubmit : function (i) {} //提交成功后的回调函数,參数为跳转的IFRAME
};
config = $.extend({}, def, config);
if (!config.url) {
config.onSubmit({error: 'URL is Empty!'});
return;
}
/****baseMethod****/
/**
* 生成随机的10位字符,且唯一
* @returns {string}
*/
var createGuid = function () {
var guid = "";
for (var i = 1; i <= 10; i++) {
guid += Math.floor(Math.random() * 16.0).toString(16);
}
return guid;
},
/**
* 删除指定的节点
* @param _element 要删除的节点
*/
removeElement = function (_element) {
var _parentElement = _element.parentNode;
if (_parentElement) {
_parentElement.removeChild(_element);
}
} // Add the iframe with a unique name
var iframe = document.createElement("iframe");
var uniqueString = createGuid();
document.body.appendChild(iframe);
iframe.style.display = "none";
iframe.contentWindow.name = uniqueString; // construct a form with hidden inputs, targeting the iframe
var form = document.createElement("form");
form.target = uniqueString;
form.action = config.url;
form.method = "POST"; // repeat for each parameter
for (var item in config.param) {
var input = document.createElement("input");
input.type = "hidden";
input.name = item;
input.value = config.param[ item ];
form.appendChild(input);
} document.body.appendChild(form);
try{
form.submit();
}catch(e){
console.log('error');
consoel.log(e);
} setTimeout(function () {
config.onSubmit(iframe);
removeElement(form); //移除form
}, config.delay);
}
</script>
</body>
</html>

2.后台接收代码

这里仅接收POST的请求

@app.route('/test' ,methods=['POST'])
def test():
print 'param is :';
print request.form
return jsonify(data='2222')

3.控制台输出:

服务端处理了非站内的请求

4.浏览器输出:

本地test.html获取到返回信息

2.CSRF

跨站请求攻击。简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去訪问一个自己以前认证过的站点并运行一些操作(如发邮件,发消息,甚至財产操作如转账和购买商品)。因为浏览器以前认证过。所以被訪问的站点会觉得是真正的用户操作而去运行。

这利用了web中用户身份验证的一个漏洞:简单的身份验证仅仅能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

你这能够这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包含:以你名义发送邮件。发消息,盗取你的账号。甚至于购买商品,虚拟货币转账……造成的问题包含:个人隐私泄露以及財产安全。

1.原理

从上图能够看出,要完毕一次CSRF攻击,受害者必须依次完毕两个步骤:

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

看到这里。你或许会说:“假设我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。

是的,确实如此。但你不能保证下面情况不会发生:

1.你不能保证你登录了一个站点后,不再打开一个tab页面并訪问另外的站点。
2.你不能保证你关闭浏览器了后,你本地的Cookie立马过期,你上次的会话已经结束。
3.上图中所谓的攻击站点。可能是一个存在其它漏洞的可信任的常常被人訪问的站点。

原理具体:http://www.80sec.com/csrf-securit.html

2.常见的攻击类型:

1.GET类型的CSRF

仅仅须要一个HTTP请求。就能够构造一次简单的CSRF。

样例:

银行站点A:它以GET请求来完毕银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000

危急站点B:它里面有一段HTML的代码例如以下:

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

首先。你登录了银行站点A,然后訪问危急站点B,噢,这时你会发现你的银行账户少了1000块

为什么会这样呢?原因是银行站点A违反了HTTP规范,使用GET请求更新资源。

在訪问危急站点B的之前。你已经登录了银行站点A,而B中的以GET的方式请求第三方资源(这里的第三方就是指银行站点了,原本这是一个合法的请求,但这里被不法分子利用了)。所以你的浏览器会带上你的银行站点A的Cookie发出Get请求,去获取资源

toBankId=11&money=1000">http://www.mybank.com/Transfer.php?toBankId=11&money=1000 ,结果银行站点服务器收到请求后,觉得这是一个更新资源操作(转账操作),所以就立马进行转账操作

2.POST类型的CSRF

如上边的跨域POST样例

3.怎样防御CSRF

1.提交验证码

在表单中添加一个随机的数字或字母验证码。通过强制用户和应用进行交互。来有效地遏制CSRF攻击。

2.Referer Check

检查假设是非正常页面过来的请求,则极有可能是CSRF攻击。

3.token验证

  • 在 HTTP 请求中以參数的形式添加一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,假设请求中没有

    token 或者 token 内容不对,则觉得可能是 CSRF 攻击而拒绝该请求。

  • token须要足够随机
  • 敏感的操作应该使用POST。而不是GET,以form表单的形式提交。能够避免token泄露。

4.在 HTTP 头中自己定义属性并验证

这样的方法也是使用 token 并进行验证。这里并非把 token 以參数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自己定义的属性里。通过 XMLHttpRequest 这个类,能够一次性给全部该类请求加上 csrftoken 这个 HTTP 头属性。并把 token 值放入当中。这样攻克了上种方法在请求中添加 token 的不便。同一时候,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用操心 token 会透过 Referer 泄露到其它站点中去。

4.关于token

  1. Token 应该被保存起来(放到 local / session stograge 或者 cookies
  2. Tokens 除了像 cookie 一样有有效期。而且你能够有很多其它的操作方法。一旦 token 过期,仅仅须要又一次获取一个。你能够使用一个接口去刷新 token。你甚至能够把 token 原来的公布时间也保存起来。而且强制在两星期后又一次登录什么的。假设你须要撤回 tokens(当 token 的生存期比較长的时候这非常有必要)那么你须要一个 token 的生成管理器去作检查。
  3. Local / session storage 不会跨域工作,请使用一个标记 cookie
  4. 有须要的话,要加密而且签名 token
  5. 将 JSON Web Tokens 应用到 OAuth 2

使用Token

1.引入csrf

from flask_wtf.csrf import CsrfProtect
csrf = CsrfProtect() app = Flask(__name__) csrf.init_app(app)
app.config['SECRET_KEY']='myblog'

2.在站内页面上head中,添加token

<meta name="csrf-token" content="{{ csrf_token() }}">

3.配置angular提交表头

app.config(function ($httpProvider) {
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
});

4.再次測试跨域post

后台输出:



前台输出:

关于webapp跨域Post使用token思路:

  1. 移动端登录时,服务端验证表单信息。登陆成功,生成token,返回给client;
  2. client将token存在localstorage/sessionstorage中。每次提交表单。都须要携带token;
  3. 服务端获取请求。假设没有token,则忽略请求;

出现的问题:

  1. 服务端须要限制登陆次数

    解决方法:

    client添加登陆间隔。请求一次后,等待x秒才干再次请求

    服务端做cas验证

  2. 服务端须要保存用户的token,及过期时间;

    解决方法:

    能够将token 保存在Memcache,数据库中,redis

  3. client存token时。须要对token加密

    解决方法:

    在存储的时候把token进行对称加密存储,用时解开

    将请求URL、时间戳、token三者进行合并加盐签名。服务端校验有效性

当然。以上仅仅防君子,不防小人

參考:

跨域post请求:http://blog.csdn.net/doraeimo/article/details/7329779

跨站请求伪造:http://www.jianshu.com/p/7f33f9c7997b

token:http://alvinzhu.me/blog/2014/08/26/10-things-you-should-know-about-tokens/

跨域post 及 使用token防止csrf 攻击的更多相关文章

  1. SpringBoot22 Ajax跨域、SpringBoot返回JSONP、CSRF、CORS

    1 扫盲知识 1.1 Ajax为什么存在跨域问题 因为浏览器处于安全性的考虑不允许JS执行跨域请求. 1.2 浏览器为什么要限制JS的跨域访问 如果浏览器允许JS的跨域请求就很容易造成 CSRF (C ...

  2. jsonp 跨域Uncaught SyntaxError: Unexpected token :解决方法

    [jQuery]Ajax实现跨域访问JSON Ajax跨域访问JSON 环境:.net4.0+jQuery+JSON.net 因为在跨域实现,所以这里新建网站,这个网站只需要Ashx文件 public ...

  3. spring boot + spring security +前后端分离【跨域】配置 + ajax的json传输数据

    1.前言 网上各个社区的博客参差不齐 ,给初学者很大的困扰 , 我琢磨了一天一夜,到各个社区找资料,然后不断测试,遇到各种坑,一言难尽啊,要么源码只有一部分,要么直接报错... 最后实在不行,直接去看 ...

  4. 前端安全系列之二:如何防止CSRF攻击

    原文:https://my.oschina.net/meituantech/blog/2243958 背景 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题 ...

  5. 前端安全系列之二:如何防止CSRF攻击?

    背景 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点.在移动互联网时代,前端人员除了传统的 XSS.CSRF 等安全问题之外,又时常遭遇网络劫持 ...

  6. 前端安全系列:如何防止CSRF攻击?

    背景 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点.在移动互联网时代,前端人员除了传统的 XSS.CSRF 等安全问题之外,又时常遭遇网络劫持 ...

  7. 前端安全系列(二):如何防止CSRF攻击?

    前端安全系列(二):如何防止CSRF攻击?   背景 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点.在移动互联网时代,前端人员除了传统的 XS ...

  8. 如何防止CSRF攻击?

    CSRF攻击 CSRF漏洞的发生 相比XSS,CSRF的名气似乎并不是那么大,很多人都认为CSRF“不那么有破坏性”.真的是这样吗? 接下来有请小明出场~~ 小明的悲惨遭遇 这一天,小明同学百无聊赖地 ...

  9. 咱妈说别乱点链接之浅谈CSRF攻击

    平时经常听到人们说别乱点链接,小心有病毒.还有长辈们转发的“天呐~XXX的阴谋,全是病毒”.“XXX惊天大病毒,点了苹果手机就要爆炸!”.“现在转发热门连接会乱扣费!千万别点!”. 到底长辈们说的这些 ...

随机推荐

  1. [BeiJing2006]狼抓兔子 dijkstra+平面图最小割

    一眼裸的最大流求最小割,然而数据范围过大,跑不下来. 我们可以将平面图转成对偶图,并进行连边. 这样,每条边的长度就对应原图中的割边长度. 起点到终点的最短路即为最小割. 别用SPFA,会死的很惨 C ...

  2. pandaboy玩pandas

    基于python的三方库pandas的excel表二次开发 import numpy as np import pandas as pd import time from pandas import ...

  3. 设置div内的内容不能被选中

    通过简单的css设置页面的文字无法被选定. <div class="select">我不能被选中复制</div> .select{ -webkit-user ...

  4. (WC2018模拟十二)【FJOI2016集训Day7T3】Xor-Mul棋盘

    是不是应该第100篇博文纪念一下? 题解: 本质简单题...但是我没仔细看这题... 观察它的两个式子,都是xor完再乘以某个数,意味着d数组的每个二进制位对答案的贡献都是独立的,可以每一位分开处理. ...

  5. Promise语法

    转自:廖雪峰的官方网站 在JavaScript的世界中,所有代码都是单线程执行的. 由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行.异步执行可以用回调函数实现: ...

  6. ubuntu安装和使用

    1.查看ubuntu是32位还是64位 教程:jingyan.baidu.com/article/db55b609ab531f4ba30a2f13.html 2.安装maven 教程:www.linu ...

  7. 题解 P2532 【[AHOI2012]树屋阶梯】

    本题运用卡特兰数求解. 卡特兰数有两种表达方式: 1)\(h_i=\sum^{k=0}_{i-1}h_kh_{i-k-1}\) 2)\(h_i=\frac{1}{n+1}C^{n}_{2n}\) 运用 ...

  8. 题解 P3128 【[USACO15DEC]最大流Max Flow】

    此类型题目有两种比较常见的做法:树链剖分和树上差分. 本题有多组修改一组询问,因此树上差分会比树链剖分优秀很多. 这里两种方法都进行介绍. 树链剖分和树上差分的本质都是将一颗树转换为一个区间,然后进行 ...

  9. 05004_Linux的其他命令和权限命令

    1.其他命令 (1)显示当前所在位置 命令:pwd (2)搜索命令 a.命令:grep 要搜索的字符串 要搜索的文件 示例:搜索/etc/sudu.conf文件中包含字符串to的行 b.搜索/etc/ ...

  10. 3D拾取技术

    在unity3d中用户通过触摸屏选中虚拟3D世界中的物体进行操控,就须要掌握3d 拾取技术. 3d拾取技术很的简单:由摄像机与屏幕上的触控点之间确定一条射线.由此射线射向3d世界, 最先和此射线相交的 ...