Policy Builder¶
CSP()¶
Directives: base_uri(sources)
, block_all_mixed_content()
,
connect_src(sources)
, default_src(sources)
,
font_src(sources)
, form_action(sources)
,
frame_ancestors(sources)
, frame_src(sources)
,
img_src(sources)
, manifest_src(sources)
, media_src(sources)
,
object_src(sources)
, plugin_types(types)
,
report_to(json_object)
, report_uri(uri)
,
require_sri_for(values)
, sandbox(values)
,
script_src(sources)
, style_src(sources)
,
upgrade_insecure_requests()
, worker_src(sources)
Values(): self_
, none
, unsafe_inline
, unsafe_eval
,
strict_dynamic
, nonce(nonce_value)
, all
= “*”
Example:
csp_value = (
SecurePolicies.CSP()
.default_src(SecurePolicies.CSP().Values.none)
.base_uri(SecurePolicies.CSP().Values.self_)
.block_all_mixed_content()
.connect_src(SecurePolicies.CSP().Values.self_, "api.spam.com")
.frame_src(SecurePolicies.CSP().Values.none)
.img_src(SecurePolicies.CSP().Values.self_, "static.spam.com")
)
# default-src 'none'; base-uri 'self'; block-all-mixed-content; connect-src 'self' api.spam.com; frame-src 'none'; img-src 'self' static.spam.com
You can check the effectiveness of your CSP Policy at the CSP Evaluator
HSTS()¶
Directives: include_subDomains()
, max_age(seconds)
,
preload()
Example:
hsts_value = (
SecurePolicies.HSTS()
.include_subdomains()
.preload()
.max_age(SecurePolicies.Seconds.one_month)
)
# includeSubDomains; preload; max-age=2592000
XXP()¶
Directives: disabled()
= 0, enabled()
= 1,
enabled_block()
= 1; mode=block, enabled_report(uri)
= 1;
report=uri
Example:
xxp_value = SecurePolicies.XXP().enabled_block()
# 1; mode=block
XFO()¶
Directives: allow_from(uri)
, deny()
, sameorigin()
Example:
xfo_value = SecurePolicies.XFO().deny()
# deny
Referrer()¶
Directives: no_referrer()
, no_referrer_when_downgrade()
,
origin()
, origin_when_cross_origin()
, same_origin()
,
strict_origin()
, strict_origin_when_cross_origin()
,
unsafe_url()
Example:
referrer_value = SecurePolicies.Referrer().no_referrer()
# no-referrer
Feature()¶
Directives: accelerometer(allowlist)
,
ambient_light_sensor(allowlist)
, autoplay(allowlist)
,
camera(allowlist)
, document_domain(allowlist)
,
encrypted_media(allowlist)
, fullscreen(allowlist)
,
geolocation(allowlist)
, gyroscope(allowlist)
,
magnetometer(allowlist)
, microphone(allowlist)
,
midi(allowlist)
, payment(allowlist)
,
picture_in_picture(allowlist)
, speaker(allowlist)
,
sync_xhr(allowlist)
, usb(allowlist)
, Values(allowlist)
,
vr(allowlist)
Values(): self_
, none
, src
, all_
= “*”
Example:
feature_value = (
SecurePolicies.Feature()
.geolocation(SecurePolicies.Feature.Values.self_, "spam.com")
.vibrate(SecurePolicies.Feature.Values.none)
)
# geolocation 'self' spam.com; vibrate 'none'
Cache()¶
Directives: immutable()
, max_age(seconds)
,
max_stale(seconds)
, min_fresh(seconds)
, must_revalidate()
,
no_cache()
, no_store()
, no_transform()
,
only_if_cached()
, private()
, proxy_revalidate()
,
public()
, s_maxage(seconds)
, stale_if_error(seconds)
,
stale_while_revalidate(seconds)
,
Example:
cache_value = SecurePolicies.Cache().no_store().must_revalidate().proxy_revalidate()
# no-store, must-revalidate, proxy-revalidate
Seconds¶
Values: five_minutes
= “300”, one_week
= “604800”,
one_month
= “2592000”, one_year
= “31536000”, two_years
=
“63072000”
Usage¶
Example:
from sanic import Sanic
from secure import SecureHeaders, SecurePolicies
csp_value = (
SecurePolicies.CSP()
.default_src(SecurePolicies.CSP().Values.none)
.base_uri(SecurePolicies.CSP().Values.self_)
.block_all_mixed_content()
.connect_src(SecurePolicies.CSP().Values.self_, "api.spam.com")
.frame_src(SecurePolicies.CSP().Values.none)
.img_src(SecurePolicies.CSP().Values.self_, "static.spam.com")
)
hsts_value = (
SecurePolicies.HSTS()
.include_subdomains()
.preload()
.max_age(SecurePolicies.Seconds.one_month)
)
xxp_value = SecurePolicies.XXP().enabled_block()
xfo_value = SecurePolicies.XFO().deny()
referrer_value = SecurePolicies.Referrer().no_referrer()
feature_value = (
SecurePolicies.Feature()
.geolocation(SecurePolicies.Feature.Values.self_, "spam.com")
.vibrate(SecurePolicies.Feature.Values.none)
)
cache_value = SecurePolicies.Cache().no_store().must_revalidate().proxy_revalidate()
secure_headers = SecureHeaders(
csp=csp_value,
hsts=hsts_value,
xfo=xfo_value,
xxp=xxp_value,
referrer=referrer_value,
feature=feature_value,
cache=cache_value,
)
secure_cookie = SecureCookie()
app = Sanic()
. . .
@app.middleware("response")
async def set_secure_headers(request, response):
secure_headers.sanic(response)
. . .
Response Headers:
Strict-Transport-Security: includeSubDomains; preload; max-age=2592000
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; connect-src 'self' api.spam.com; frame-src 'none'; img-src 'self' static.spam.com
Referrer-Policy: no-referrer
Cache-control: no-store, must-revalidate, proxy-revalidate
Feature-Policy: geolocation 'self' spam.com; vibrate 'none'