我有一些服务需要不同的 Content-Security-Policy 标头。我最初的尝试是创建一个默认的中间件来处理所有通用标头,然后我可以为每个路由器创建具有唯一contentSecurityPolicy
设置的新中间件。
当您发现如果您有多个带有标头的中间件时,我感到很惊讶,最后应用的一个会覆盖前一个。这意味着我必须为每个服务在中间件中重新创建所有标头。而且,如果我将来进行更改,则必须确保在所有这些更改中都得到体现。
作为一种解决方法,我尝试添加带有 Content-Security-Policy 标头的customResponseHeaders
,但这并没有覆盖默认标头,即使它显示在仪表板上。
我的设置摘录:
...
[http.routers.service]
rule = "Host(`example.com`)"
entrypoints = ["https"]
middlewares = ["default", "service"]
service = "service"
...
[http.middlewares.default.headers]
accessControlAllowOrigin = "origin-list-or-null"
stsSeconds = 315360000
stsIncludeSubdomains = true
stsPreload = true
customFrameOptionsValue = "SAMEORIGIN"
contentTypeNosniff = true
browserXssFilter = true
referrerPolicy = "strict-origin"
contentSecurityPolicy = "default-src 'none';form-action 'none';frame-ancestors 'none';base-uri 'none'"
featurePolicy = "notifications 'none'; camera 'none'"
[http.middlewares.service.headers]
contentSecurityPolicy = "default-src 'none';script-src 'self' 'unsafe-inline';style-src 'self';img-src 'self'"
答案 0 :(得分:0)
在Traefik forums的讨论中,我指出了这样一个事实,即the used library的这种行为似乎是预期的。经过一些试验,我想出了以下解决方案:
跳过默认的安全标头,仅使用customResponseHeaders
选项。它们似乎是与提到的库分开处理的,可以合并,因此您必须首先从最特定的库开始,然后添加常规库,例如:middlewares = ["service", "default"]
这是问题中的重构标头:
[http.middlewares.default.headers.customResponseHeaders]
Access-Control-Allow-Origin = "null"
Content-Security-Policy = "default-src 'none';form-action 'none';frame-ancestors 'none';base-uri 'none'"
Feature-Policy = "notifications 'none'; camera 'none'"
Referrer-Policy = "strict-origin"
Server = "home.stoinov.com"
Strict-Transport-Security = "max-age=315360000; includeSubDomains; preload"
X-Content-Type-Options = "nosniff"
X-Frame-Options = "SAMEORIGIN"
X-Xss-Protection = "1; mode=block"
[http.middlewares.service.headers.customResponseHeaders]
Content-Security-Policy = "default-src 'none';script-src 'self' 'unsafe-inline';style-src 'self';img-src 'self'"
对于相同的结果,默认设置实际上比使用预定义的标题短了一行。
一个缺点是,在仪表板上,您会看到标题堆积在中间件卡的顶部,但是实际的安全标题将保留其默认值。如果我们有标头名称和值,说实话,这可能是一个加号。