Koba 是一个 Kitura 中间件,用于设置 HTTP 安全标头,以帮助缓解漏洞并防御攻击者。 它包含严格的默认配置和一个策略构建器,用于设计和覆盖安全标头值。
安全标头是 HTTP 响应标头,设置后可以通过启用浏览器安全策略来增强 Web 应用程序的安全性。
您可以在 securityheaders.com 或 Mozilla Observatory 评估 HTTP 响应标头的安全性。
Koba 使用的建议以及有关安全标头的更多信息可以在 OWASP 安全标头项目 和 Mozilla Web Security 中找到。
防止缓存 HTTPS 响应
默认值: no-cache, no-store, must-revalidate, max-age=0
防止跨站注入
默认值: script-src 'self'; object-src 'self'
(默认情况下未包含)
强制执行证书透明度 默认值: max-age=0
(默认情况下未包含)
禁用浏览器功能和 API
默认值: accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; camera 'none'; encrypted-media 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture 'none'; speaker 'none'; sync-xhr 'none'; usb 'none'; vr 'none'
(默认情况下未包含)
确保应用程序通信通过 HTTPS 发送
默认值: max-age=86400; includeSubDomains
如果同源则启用完整引用,跨域则删除路径,并在不受支持的浏览器中禁用引用
默认值: no-referrer, strict-origin-when-cross-origin
防止 MIME 嗅探
默认值: nosniff
禁用来自不同源的框架(点击劫持防御)
默认值: SAMEORIGIN
启用浏览器跨站脚本过滤器
默认值: 1; mode=block
hsts: nil
不包含 HSTS 标头。csp: CSP().default()
来启用默认值。添加到 dependencies
.package(url: "https://github.com/cak/koba", from: "0.2.0"),
添加到 target dependencies
.target(name: "name", dependencies: ["Koba"]),
导入包
import Koba
默认配置
import Kitura
import Koba
let koba = Koba()
let router = Router()
router.all(middleware: koba)
默认 HTTP 响应标头
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
X-Frame-Options: SAMEORIGIN
Cache-control: no-cache, no-store, must-revalidate, max-age=0
Strict-Transport-Security: max-age=86400; includeSubDomains
您可以通过传递带有 Header().default()
的对象来切换具有默认值的标头的设置,或者使用 nil
来删除标头。 您可以通过为自定义标头值传递 Header().set("custom")
或使用以下选项的策略构建器来覆盖默认值
例子
import Kitura
import Koba
let config = KobaConfig(
cacheControl: CacheControl()
.noStore()
.mustRevalidate()
.proxyRevalidate(),
csp: CSP()
.defaultSrc(Koba.Source.none)
.blockAllMixedContent()
.connectSrc(Koba.Source.sameOrigin, "api.swiftserver.dev"),
expectCT: ExpectCT()
.maxAge(Koba.Time.fiveMinutes)
.enforce(),
featurePolicy: FeaturePolicy()
.geolocation(Koba.Source.sameOrigin, "swiftserver.dev")
.vibrate(Koba.Source.none),
hsts: HSTS()
.includeSubdomains()
.preload()
.maxAge(Koba.Time.oneWeek),
referrerPolicy: ReferrerPolicy()
.noReferrer(),
xcto: nil,
xfo: XFO()
.deny(),
xxp: XXP()
.enabledBlock()
)
let koba = Koba(config: config)
router.all(middleware: koba)
Referrer-Policy: no-referrer
Strict-Transport-Security: includeSubDomains; preload; max-age=604800
Cache-control: no-store, must-revalidate, proxy-revalidate
Expect-CT: max-age=300; enforce
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'none'; block-all-mixed-content; connect-src 'self' api.swiftserver.dev
Feature-Policy: geolocation 'self' swiftserver.dev; vibrate 'none'
X-Frame-Options: DENY
data:
mediastream:
https:
blob:
filesystem:
'none'
'self'
'src'
'strict-dynamic'
'unsafe-eval'
'unsafe-inline'
*
300
86400
604800
2592000
31536000
63072000
例子
let config = KobaConfig(
csp: CSP().defaultSrc(Koba.Source.sameOrigin),
hsts: HSTS().maxAge(Koba.Time.oneDay)
)
let koba = Koba(config: config)
Content-Security-Policy: default-src 'self'
Strict-Transport-Security: max-age=86400
指令: private(), public(), immutable(), maxAge(seconds), maxStale(seconds), minFresh(seconds), mustRevalidate(), noCache(), noStore(), noTransform(), onlyIfCached(), proxyRevalidate(), sMaxage(seconds), staleIfError(seconds), staleWhileRevalidate(seconds)
例子
let policy = CacheControl()
.noStore()
.mustRevalidate()
.proxyRevalidate()
// no-store, must-revalidate, proxy-revalidate
指令: baseUri(sources), blockAllMixedContent(), connectSrc(sources), defaultSrc(sources), fontSrc(sources), formAction(sources), frameAncestors(sources), frameSrc(sources), imgSrc(sources), manifestSrc(sources), mediaSrc(sources), objectSrc(sources), pluginTypes(types), reportTo(ReportTo), reportUri(uri), requireSriFor(values), sandbox(values), scriptSrc(sources), styleSrc(sources), upgradeInsecureRequests(), workerSrc(sources)
您可以在 CSP Evaluator 检查 CSP 策略的有效性。
例子
let policy = CSP()
.defaultSrc(Koba.Source.none)
.baseUri(Koba.Source.sameOrigin)
.blockAllMixedContent()
.connectSrc(Koba.Source.sameOrigin, "api.swiftserver.dev")
.frameSrc(Koba.Source.none)
.imgSrc(Koba.Source.sameOrigin, "static.swiftserver.dev");
// default-src 'none'; base-uri 'self'; block-all-mixed-content; connect-src 'self' api.swiftserver.dev; frame-src 'none'; img-src 'self' static.swiftserver.dev
Content-Security-Policy-Report-Only
使用 reportOnly()
会将标头更改为 Content-Security-Policy-Report-Only
例子
let policy = CSP()
.defaultSrc(Koba.Source.none)
.baseUri(Koba.Source.sameOrigin)
.reportOnly()
let config = KobaConfig(csp: policy)
let koba = Koba(config: config)
router.all(middleware: koba)
Cache-control: no-cache, no-store, must-revalidate, max-age=0
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy-Report-Only: default-src 'none'; base-uri 'self'
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Frame-Options: SAMEORIGIN
report-to
let reportToEndpoint = CSP.ReportToEndpoint(url: "https://swiftserver.dev/reports")
let reportTo = CSP.ReportTo(group: "CSP-Endpoint",
maxAge: Koba.Time.oneWeek,
endpoints: [reportToEndpoint],
includeSubdomains: true)
let policy = CSP()
.defaultSrc(Koba.Source.none)
.baseUri(Koba.Source.sameOrigin)
.reportTo(reportTo)
// default-src 'none'; base-uri 'self'; report-to {"group":"CSP-Endpoint","endpoints":[{"url":"https:\/\/swiftserver.dev\/reports"}],"include_subdomains":true,"max_age":604800}
report-uri
let policy = CSP()
.defaultSrc(Koba.Source.none)
.baseUri(Koba.Source.sameOrigin)
.reportUri("https://swiftserver.dev/reports")
// default-src 'none'; base-uri 'self'; report-uri https://swiftserver.dev/reports
资源: CSP Cheat Sheet | Scott Helme , Content-Security-Policy | MDN , Content Security Policy Cheat Sheet | OWASP , Content Security Policy CSP Reference & Examples, 报告: The Reporting API | Google Developers, CSP: report-uri | MDN, report-to - HTTP | MDN
指令: maxAge(seconds), enforce(), reportUri(uri)
例子
let policy = ExpectCT()
.maxAge(Koba.Time.oneDay)
.enforce()
.reportUri("https://swiftserver.dev")
// max-age=86400; enforce; report-uri="https://swiftserver.dev"
资源: Expect-CT | MDN
指令: accelerometer(allowlist), ambientLightSensor(allowlist), autoplay(allowlist), camera(allowlist), documentDomain(allowlist), encryptedMedia(allowlist), fullscreen(allowlist), geolocation(allowlist), gyroscope(allowlist), magnetometer(allowlist), microphone(allowlist), midi(allowlist), payment(allowlist), pictureInPicture(allowlist), speaker(allowlist), syncXhr(allowlist), usb(allowlist), vibrate(allowlist), vr(allowlist)
例子
let policy = FeaturePolicy()
.geolocation(Koba.Source.sameOrigin, "swiftserver.dev")
.vibrate(Koba.Source.none)
// geolocation 'self' swiftserver.dev; vibrate 'none'
资源: A new security header: Feature Policy | Scott Helme , Feature-Policy | MDN , Introduction to Feature Policy | Google Developers
指令: includeSubdomains(), maxAge(seconds), preload()
例子
let policy = HSTS()
.maxAge(Koba.Time.oneMonth)
.includeSubdomains()
.preload()
// max-age=2592000; includeSubDomains; preload
资源: Strict-Transport-Security | MDN , HTTP Strict Transport Security Cheat Sheet | OWASP
指令:, noReferrer(), noReferrerWhenDowngrade(), origin(), originWhenCrossOrigin(), sameOrigin(), strictOrigin(), strictOriginWhenCrossOrigin(), unsafeUrl()
资源: A new security header: Referrer Policy | Scott Helme , Referrer-Policy | MDN
例子
let policy = XCTO().default()
// nosniff
资源: X-Content-Type-Options - HTTP | MDN
指令: allowFrom(), deny(), sameorigin()
例子
let policy = XFO().deny()
// DENY
指令: disabled(), enabled(), enabledBlock(), enabledReport(uri)
例子
let policy = XXP().enabledBlock()
// 1 mode=block
发送拉取请求,创建 issue 或在 Kitura Slack 上与我 (@cak) 讨论。
Kob'a (ko'-bah) 是希伯来语头盔的意思,是对 Helmet.js 的致敬。
正在寻找 Vapor 的安全标头? 请查看 Vapor Security Headers。