tornado 10、网站安全问题
实际使用过程中,网站总是会遇到这样那样安全问题,以下是我基于tornado网站做的一些防护。
一、用户验证问题
首先用户登录使用安全cookie,见《tornado 8、用户登录验证 secure_cookie》。在登录过程中我们还可以对用户密码进行加密,即使数据被获取,也得不到用户的真实密码。
一般对密码加密,我们可以使用不可逆算法,如md5等。但是这样只是避免用户密码暴露,如果坏人知道了MD5加密后的密码,还是可以登录我们的网站的。
因此我们还需要提高密码强度,俗称加盐。我们可以对用户输入密码进行动态加密。这样密码一致在变化。这个地方我对前端密码加密过程中使用的验证码答案。
前端代码:
var imgID = $(".indetify").val();
var pasw = $.md5($.md5($.trim($(".pasw").val()))+imgID);
看到我首先对用户密码进行MD5加密,在把加密后的代码与用户输入验证码进行MD5加密。这样前端传递到后端的密码每次都在变化。即使被人截取也没用。
二、安全cookie
目前浏览器都允许插件的存在,插件有时能够获取我们的安全cookie,对后台恶意传输数据。我们
- 可以在后端设置cookie属性,
- 设置关闭浏览器清除cookie达到session效果,
- 使用https协议,让cookie只能走ssl通道。(需支持网站https)
# expires_days关闭浏览器清除cookie
# secure只能在https中传递cookie,防止在传送中被截取
# httponly禁止javascript读取cookie
self.set_secure_cookie("sessionID",str("uid"),expires_days=None,httponly=True)
三、XSRF跨站请求
对于get方法:
我们可以在路由参数使用正则匹配,严格控制get参数。
(r"/member/detail/(\w*)/([01]*)", F.MemberDetailHandler),
对于post方法:
tornado提供了XSRF保护,我们在前端需要使用的地方生成一个_xsrf参数,在post过程中带上这个参数,tornado会自动帮我们验证_xsrf是否正确。如果不正确则不会相应。
1.开启使用:
settings = {
"xsrf_cookies": True
}
2.form中使用:
<form action="/purchase" method="POST">
{% raw xsrf_form_html() %}
<input type="text" name="title" />
<input type="text" name="quantity" />
<input type="submit" value="Check Out" />
</form>
3.ajax post中使用:
在jquey中能在ajax请求前设置一些参数:
function getCookie(name) {
var c = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return c ? c[1] : undefined;
}
// 对基于jquery的postajax使用ajaxSetup添加xsrf;对ajaxfileupload手动添加。
$.ajaxSetup({
beforeSend: function(jqXHR, settings)
{
type = settings.type
if (type != 'GET' && type != 'HEAD' && type != 'OPTIONS')
{
var pattern = /(.+; *)?_xsrf *= *([^;" ]+)/;
var xsrf = pattern.exec(document.cookie);
if (xsrf) {
jqXHR.setRequestHeader('X-Xsrftoken', xsrf[2]);
console.log(xsrf[2]);
}
}
}
});
或者使用:
function getCookie(name) {
var c = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return c ? c[1] : undefined;
}
jQuery.postJSON = function(url, data, callback) {
_xsrf = getCookie("_xsrf");
jQuery.ajax({
url: url,
data: {_xsrf:_xsrf}, //在post传递的数据中添加
dataType: "json",
type: "POST",
success: callback
});
}