pub struct ContentSecurityPolicy { /* private fields */ }Expand description
A Content-Security-Policy header, built directive by directive, and the layer that sends it.
Rails’ content_security_policy initializer as plain Rust: build the
policy in src/lib.rs and add it to the router with .layer(policy)
(generated apps do, in content_security_policy()). Every response gets
the header unless the handler (or a layer closer to it) set one already,
which is how routes override the global policy: give a nested router its
own .layer(...), or return the header from the handler.
Sources are written as in the header: SELF, NONE, DATA,
"https://unpkg.com", … NONCE stands for the request’s random nonce
(see CspNonce). Calling a directive twice replaces it.
report_only sends
Content-Security-Policy-Report-Only instead, to try a policy without
breaking pages; report_uri and
report_to collect violations.
§Free plan
A header per response and, when the policy uses NONCE, 16 random
bytes per request: no binding call, microseconds of CPU.
§Examples
use axum::{Router, routing::get};
use ocre::security::{ContentSecurityPolicy, DATA, NONCE, NONE, SELF};
let policy = ContentSecurityPolicy::new()
.default_src(&[SELF])
.script_src(&[SELF, NONCE, "https://unpkg.com"])
.img_src(&[SELF, DATA])
.object_src(&[NONE])
.report_uri("/csp-reports");
assert_eq!(
policy.header_value(Some("r4nd0m")),
"default-src 'self'; script-src 'self' 'nonce-r4nd0m' https://unpkg.com; img-src 'self' data:; \
object-src 'none'; report-uri /csp-reports"
);
let app: Router = Router::new().route("/", get(|| async { "home" })).layer(policy);Implementations§
Source§impl ContentSecurityPolicy
impl ContentSecurityPolicy
Sourcepub fn new() -> Self
pub fn new() -> Self
An empty policy: add directives with the builder methods.
§Examples
assert_eq!(ocre::security::ContentSecurityPolicy::new().header_value(None), "");Sourcepub fn directive(self, name: &str, sources: &[&str]) -> Self
pub fn directive(self, name: &str, sources: &[&str]) -> Self
Sets any directive, e.g. directive("sandbox", &["allow-forms"]); replaces a previous value.
An empty sources list writes the directive alone
(upgrade-insecure-requests).
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
let csp = ContentSecurityPolicy::new().directive("worker-src", &[SELF]).directive("worker-src", &["blob:"]);
assert_eq!(csp.header_value(None), "worker-src blob:");Sourcepub fn default_src(self, sources: &[&str]) -> Self
pub fn default_src(self, sources: &[&str]) -> Self
default-src: the fallback for every fetch directive not set.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
assert_eq!(ContentSecurityPolicy::new().default_src(&[SELF]).header_value(None), "default-src 'self'");Sourcepub fn script_src(self, sources: &[&str]) -> Self
pub fn script_src(self, sources: &[&str]) -> Self
script-src: where scripts may come from.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
let csp = ContentSecurityPolicy::new().script_src(&[SELF, "https://unpkg.com"]);
assert_eq!(csp.header_value(None), "script-src 'self' https://unpkg.com");Sourcepub fn style_src(self, sources: &[&str]) -> Self
pub fn style_src(self, sources: &[&str]) -> Self
style-src: where stylesheets and inline styles may come from.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF, UNSAFE_INLINE};
let csp = ContentSecurityPolicy::new().style_src(&[SELF, UNSAFE_INLINE]);
assert_eq!(csp.header_value(None), "style-src 'self' 'unsafe-inline'");Sourcepub fn img_src(self, sources: &[&str]) -> Self
pub fn img_src(self, sources: &[&str]) -> Self
img-src: images and favicons.
§Examples
use ocre::security::{ContentSecurityPolicy, DATA, SELF};
assert_eq!(ContentSecurityPolicy::new().img_src(&[SELF, DATA]).header_value(None), "img-src 'self' data:");Sourcepub fn font_src(self, sources: &[&str]) -> Self
pub fn font_src(self, sources: &[&str]) -> Self
font-src: web fonts.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
assert_eq!(ContentSecurityPolicy::new().font_src(&[SELF]).header_value(None), "font-src 'self'");Sourcepub fn connect_src(self, sources: &[&str]) -> Self
pub fn connect_src(self, sources: &[&str]) -> Self
connect-src: fetch, XHR (htmx requests), WebSockets and EventSource.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
assert_eq!(ContentSecurityPolicy::new().connect_src(&[SELF]).header_value(None), "connect-src 'self'");Sourcepub fn media_src(self, sources: &[&str]) -> Self
pub fn media_src(self, sources: &[&str]) -> Self
media-src: <audio> and <video>.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
assert_eq!(ContentSecurityPolicy::new().media_src(&[SELF]).header_value(None), "media-src 'self'");Sourcepub fn object_src(self, sources: &[&str]) -> Self
pub fn object_src(self, sources: &[&str]) -> Self
Sourcepub fn frame_src(self, sources: &[&str]) -> Self
pub fn frame_src(self, sources: &[&str]) -> Self
frame-src: pages this app may put in an <iframe>.
§Examples
use ocre::security::ContentSecurityPolicy;
let csp = ContentSecurityPolicy::new().frame_src(&["https://www.youtube-nocookie.com"]);
assert_eq!(csp.header_value(None), "frame-src https://www.youtube-nocookie.com");Sourcepub fn frame_ancestors(self, sources: &[&str]) -> Self
pub fn frame_ancestors(self, sources: &[&str]) -> Self
frame-ancestors: sites that may put this app in a frame (the modern X-Frame-Options).
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
assert_eq!(ContentSecurityPolicy::new().frame_ancestors(&[SELF]).header_value(None), "frame-ancestors 'self'");Sourcepub fn form_action(self, sources: &[&str]) -> Self
pub fn form_action(self, sources: &[&str]) -> Self
form-action: where forms may be submitted.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
assert_eq!(ContentSecurityPolicy::new().form_action(&[SELF]).header_value(None), "form-action 'self'");Sourcepub fn base_uri(self, sources: &[&str]) -> Self
pub fn base_uri(self, sources: &[&str]) -> Self
base-uri: allowed <base href> values.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
assert_eq!(ContentSecurityPolicy::new().base_uri(&[SELF]).header_value(None), "base-uri 'self'");Sourcepub fn upgrade_insecure_requests(self) -> Self
pub fn upgrade_insecure_requests(self) -> Self
upgrade-insecure-requests: browsers load http: resources over HTTPS.
§Examples
use ocre::security::ContentSecurityPolicy;
let csp = ContentSecurityPolicy::new().upgrade_insecure_requests();
assert_eq!(csp.header_value(None), "upgrade-insecure-requests");Sourcepub fn report_uri(self, uri: &str) -> Self
pub fn report_uri(self, uri: &str) -> Self
report-uri: where browsers POST violation reports (JSON), e.g. a route of the app.
§Examples
use ocre::security::ContentSecurityPolicy;
let csp = ContentSecurityPolicy::new().report_uri("/csp-reports");
assert_eq!(csp.header_value(None), "report-uri /csp-reports");Sourcepub fn report_to(self, group: &str) -> Self
pub fn report_to(self, group: &str) -> Self
report-to: the Reporting-Endpoints group violation reports go to.
Send the Reporting-Endpoints: csp="/csp-reports" header too
(browsers without Reporting API support use report_uri).
§Examples
use ocre::security::ContentSecurityPolicy;
assert_eq!(ContentSecurityPolicy::new().report_to("csp").header_value(None), "report-to csp");Sourcepub fn report_only(self) -> Self
pub fn report_only(self) -> Self
Sends Content-Security-Policy-Report-Only: browsers report violations but block nothing.
§Examples
use ocre::security::{ContentSecurityPolicy, SELF};
let csp = ContentSecurityPolicy::new().default_src(&[SELF]).report_only();
assert_eq!(csp.header_name(), "content-security-policy-report-only");Sourcepub fn header_name(&self) -> HeaderName
pub fn header_name(&self) -> HeaderName
content-security-policy, or content-security-policy-report-only after
report_only.
§Examples
assert_eq!(ocre::security::ContentSecurityPolicy::new().header_name(), "content-security-policy");Sourcepub fn header_value(&self, nonce: Option<&str>) -> String
pub fn header_value(&self, nonce: Option<&str>) -> String
The header value, with NONCE replaced by 'nonce-<nonce>' (and dropped when nonce is None).
§Examples
use ocre::security::{ContentSecurityPolicy, NONCE, SELF};
let csp = ContentSecurityPolicy::new().default_src(&[SELF]).script_src(&[SELF, NONCE]);
assert_eq!(csp.header_value(Some("n0nce")), "default-src 'self'; script-src 'self' 'nonce-n0nce'");
assert_eq!(csp.header_value(None), "default-src 'self'; script-src 'self'");Trait Implementations§
Source§impl Clone for ContentSecurityPolicy
impl Clone for ContentSecurityPolicy
Source§fn clone(&self) -> ContentSecurityPolicy
fn clone(&self) -> ContentSecurityPolicy
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ContentSecurityPolicy
impl Debug for ContentSecurityPolicy
Source§impl Default for ContentSecurityPolicy
impl Default for ContentSecurityPolicy
Source§fn default() -> ContentSecurityPolicy
fn default() -> ContentSecurityPolicy
impl Eq for ContentSecurityPolicy
Source§impl<S> Layer<S> for ContentSecurityPolicy
impl<S> Layer<S> for ContentSecurityPolicy
Source§type Service = PolicyService<S, ContentSecurityPolicy>
type Service = PolicyService<S, ContentSecurityPolicy>
Source§impl PartialEq for ContentSecurityPolicy
impl PartialEq for ContentSecurityPolicy
Source§fn eq(&self, other: &ContentSecurityPolicy) -> bool
fn eq(&self, other: &ContentSecurityPolicy) -> bool
self and other values to be equal, and is used by ==.impl StructuralPartialEq for ContentSecurityPolicy
Auto Trait Implementations§
impl Freeze for ContentSecurityPolicy
impl RefUnwindSafe for ContentSecurityPolicy
impl Send for ContentSecurityPolicy
impl Sync for ContentSecurityPolicy
impl Unpin for ContentSecurityPolicy
impl UnsafeUnpin for ContentSecurityPolicy
impl UnwindSafe for ContentSecurityPolicy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.