Flask Talisman 让随机数开始工作。拒绝执行内联脚本,因为它违反了以下内容安全策略指令

问题描述 投票:0回答:1

我一直在尝试将 python3 插件 Flask_Talisman 实现到我当前的项目中。除了内容安全策略 (CSP) 之外,一切似乎都正常。问题是我需要从我的站点执行脚本(bootstrap、google reCaptcha 等),但它们被 CSP 阻止。

我的旧配置如下所示:

csp = {
    'default-src': [
        '\'self\''
        ],
    'script-src': [
        '\'self\'',
        'unsafe-inline',
        'https://cdn.jsdelivr.net/npm/',
        'https://www.googletagmanager.com/gtag/',
        'https://www.google.com/recaptcha/',
        'https://www.gstatic.com/recaptcha/'
        ],
    'frame-src': [
        'unsafe-inline',
        'https://www.google.com/recaptcha/', 
        'https://www.recaptcha.google.com.com/recaptcha/'
        ],
    'style-src': [
        '\'self\'',
        'https://cdn.jsdelivr.net/npm/'
        ]
    }

Talisman(app, content_security_policy=csp)

这不起作用。 所以我转而使用哈希,这是网上推荐的:

csp = {
    'script-src': [
        '\'sha256-pyVP/WTBWg0xeYb2xYVwRtZnbyqX6sWurV0uPjEvCN8=\'',
        '\'sha256-fWJPdkYD1sLmgF1O8gp95DZx1j4F+AnK3vUr+ok3MQ8=\'',
        '\'sha256-6WSoVabpxgBYdB7f22nyWr5xcn/Gy4BzHFxng1Z4Gvk=\'',
        '\'sha256-wOhDwuiz1H/PNcPRBBYh/Udj5Jiune650+GU60FuIFI=\''
        ],
    'frame-src': [
        '\'sha256-6WSoVabpxgBYdB7f22nyWr5xcn/Gy4BzHFxng1Z4Gvk=\'',
        '\'sha256-bwxrUkAWabRJI1ius9X3I0XsglPBvIQ5uU/V2h/wuhc=\''
        ],
    'style-src': [
        '\'self\'',
        'https://cdn.jsdelivr.net/npm/'
        ],
    'object-src': [
        '\'none\''
        ]
    }
   
Talisman(app, content_security_policy=csp)

我还尝试使用

unsafe-inline
标签,以及
unsafe-hashed
和许多其他标签,总是得到相同的结果:
Refused to load the stylesheet 'https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css' because it violates the following Content Security Policy directive:

在我的最后一次尝试中,我实现了一个随机数系统,它现在可以与一个函数一起使用;每次调用时它都会创建一个随机数,将其传递到我的index.html并告诉护身符它在哪里。 (我还尝试使用文档提供的

{{ csp_nonce() }}
Docs 示例 #6 函数,但这不起作用。)

所以:

def getNonce():
    return os.urandom(16).hex()

然后在我的烧瓶路线中:

return render_template('index.html', message=message, nonce=getNonce())

配置:

csp = {
    'script-src': '\'self\'',
    'frame-src': '\'self\'',
    'style-src': '\'self\'',
    'object-src': '\'none\''
    }

Talisman(app, content_security_policy=csp, content_security_policy_nonce_in=['script-src', 'style-src']

以及将

nonce={{ nonce }}
添加到我的 HTML 中的每个脚本标记中。

<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" nonce="{{ nonce }}"></script>

即使我一遍又一遍地尝试,我仍然停留在“相同”的错误消息上(只有当我在不安全内联、哈希或随机数之间切换时才会改变):

所以总是

Refused to execute inline script because it violates the following Content Security Policy directive:

如果您知道如何解决此问题,请告诉我,因为我不再知道了。网站本身运行没有问题,但一旦启用 Flask Talisman CSP,一切似乎都崩溃了。

再次阅读文档后,我读到了

Note that the CSP directive (script-src in the example) to which the nonce-... source should be added needs to be defined explicitly.
。因此,我尝试将 URL 重新添加回 CSP(不使用
unsafe-inline
)。新的配置现在看起来像这样:

newCsp = {
    'default-src': '\'self\'',
    'script-src': [
        'https://cdn.jsdelivr.net/npm/',
        'https://www.googletagmanager.com/gtag/',
        'https://www.google.com/recaptcha/',
        'https://www.gstatic.com/recaptcha/'
        ],
    'frame-src': [
        'https://www.google.com/recaptcha/', 
        'https://www.recaptcha.google.com.com/recaptcha/'
        ],
    'style-src': [
        '\'self\'',
        'https://cdn.jsdelivr.net/npm/'
        ],
    'object-src': '\'none\''
    }

现在的问题是,虽然网站现在可以检索所有脚本(并且正在运行)并使用随机数,但它仍然会抛出此错误:

或以文字形式:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src https://cdn.jsdelivr.net/npm/ https://www.googletagmanager.com/gtag/ https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ 'nonce-bykkHFtoKjMIXmjxP4M28B6lSmJMa9XA'". Either the 'unsafe-inline' keyword, a hash ('sha256-h0FtDBdxOnu72uVQe4oUILMiGyexQqDT1jgToPa4Sog='), or a nonce ('nonce-...') is required to enable inline execution.

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' https://cdn.jsdelivr.net/npm/". Either the 'unsafe-inline' keyword, a hash ('sha256-pyVP/WTBWg0xeYb2xYVwRtZnbyqX6sWurV0uPjEvCN8='), or a nonce ('nonce-...') is required to enable inline execution.

我无法解释,因为当再次删除 URL 时,我又回到了旧的错误。

在网上进行了更多搜索后,我发现了这篇文章

由此,我尝试将随机数添加到 CSP 本身,并且它有效!所以现在我的代码看起来有点像这样:

def getCSP():
    nonce = os.urandom(16).hex()
    CSP = {'script-src': [f'nonce-{nonce}'],
        'frame-src': ['https://www.google.com/recaptcha/', 'https://www.recaptcha.google.com.com/recaptcha/'],
        'style-src': ['\'self\'', f'nonce-{nonce}'],
        'object-src': '\'none\''}
    return CSP, nonce

我使用此函数返回一个随机数和带有该随机数的新 CSP。

在我的 Flask 应用程序路径中,然后我使用该函数来获取随机数并将 CSP 设置为全局,以便 Flask_Talisman 可以读取它:

global CSP
CSP, nonce = getCSP()
return render_template('index.html', message=message, nonce=nonce)

然后在启动我的 Flask 应用程序之前:

CSP = {} # Intialize CSP before getting globalized
Talisman(app, content_security_policy=CSP, content_security_policy_nonce_in=['script-src', 'style-src'])

(注意,您仍然需要将

nonce={{ nonce }}
添加到每个 HTML
<script >
标签)

完成所有这些后,我的网站终于备份并运行,控制台日志中没有任何错误消息!

我刚刚意识到设置

CSP={}
– 当然 – 只是禁用 CSP,因为它在启动时仅加载一次,并且不会更新。我稍后会处理这个问题。也许你们中的一些人有另一种解决方案。

python html flask content-security-policy nonce
1个回答
0
投票

我遇到了类似的问题,使用随机数是我的解决方案,也许这有帮助:

SELF = "'self'"
csp = {
        'default-src': SELF,
        'img-src': '*',
        'script-src': [SELF,],
        'style-src': [SELF,],
        'font-src': [SELF,],
    }

nonce_list = ['default-src', 'script-src']

talisman = Talisman(app, content_security_policy=csp, content_security_policy_nonce_in=nonce_list)

脚本如下:

<script nonce="{{ csp_nonce() }}"  src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.