Compatibility
- 0.2.0 and master5.35.25.15.04.2
- 0.2.0 and masteriOSmacOS(Intel)macOS(ARM)LinuxtvOSwatchOS
Security Headers for Kitura
Koba is a Kitura middleware for setting HTTP security headers to help mitigate vulnerabilities and protect against attackers. It contains a strict default configuration and a policy builder for designing and overriding security header values.
Security Headers are HTTP response headers that, when set, can enhance the security of your web application by enabling browser security policies.
You can assess the security of your HTTP response headers at securityheaders.com or at the Mozilla Observatory
Recommendations used by Koba and more information regarding security headers can be found at the OWASP Secure Headers Project and Mozilla Web Security
Prevent cacheable HTTPS response
Default Value: no-cache, no-store, must-revalidate, max-age=0
Prevent cross-site injections
Default Value: script-src 'self'; object-src 'self'
(not included by default)
Enforcement of Certificate Transparency
Default Value: max-age=0
(not included by default)
Disable browser features and APIs
Default Value: 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'
(not included by default)
Ensure application communication is sent over HTTPS
Default Value: max-age=86400; includeSubDomains
Enable full referrer if same origin, remove path for cross origin and disable referrer in unsupported browsers
Default Value: no-referrer, strict-origin-when-cross-origin
Prevent MIME-sniffing
Default Value: nosniff
Disable framing from different origins (clickjacking defense)
Default Value: SAMEORIGIN
Enable browser cross-site scripting filters
Default Value: 1; mode=block
hsts: nil
in the KobaConfig to not include the HSTS header.csp: CSP().default()
in the KobaConfig to enable default values.Add to dependencies
.package(url: "https://github.com/cak/koba", from: "0.2.0"),
Add to target dependencies
.target(name: "name", dependencies: ["Koba"]),
Import package
import Koba
Default configuration:
import Kitura
import Koba
let koba = Koba()
let router = Router()
router.all(middleware: koba)
Default HTTP response headers:
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
You can toggle the setting of headers with default values by passing an object with Header().default()
or nil
to remove the header. You can override default values by passing Header().set("custom")
for a custom header value or using the policy builder for the following options:
Example:
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
Example
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
Directives: private(), public(), immutable(), maxAge(seconds), maxStale(seconds), minFresh(seconds), mustRevalidate(), noCache(), noStore(), noTransform(), onlyIfCached(), proxyRevalidate(), sMaxage(seconds), staleIfError(seconds), staleWhileRevalidate(seconds)
Example:
let policy = CacheControl()
.noStore()
.mustRevalidate()
.proxyRevalidate()
// no-store, must-revalidate, proxy-revalidate
Resources: Cache-Control | MDN
Directives: 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)
You can check the effectiveness of your CSP Policy at the CSP Evaluator
Example:
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
Using reportOnly()
will change the header to Content-Security-Policy-Report-Only
Example:
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
Resources: CSP Cheat Sheet | Scott Helme , Content-Security-Policy | MDN , Content Security Policy Cheat Sheet | OWASP , Content Security Policy CSP Reference & Examples, Reporting: The Reporting API | Google Developers, CSP: report-uri | MDN, report-to - HTTP | MDN
Directives: maxAge(seconds), enforce(), reportUri(uri)
Example:
let policy = ExpectCT()
.maxAge(Koba.Time.oneDay)
.enforce()
.reportUri("https://swiftserver.dev")
// max-age=86400; enforce; report-uri="https://swiftserver.dev"
Resources: Expect-CT | MDN
Directives: 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)
Example:
let policy = FeaturePolicy()
.geolocation(Koba.Source.sameOrigin, "swiftserver.dev")
.vibrate(Koba.Source.none)
// geolocation 'self' swiftserver.dev; vibrate 'none'
Resources: A new security header: Feature Policy | Scott Helme , Feature-Policy | MDN , Introduction to Feature Policy | Google Developers
Directives: includeSubdomains(), maxAge(seconds), preload()
Example:
let policy = HSTS()
.maxAge(Koba.Time.oneMonth)
.includeSubdomains()
.preload()
// max-age=2592000; includeSubDomains; preload
Resources: Strict-Transport-Security | MDN , HTTP Strict Transport Security Cheat Sheet | OWASP
Directives:, noReferrer(), noReferrerWhenDowngrade(), origin(), originWhenCrossOrigin(), sameOrigin(), strictOrigin(), strictOriginWhenCrossOrigin(), unsafeUrl()
Resources: A new security header: Referrer Policy | Scott Helme , Referrer-Policy | MDN
Examples:
let policy = XCTO().default()
// nosniff
Resources: X-Content-Type-Options - HTTP | MDN
Directives: allowFrom(), deny(), sameorigin()
Examples:
let policy = XFO().deny()
// DENY
Resources: X-Frame-Options | MDN
Directives: disabled(), enabled(), enabledBlock(), enabledReport(uri)
Examples:
let policy = XXP().enabledBlock()
// 1 mode=block
Resources: X-XSS-Protection | MDN
Send a pull request, create an issue or discuss with me (@cak) on the the Kitura Slack.
Kob'a (ko'-bah) is the Hebrew word for helmet, a nod to Helmet.js.
Looking for security headers for Vapor? Check out Vapor Security Headers.