DRF(Django REST Framework)是基于一个Django遵循REST的一个强大灵活的用于构建Web API的工具集。作为一个基础坚实,使用广泛的Web框架,其在安全方面的措施也是棒棒哒!
废话不多说,开门见山,跳过安装初始化步骤, 直接上接口:
-
构建一个简单列表接口
视图(View)
序列化(Serializer)
路由(urls)
浏览器访问
http://127.0.0.1:8000/users/
-
序列化(Serializer)
内置的Serializer,可以很方便地控制Model中“我想让用户看到的属性”和“用户可以控制的属性”。Serializer的角色,虽然它有这样一个容易被人误解的名字,但Serializer实际作用和原生Django中的Form类似,主要作用是控制用户输入的内容,并进行校验。但有一个不同点是,Serializer还能控制输出信息的范围。
我们可以把Serializer理解为一个Model和View之间的媒介,View将用户输入的信息发送给Serializer,Serializer进行筛选和校验,成功后发送给Model,保存进数据库;Model从数据库中取出信息交给Serializer,Serializer进行筛选,只显示开发者允许显示的内容,并交给View,Views显示出来。
在代码中,我们通过在Serializer里定义fields,来限制允许显示或修改的属性:
上述代码是一个简单的用户Model对应的Serializer,可见,我通过定义fields,列出程序需要的有哪些字段;再通过定义read_only_fields,来限制哪些是只读字段。
但实际上有些字段是不太适合显示的,比如password,这个字段应该定义为“只可写而不允许读”:
-
权限控制
DRF内置了三种授权(authentication)方法:HTTP基础认证、Session、Token。HTTP基础认证适合于纯浏览器的前端环境,Session适合于浏览器或基于浏览器内核的应用程序,Token适合无浏览器环境的应用程序。
通过授权方法,DRF给每个请求标记上一个用户(未登录的用户被称为匿名用户AnonymousUser),但该用户是否有权限访问某个API,这就得问“许可模块”(Permission)了。也就是说,Authentication模块只负责给请求“发通行证”,Permission模块负责检查这个“通行证”是否有权限访问某个地点。
不同的API View可以选择使用不同的Authentication和Permission,根据自己需要的访问权限任意搭配,也可以使用全局默认值。
另外,权限方面DRF还提供了一个更高级的模块:Throttling
。使用这个模块,即可定义某个“用户”访问某个API的频度。举个例子,某视频网站允许每个免费用户每天观看5个视频,就需要经过如下步骤:
Authentication:Session认证
--> Permission:是否是已登录用户
--> Permission:是否是免费用户
--> Throttling:是否已观看5个视频
--> View:返回视频地址
-
模型(Modles)
由于Python运行模式的特殊性(由某一入口点统一进入),上传文件后缀通常也不会卡的太死,只要不覆盖到程序本身的py文件,都不会有太大问题。所以,Django
本身很多操作默认是不检查后缀的,比如我们定义一个model
,其中包含一个ImageField():
正常来说,
ImageField
是Django
提供的图片字段,按理说Django
自己应该已经做了细致的检查。但实际上Django
只检查用户上传的文件内容是否是图片,而不会检查文件后缀是否是图片后缀。所以,只需要上传一个文件内容符合GIF格式,而后缀
.html
的文件,即可构造一个XSS漏洞。
解决这个问题的方法是,在
ImageField
字段上增加validators
,如photo = models.ImageField('图片',validators=[check_image_extension], null=True, blank=True)
,check_image_extension
函数里对文件后缀进行检查即可。
-
Django部署
Django
考虑的非常周到,在项目上线前,我们可以通过执行./manage.py check --deploy
命令来查看可能存在的安全问题:
问题解释:
另外,上线前,最好修改后台地址,如果你不需要使用Django自带的后台,可以在INSTALLED_APPS里将其移除。SECRET_KEY重新进行生成,不要和开发、测试环境相同:openssl rand 50
。
-
SECURE_HSTS_SECONDS
是否开启HSTS头,强制HTTPS访问 -
SECURE_CONTENT_TYPE_NOSNIFF
是否输出nosniff头,以防止类型混淆类漏洞 -
SECURE_BROWSER_XSS_FILTER
是否输出x-xss-protection头,让浏览器强制开启XSS过滤 -
SECURE_SSL_REDIRECT
是否让HTTP的请求强制跳转到HTTPS -
SESSION_COOKIE_SECURE
是否将Cookie设置为Secure(不允许在HTTP中传输) -
CSRF_COOKIE_SECURE
是否将CSRF Token Cookie设置为Secure(不允许在HTTP中传输) -
CSRF_COOKIE_HTTPONLY
是否将CSRF Token Cookie设置为HTTP ONLY -
X_FRAME_OPTIONS
是否返回X-FRAME-OPTIONS: DENY
头,以防止被其他页面作为框架加载 -
DEBUG
是否开启调试模式 -
Django Rest Framework框架安全部署
|
开发环境中DRF通常使用BrowsableAPIRenderer
,但在部署到生产环境后,最好将这个Renderer
移除,只保留我们需要用到的JSONRenderer
:
因为攻击者可以利用
BrowsableAPIRenderer
输出的表单和返回结果,很容易地进行测试和攻击,也可能是DRF本身出现的前端安全漏洞(如XSS),会因此受到影响。
-
总结
啰嗦这么多其实就是一句话,使用DRF写的接口一般情况下会存在哪些安全问题,在充分考虑安全的情况下我们可以如何避免这些问题,仅此而已,但不限于此。
原文始发于微信公众号(A9 Team):DRF中一些安全小知识
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论