跳转到主要内容

浏览器表单安全

项目描述

简介

此软件包包含一些工具,可以帮助保护Plone或基于Plone框架构建的应用程序的部分。

1. 仅允许HTTP POST

a) 使用装饰器

如果您只需要允许HTTP POST请求,您可以使用PostOnly检查器

from plone.protect import PostOnly
from plone.protect import protect

@protect(PostOnly)
def manage_doSomething(self, param, REQUEST=None):
    pass

此检查器仅在HTTP请求上操作;其他类型的请求不会被检查。

b) 将请求传递给函数验证器

简单

from plone.protect import PostOnly

...
PostOnly(self.context.REQUEST)
...

2. 表单认证(CSRF)

在Web应用程序中,一个常见问题是跨站请求伪造(CSRF)。这是一种攻击方法,其中攻击者欺骗浏览器向另一个站点提交HTTP表单。为此,攻击者需要知道确切的表单参数。表单认证是一种方法,通过添加一个可验证的额外验证器,使得攻击者无法预测这些参数。

生成令牌

要使用表单验证器,您首先需要将其插入到您的表单中。这可以通过在表单内部使用简单的TAL语句来完成

<span tal:replace="structure context/@@authenticator/authenticator"/>

这将生成一个包含认证信息的HTML输入元素。

如果您想以编程方式创建令牌值,请使用以下

from plone.protect.authenticator import createToken
token = createToken()

验证令牌

a) Zope组件架构方式

接下来,您需要在某处添加逻辑以验证验证器。这可以通过调用验证器视图来完成。例如

authenticator=getMultiAdapter((context, request), name=u"authenticator")
if not authenticator.verify():
    raise Unauthorized

b) 使用装饰器

您可以使用protect装饰器更方便地完成同样的事情

from plone.protect import CheckAuthenticator
from plone.protect import protect

@protect(CheckAuthenticator)
def manage_doSomething(self, param, REQUEST=None):
    pass

c) 将请求传递给函数验证器

或者只是

from plone.protect import CheckAuthenticator

...
CheckAuthenticator(self.context.REQUEST)
...

头信息

您还可以通过使用头信息X-CSRF-TOKEN来传递令牌。这对于AJAX请求可能很有用。

Protect装饰器

使用plone.protect最常见的方式是通过protect装饰器。此装饰器接受一个检查器列表作为参数:每个检查器都会检查请求的特定安全方面。例如

from plone.protect import protect
from plone.protect import PostOnly

@protect(PostOnly)
def SensitiveMethod(self, REQUEST=None):
    # This is only allowed with HTTP POST requests.

依赖于受保护的方法有一个名为REQUEST(大小写敏感)的参数。

自定义表单认证

如果您想为不同的表单使用不同的认证令牌,您可以提供一个额外的字符串来与令牌一起使用

<tal:authenticator tal:define="authenticator context/@@authenticator">
  <span tal:replace="structure python: authenticator.authenticator('a-form-related-value')"/>
</tal:authenticator>

验证

authenticator=getMultiAdapter((context, request), name=u"authenticator")
if not authenticator.verify('a-form-related-value'):
    raise Unauthorized

使用装饰器

from plone.protect import CustomCheckAuthenticator
from plone.protect import protect

@protect(CustomCheckAuthenticator('a-form-related-value'))
def manage_doSomething(self, param, REQUEST=None):
    pass

自动CSRF保护

自版本3以来,plone.protect提供了自动CSRF保护。它通过在请求页面的用户登录时自动将auth令牌包含到所有内部表单中来实现这一点。

此外,每当特定请求尝试写入ZODB时,它将检查是否存在正确的auth令牌。

以编程方式允许读取时写入

当您需要允许已知的写入时,您有几个选项。

如果您只想允许在请求中对对象进行写入...

您可以使用 safeWrite 辅助函数

from plone.protect.utils import safeWrite

safeWrite(myobj, request)

将整个请求标记为安全

只需将 IDisableCSRFProtection 接口添加到当前请求对象中

from plone.protect.interfaces import IDisableCSRFProtection
from zope.interface import alsoProvides

alsoProvides(request, IDisableCSRFProtection)

警告!当您这样做时,当前请求容易受到 CSRF 漏洞的攻击,所以请手动进行任何必要的 CSRF 保护。

点击劫持保护

自 3.0 版本起,plone.protect 默认提供点击劫持保护。

为了防止这种攻击,Plone 使用 X-Frame-Options 头部。plone.protect 将 X-Frame-Options 的值设置为 SAMEORIGIN

要自定义此值,您可以为自定义视图(例如 self.request.response.setHeader('X-Frame-Options', 'ALLOWALL'))设置自定义值,在您的代理服务器上覆盖它,或者您可以将 PLONE_X_FRAME_OPTIONS 的环境变量设置为 plone.protect 在全局中设置此值的任何值。

您可以通过使环境变量为空来选择退出此功能。

禁用所有自动 CSRF 保护

要禁用所有自动 CSRF 保护,将环境变量 PLONE_CSRF_DISABLED 的值设置为 true

修复测试中的 CSRF 保护失败

如果在测试中由于未受保护的表单提交而导致出现 Unauthorized 错误,而通常自动保护会生效,您可以使用以下蓝图来保护您的表单

from plone.protect.authenticator import createToken
from ..testing import MY_INTEGRATION_TESTING_LAYER
import unittest

class MyTest(unittest.TestCase):

    layer = MY_INTEGRATION_TESTING_LAYER

    def setUp(self):
        self.request = self.layer['request']
        # Disable plone.protect for these tests
        self.request.form['_authenticator'] = createToken()
        # Eventuelly you find this also useful
        self.request.environ['REQUEST_METHOD'] = 'POST'

备注

此包对多个模块进行了猴子补丁,以更好地处理 CSRF 保护

- Archetypes add forms, add csrf
- Zope2 object locking support
- pluggable auth csrf protection

如果您在网站前面使用代理缓存,请注意,每次更新此包时,您都需要清除 ++resource++protect.js 的条目,否则您在编辑内容时可能会遇到与模态相关的问题。

兼容性

plone.protect 版本 3是为 Plone 5 制作的。您可以在 Plone 4 上使用它以获得更好的保护,但您还需要 plone4.csrffixes 热补丁包,以避免收到不必要的警告或错误。请参阅 热补丁公告热补丁页面

变更日志

5.0.1 (2024-01-22)

内部

  • 更新配置文件。[plone 开发者] (6e36bcc4, 7723aeaf)

5.0.0 (2023-04-15)

新功能

  • 放弃对 Python <3.8 的支持。(5390ebc6)

错误修复

  • 不要严格依赖于 plone.portlets。为具有可选端口的 Plone 准备。[jensens] (#99)

内部

  • 更新配置文件。[plone 开发者] (a9dd65cc)

4.1.8 (2022-12-16)

错误修复

  • 测试:显式设置响应内容类型头部为 html。[jeromeperrin] (#97)

4.1.7 (2022-12-02)

错误修复

  • 添加缺少的 z3c.zcmlhook 依赖项。[icemac] (#96)

4.1.6 (2020-09-26)

错误修复

  • 修复了对 webdav.Lockable.LockableItem 的弃用警告。[maurits] (#3130)

4.1.5 (2020-04-21)

错误修复

  • 微小的打包更新。(#1)

4.1.4 (2020-03-13)

错误修复

  • 删除弃用警告 (#90)

4.1.3 (2019-08-23)

错误修复

  • 在标记 OOBTree 为安全时,也将其桶标记为安全。修复了具有许多注释的对象的问题。(#88)

4.1.2 (2019-02-13)

错误修复

  • 避免弃用警告。[gforcada] (#87)

4.1.1 (2018-12-11)

重大更改

  • 删除 five.globalrequest 依赖项。它已在上游弃用(Zope 4)。[gforcada]

4.1.0 (2018-11-02)

重大更改

  • 适应 AccessControl.requestmethodbuildfacade 的更改可见性。需要 AccessControl >= 4.0b6。[tschorr]

错误修复

  • 更多的 Python 2/3 兼容性 [pbauer, MatthewWilkes]

  • 修复 Python 3 的 marmoset 猴子补丁。[jensens]

  • 在加载zcml之前不要打补丁 [davisagli]

  • 用皮带拴住狨猴(测试后重置csrf检查) [davisagli]

4.0.1 (2018-07-16)

错误修复

  • 修复包依赖;cssselect自2014年以来一直是< span class="docutils literal">lxml的额外部分(关闭#79)。 [hvelarde]

  • 修复了与合并的plone.login兼容的测试 [jensens]

4.0.0 (2018-07-16)

重大更改

  • 3.1.3版本引入了Python 3兼容性修复,导致一些Python 2版本出现SyntaxError。报告主要针对Python 2.7.8及以下版本,但也有一份针对2.7.14版本的报告,但仅限于Travis。所以这标志着是一个破坏性变更。不兼容性将在3.x分支上回滚。3.1.4版本应该可以安全使用。请参阅问题74问题75。 [maurits]

错误修复

  • 避免由于在plone.scale.storage.ScalesDict中存储生成的图像缩放而导致的CSRF警告 [davisagli]

3.1.3 (2018-04-04)

错误修复

  • 更多的Python 2 / 3兼容性。警告:这会在Python 2.7.8或更低版本上引发语法错误。请参阅问题74。 [pbauer]

3.1.2 (2018-02-02)

错误修复

3.1.1 (2017-08-27)

错误修复

  • README措辞调整 [tkimnguyen]

3.1 (2017-08-14)

新功能

3.0.26 (2017-08-04)

新功能

  • 在转换时捕获AttributeError [hvelarde]

3.0.25 (2017-07-18)

错误修复

  • 修复日志记录,不再将跟踪信息写入stdout,而是将其包含在日志消息中。 [jone]

3.0.24 (2017-07-03)

错误修复

  • 删除unittest2依赖 [kakshay21]

3.0.23 (2016-11-26)

错误修复

  • 允许所有上下文中的< span class="docutils literal">confirm-action,而不仅仅是Plone网站根。这避免了在子站上调用它时出错。修复问题 #51。 [maurits]

  • 代码风格:utf8-headers,导入排序,新样式命名空间声明,autopep8 [jensens]

  • 修复#57:Html必须包含“body”,否则plone.protect会中断。 [jensens]

3.0.22 (2016-11-17)

错误修复

  • 避免使用zope.globalrequest.getRequest() [tschorr]

3.0.21 (2016-10-05)

错误修复

3.0.20 (2016-09-08)

错误修复

  • 仅尝试对位于门户中的URL进行确认视图。这适用于PloneHotfix20160830。 [maurits]

  • 删除RedirectTo补丁。该补丁已合并到Products.CMFFormController 3.0.7(Plone 4.3和5.0)和3.1.2(Plone 5.1)。请注意,我们不在我们的setup.py中要求这些版本,因为此包中的代码不再需要它。 [maurits]

3.0.19 (2016-08-19)

修复

  • 使用zope.interface装饰器。 [gforcada]

3.0.18 (2016-02-25)

修复

  • 当在TestRequest上调用safeWrite时修复了属性错误,因为此没有environ.。 [maurits]

3.0.17 (2015-12-07)

修复

  • 在confirm.pt中添加了国际化按钮。 [vincentfretin]

3.0.16 (2015-11-05)

修复

  • 确保转换不会在重定向时失败。 [lgraf]

3.0.15 (2015-10-30)

  • 确保在检查是否应该显示confirm-action视图时,始终将内容类型与字符串进行比较。 [vangheem]

  • 国际化confirm.pt [vincentfretin]

  • 禁用@@confirm-action视图的编辑边框。 [lgraf]

  • 确保标题和描述在@@confirm-action视图中显示。 [lgraf]

  • 允许视图通过手动设置响应头来自定义“X-Frame-Options”。 [alecm]

  • 避免解析重定向响应(这可以避免日志文件中的警告)。[gforcada]

3.0.14 (2015-10-08)

  • 处理因在无效上下文中调用getToolByName而引起的TypeError。[vangheem]

  • 您可以通过将环境变量PLONE_X_FRAME_OPTIONS设置为空字符串来选择退出点击劫持保护。[maurits]

  • 在解析PLONE_CSRF_DISABLED环境变量时更加灵活。我们不再区分大小写,并接受truetyesy1作为真值。[maurits]

  • 避免在检查内容类型头时发生TypeError。[maurits]

3.0.13 (2015-10-07)

  • 始终强制使用HTML序列化器,因为XHTML变体似乎会导致字符编码问题。[vangheem]

3.0.12 (2015-10-06)

  • 不要检查临时存储(如会话存储)的写入操作。[davisagli]

3.0.11 (2015-10-06)

  • 与内联JavaScript更好地合作。[vangheem]

3.0.10 (2015-10-06)

  • 使导入向后兼容。[vangheem]

3.0.9 (2015-09-27)

  • 使用marmoset补丁修复可插拔身份验证,因为如果不这样做,则依赖于某些随机的导入顺序。[vangheem]

  • 在zope根目录上使自动CSRF保护工作。[vangheem]

3.0.8 (2015-09-20)

  • 如有必要,有条件地修补Products.PluggableAuthService。[vangheem]

  • 在转换时不要引发ComponentLookupError。[vangheem]

3.0.7 (2015-07-24)

  • 修复zope根目录上的可插拔身份验证CSRF警告。非常难以重现。只需让plone.protect在zope根目录上执行其工作即可。[vangheem]

3.0.6 (2015-07-20)

  • 如果请求对象无效,则直接返回。[vangheem]

3.0.5 (2015-07-20)

  • 修复可插拔身份验证CSRF警告。[vangheem]

  • 修复在非GET请求上检测安全对象写入的问题。[vangheem]

  • 现在,用户应使用plone.protect.auto中的safeWrite函数代替_v_safe_write。[vangheem]

3.0.4 (2015-05-13)

  • 修补锁定函数以使用_v_safe_write属性。[vangheem]

  • 能够使用_v_safe_write属性来指定可以安全写入的对象。[vangheem]

3.0.3 (2015-03-30)

  • 处理zope根目录没有IKeyManager实用程序,并且zope根请求尚未支持CSRF保护的情况。[vangheem]

3.0.2 (2015-03-13)

  • 为保护转换添加ITransform.transformBytes以修复与plone.app.blocks的ESI渲染的兼容性。[atsoukka]

3.0.1 (2014-11-01)

  • 自动CSRF保护:检查所有存储上的更改。[mamico]

  • 修复CSRF测试。[mamico]

3.0.0 (2014-04-13)

  • 自动旋转密钥环。[vangheem]

  • 为受保护的表单使用特定的密钥环。[vangheem]

  • 添加自动点击劫持保护(感谢Manish Bhattacharya)[vangheem]

  • 添加自动CSRF保护。[vangheem]

2.0.2 (2012-12-09)

2.0 - 2010-07-18

2.0a1 - 2009-11-14

  • 移除了已弃用的AuthenticateForm类和zope.deprecation依赖。[hannosch]

  • 避免在Python 2.6中对sha模块的弃用警告。[hannosch]

  • 指定包依赖。[hannosch]

1.1 - 2008-06-02

  • 添加一个可选的GenericSetup配置文件,以使安装plone.protect更加容易。[mj]

1.0 - 2008-04-19

  • 保护装饰器有一个严重的设计缺陷,这破坏了它。为其添加了适当的测试,并修复了问题。[wichert]

1.0rc1 - 2008-03-28

  • 将plone.app.protect重命名为plone.protect:该包中的功能与Plone无关,并且实际上也应该在Plone之外使用。[wichert]

  • 使utils.protect与Zope >= 2.11兼容。[stefan]

1.0b1 - 2008年3月7日

  • 重构代码,以提供用于方法的通用保护装饰器,该方法接受检查器列表作为选项。添加了用于验证器和HTTP POST-only的检查器。[wichert]

1.0a1 - 2008年1月27日

  • 首次发布 [wichert]

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

plone.protect-5.0.1.tar.gz (34.9 kB 查看哈希)

上传时间

构建分发

plone.protect-5.0.1-py3-none-any.whl (31.6 kB 查看哈希)

上传时间 Python 3

由以下组织支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面