Django REST Framework (DRF) 备忘录¶
简介¶
本备忘录为开发者提供了 Django REST Framework 的安全建议。它是一套基本的指南,旨在帮助 Django REST 开发者保护应用程序的核心安全方面。
Django 中的视图是什么?¶
Django 中的视图是一个 Python 类或函数,它在接收到 Web 请求后返回一个 Web 响应。该响应可以是简单的 HTTP、HTML 模板,或者是将用户重定向到另一个页面的 HTTP 重定向请求。
设置¶
要配置 Django REST Framework (DRF),您需要访问 REST_FRAMEWORK 命名空间。通常,您会在 settings.py 文件中找到此命名空间。从安全角度来看,最相关的项目是
DEFAULT_AUTHENTICATION_CLASSES¶
一个认证类的列表,默认情况下通过访问 request.user 或 request.auth 属性来识别哪个用户已通过认证。这些类包括 'rest_framework.authentication.SessionAuthentication'(会话认证)和 'rest_framework.authentication.BasicAuthentication'(基本认证)。
DEFAULT_PERMISSION_CLASSES¶
一个权限类的列表,定义了 Django 在视图可被访问之前检查的默认权限集。由于默认值是 'rest_framework.permissions.AllowAny',这意味着 除非更改默认权限类,否则默认情况下每个人都可以访问每个视图。
DEFAULT_THROTTLE_CLASSES¶
一个限流类的列表,决定了在视图开始时检查的默认限流设置。默认情况下,由于默认类为空,因此没有限流措施。
DEFAULT_PAGINATION_CLASS¶
用于查询集分页的默认类。在 Django 中,分页默认是禁用的。如果没有适当的分页,如果数据量很大,可能会发生拒绝服务 (DoS) 问题或攻击。
OWASP API 安全十大威胁 (2019)¶
《OWASP API 安全十大威胁》是由 开放式 Web 应用程序安全项目 (OWASP) 开发的,列出了 API 最关键的安全风险。它旨在帮助组织识别和优先处理其 API 的最重大风险,以便他们可以实施适当的控制措施来缓解这些风险。
本节使用 2019 年版本的 API 安全十大威胁。保护您的 Web API 的最佳方法是从顶部威胁(下面的 A1)开始,然后向下推进。这将确保任何用于安全的时间都得到最有效的利用,因为您将首先覆盖顶级威胁。在查看完十大威胁之后,通常建议评估其他威胁或进行专业的渗透测试。
API1:2019 对象级授权失效¶
在使用对象级权限时,您应该确保用户可以使用方法 .check_object_permissions(request, obj)
访问该对象。
示例
def get_object(self):
obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
self.check_object_permissions(self.request, obj)
return obj
请勿在未检查请求是否应具有访问该对象的权限的情况下覆盖方法 get_object()
。
API2:2019 用户认证失效¶
为防止用户认证失效,请为您的项目使用具有正确类的 DEFAULT_AUTHENTICATION_CLASSES 设置值,并在每个非公共 API 端点上进行认证。除非您对更改有信心并理解其影响,否则不要在基于类的视图(变量 authentication_classes
)或基于函数的视图(装饰器 authentication_classes
)上覆盖认证类。
API3:2019 过度数据暴露¶
为防止此问题,请仅显示所需的最少量信息。请务必审查序列化器和您正在显示的信息。如果序列化器继承自 ModelSerializer,请勿使用 exclude Meta 属性。
API4:2019 缺乏资源与速率限制¶
为防止此问题,请配置 DEFAULT_THROTTLE_CLASSES 设置,并且除非您对更改有信心并理解其影响,否则不要在基于类的视图(变量 throttle_classes
)或基于函数的视图(装饰器 throttle_classes
)上覆盖限流类。
额外提示:如果可能,使用 WAF 或类似工具进行速率限制。DRF 应该是速率限制的最后一层。
API5:2019 功能级授权失效¶
为阻止此问题,请更改 DEFAULT_PERMISSION_CLASSES 的默认值 ('rest_framework.permissions.AllowAny'
)。为您的项目使用具有正确类的 DEFAULT_PERMISSION_CLASSES 设置值。
除公共 API 端点外,请勿使用 rest_framework.permissions.AllowAny
,并且除非您对更改有信心并理解其影响,否则不要在基于类的视图(变量 permission_classes
)或基于函数的视图(装饰器 permission_classes
)上覆盖授权类。
API6:2019 批量赋值¶
为防止此问题,在使用 ModelForms 时,请使用 Meta.fields(允许列表方法)。请勿使用 Meta.exclude(拒绝列表方法)或 ModelForms.Meta.fields = "__all__"
API7:2019 安全配置错误¶
为阻止此问题,您必须拥有一个可重复的加固过程,以便快速轻松地部署一个妥善锁定的环境。建立一个自动化流程,持续评估所有环境中配置和设置的有效性。
请勿使用默认密码。将 Django 设置中的 DEBUG
和 DEBUG_PROPAGATE_EXCEPTIONS
设置为 False。确保 API 只能通过指定的 HTTP 动词访问。所有其他 HTTP 动词都应禁用。将 SECRET_KEY
设置为一个随机值,并且切勿硬编码密钥。
务必验证、过滤和净化所有客户端提供的数据,或来自集成系统的其他数据。
API8:2019 注入¶
SQLi¶
为防止此问题,请使用参数化查询。在使用 raw()
、extra()
和自定义 SQL(通过 cursor.execute()
)等危险方法时要小心。请勿将用户输入添加到危险方法(raw()
、extra()
、cursor.execute()
)中。
RCE¶
为阻止此问题,请对 YAML 文件使用 Loader=yaml.SafeLoader
。请勿使用 load()
方法加载用户控制的 YAML 文件。
此外,请勿将用户输入添加到危险方法(eval()
、exec()
和 execfile()
)中,并且请勿加载用户控制的 pickle 文件,其中包括 pandas 方法 pandas.read_pickle()
。
API9:2019 不安全的资产管理¶
为防止此问题,请创建所有 API 主机的清单。在此清单中,记录每个主机的重要方面。重点关注 API 版本和 API 环境(例如,生产、预发布、测试、开发),并确定谁应该拥有主机的网络访问权限(例如,公共、内部、合作伙伴)。确保您记录 API 的所有方面,例如认证、错误、重定向、速率限制、跨域资源共享 (CORS) 策略和端点,包括它们的参数、请求和响应。
API10:2019 日志记录与监控不足¶
为了实现适当的日志记录和监控功能,请执行以下操作:
--记录所有失败的认证尝试、拒绝的访问和输入验证错误,并附带足够的用户上下文,以识别可疑或恶意账户。
--以适合日志管理解决方案使用的格式创建日志,并包含足够的详细信息以识别恶意行为者。
--将日志作为敏感数据处理,并应保证其在存储和传输过程中的完整性。
--配置监控系统,持续监控基础设施、网络和 API 的运行情况。
--使用安全信息和事件管理 (SIEM) 系统,聚合和管理来自 API 堆栈所有组件和主机的日志。
--配置自定义仪表盘和警报,以便更早地检测和响应可疑活动。
--建立有效的监控和警报机制,以便及时检测和响应可疑活动。
请勿
--记录通用错误消息,例如:Log.Error("Error was thrown");而应记录堆栈跟踪、错误消息以及导致错误的用户 ID。
--记录敏感数据,例如用户密码、API 令牌或 PII(个人身份信息)。
其他安全风险¶
以下是 OWASP API 安全十大威胁中未讨论的 API 安全风险列表。
业务逻辑漏洞¶
注意可能导致安全漏洞的业务逻辑错误。由于业务逻辑漏洞很难通过自动化工具检测到,因此防止业务逻辑安全漏洞的最佳方法是使用威胁建模、进行安全设计审查、进行代码审查、结对编程和编写单元测试。
密钥管理¶
密钥绝不应该硬编码。最佳实践是使用密钥管理器。 更多信息请参阅 OWASP 密钥管理备忘录
更新 Django 和 DRF 并建立依赖项更新流程¶
所有应用程序都有依赖项,而这些依赖项可能存在漏洞。一种好的做法是审计项目正在使用的依赖项。通常,建立一个依赖项更新流程很重要。一个示例流程可能定义三种触发更新的机制:
--一般来说,每月/每季度更新依赖项。--每周考虑重要的安全漏洞,并可能触发更新。--在特殊情况下,可能需要应用紧急更新。
Django 安全团队提供了关于 Django 如何披露安全问题 的信息。
在考虑一个库时,请考虑该库的“安全健康状况”。它多久更新一次?是否存在已知漏洞?是否有一个活跃的社区?等等。有些工具可以帮助完成此任务(例如 Snyk Advisor)。
SAST 工具¶
有几个值得考虑的优秀 Python 开源静态分析安全工具,包括:
Bandit – Bandit 是一款旨在发现 Python 中常见安全问题的工具。Bandit 处理每个文件,从中构建抽象语法树 (AST),并针对 AST 节点运行相应的插件。Bandit 完成所有文件扫描后会生成一份报告。Bandit 最初是在 OpenStack 安全项目中开发的,后来归属到 PyCQA。
Semgrep – Semgrep 是一种快速、开源的静态分析引擎,用于发现错误、检测第三方依赖项中的漏洞以及强制执行代码标准。由“Return To Corporation”(通常称为 r2c)和开源贡献者开发。它基于规则工作,这些规则可以侧重于安全性、语言最佳实践或其他方面。创建规则很容易,而且 Semgrep 非常强大。对于 Django,有 29 条规则。
PyCharm Security – Pycharm-security 是 PyCharm 或带有 Python 插件的 JetBrains IDE 的一个插件。该插件检查 Python 代码中的常见安全漏洞并提出修复建议。它也可以从 Docker 容器中执行。它有大约 40 项检查,其中一些是 Django 特定的。