XSS攻击
跨站脚本攻击
Django自动屏蔽跨站脚本攻击
如果要跳过限制有两种方法
在后端屏蔽from django.utils.safestring import marksafe temp = "百度" newtemp = marksafe(temp) return render(request, 'hello.html', {'temp': newtemp})
在hello.html中a标签就是可以链接百度的a标签,如果不使用marksafe,在hello.html中temp返回的只是字符串。
在前端屏蔽上述代码中返回{‘temp’: temp},前端是无法得到可以连接的a标签的,得到是字符串,如果要得到可以执行的a标签,可以使用safe关键字屏蔽对于xss的限制,使用方法为{{ temp | safe }}
CSRF
概念
CSRF是Cross Site Request Forgery的缩写,即跨站请求伪造。
攻击者盗用的一个人的身份,以这个人的名义发送恶意请求,对于服务器端来说是完全合法的,但是实现了攻击者想要完成的操作,比如说盗号、添加系统管理员、转账等等。
CSRF攻击过程
A网站是一个存在CSRF漏洞的网站,B网站为恶意网站,用户user是A网站的合法用户
用户user输入账号密码登录A网站 用户验证通过,A网站生成Cookie返回user的浏览器 用户未退出A网站,在同一个浏览器中打开B网站 B网站接收请求,返回攻击代码,并发送访问A网站的请求 浏览器会根据B网站的请求,在用户不之情的情况下,携带当前用户的Cookie信息,向A网站发送请求。网站A检测到的Cookie信息是用户user浏览器中的Cookie,因此认定是合法请求,所以会执行B的请求。Django中通过CSRF验证
CSRF验证一般用于POST请求,在form表单中可以使用{% csrf_token %},对于ajax中的post请求可以使用如下方法
$.ajax({ url:'/blog/', type:'POST', data:{'csrfmiddlewaretoken':'{{ csrf_token }}'}, traditional:true, success:function(arg){ } })
这样的方法是用了{{ csrf_token }获取csrf值,即使用了模板语言,还可以使用另外一种方式方式获取csrf值
var csrf = $('input[name="csrfmiddlewaretoken"]').val();
除此之外还可以使用另外一种方法,借用jquery.cookie.js,将cookie中csrf的token在放在请求头中发送到服务端,使用方法如下所示。
var token = $.cookie('csrftoken'); var user = $('#user').val(); $.ajax({ url: '/blog/', type: 'POST', headers: {'X-CSRFToken': token}, data: {'user': user} success: function(arg){ } })
cookie和session
http协议是无状态歇息,一旦数据交互完毕,客户端与服务端的连接就会关闭,再次交互数据就需要重新创建连接,但重新建立的连接是无法跟踪上次的会话了。
例如a向购物车添加了一件产品,操作结束链接等待一段时间就会断开,过一段时间后想要结账,但不知道结账是要为谁结账。
cookie和session就是用来解决这个问题的。
cookie和session都是用来跟踪用户的整个会话的,不同的是cookie通过在客户端记录信息确定用户身份,session在服务端记录信息确定用户身份。
cookie
cookie就是一小段文本信息,当客户端访问服务端,服务端生成一个cookie通过response返回给客户端。下次客户端携带cookie访问服务端,服务端就会依据此确定用户状态。
cookie是不可跨域的
Cookie在客户端是由浏览器管理的,浏览器能够保证A网站只会操作A网站的Cookie而不会操作B网站的Cookie 。浏览器判断一个网站能否操作另一个网站的Cookie是依据域名,域名不一样就无法操作。
cookie是可以记录访问次数的
cookie可以保存账号密码
使用cookie实现用户登录验证
Django中获取cookie
request.COOKIES.get('ticket')
Django中设置cookie
obj = redirect('/blog/') obj.set_cookie('ticket', 'asdfasgasfgsadfasdffgadfas')
设置cookie超时时间
obj.set_cookie('ticket', 'asdfasgasfgsadfasdffgadfas', max_age=10) # 10秒后失效
设置cookie只在某一个URL中生效
obj.set_cookie('ticket', 'asdfasgasfgsadfasdffgadfas', path='/blog') # 只在向/blog发出请求时可以获取到cookie,默认使用“/”默认所有URL都可以获取
签名cookie
设置
obj.set_signed_cookie('ticket', 'asdfasgasfgsadfasdffgadfas', salt='kkkk')
获取
request.get_signed_cookie('ticket', salt='kkkk')
自定义签名加密规则
在settings.py中SIGNING_BACKEND = “foo”,foo为自定义的加密解密方法
session
session是服务器端记录客户状态的机制,相比于cookie使用简单,但增加了服务器存储负担。
session生命周期
session在用户第一次访问服务器的时候创建,session生成后,只要用户继续访问,服务器就会更新session的最后访问时间,并维护该session。用户每访问服务器一次,无论是否重写session,服务器都认为该用户的session活跃了一次。
session有效期
为了防止内存溢出,需要清除长时间没有活跃的session,该时间就是session的超时时间,超过超时时间session就会自动失效。
Django中的session
reqeust.session['username'] = 'Jack' # 存储session request.session.get('username') # 读取session
Django中session参数的设置
session的存储介质有五种
数据库(默认) 缓存 文件 缓存+数据库 加密cookieDjango默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
a. 配置 settings.py
#不同的SESSION_ENGINE对应不同的存储介质,使用时根据具体场景选择一种 # 数据库 SESSION_ENGINE = 'django.contrib.session.backends.db' # 默认 # 缓存 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 # 文件 SESSION_ENGINE = 'django.contrib.sessions.backends.file' SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 加密cookie SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 以下设置适用于任何一种存储介质 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
b. 使用
def index(request): # 获取、设置、删除Session中数据 request.session['k1'] # 获取, 如果不存在会报错 request.session.get('k1',None) # 获取, 如果不存在返回None, 不会报错 request.session['k1'] = 123 # 设置 request.session.setdefault('k1',123) # 存在则不设置 del request.session['k1'] # 所有 键、值、键值对 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 用户session的随机字符串 request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") # 删除当前用户的所有Session数据 request.session.delete("session_key") request.session.set_expiry(value) # 如果value是个整数,session会在些秒数后失效。 # 如果value是个datatime或timedelta,session就会在这个时间后失效。 # 如果value是0,用户关闭浏览器session就会失效。 # 如果value是None,session会依赖全局session失效策略。