1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! The response headers a browser needs in order to enforce anything.
//!
//! **The policy this application was written against did not exist.** Five
//! places in the kit — the stylesheet, the appearance tab, the layout — explain
//! that they avoid an inline `<style>` or an `on click` handler *because* the
//! pages are served under a Content-Security-Policy with no `unsafe-inline`.
//! The discipline was real and held: no inline style, no inline script, no
//! event-handler attributes, no external origin. The header was never sent, so
//! none of it bought anything. A browser enforces a policy it is given.
//!
//! It is given one now, and the discipline is what makes it safe to turn on:
//! this is a policy the pages already satisfy, not a policy they will have to
//! be rewritten for.
//!
//! `default-src 'self'` and `object-src 'none'` are the two that matter for
//! script injection — together they mean a `<script>` an attacker gets into the
//! page does not run unless it came from this origin. `frame-ancestors 'none'`
//! is clickjacking; `form-action 'self'` stops a planted form posting somebody's
//! session elsewhere.
use *;
/// The policy, as one header value.
///
/// `data:` is allowed for images only, because a QR code and an uploaded logo
/// can arrive that way. It is not allowed for scripts, which is where `data:`
/// is dangerous.
pub const POLICY: &str = "default-src 'self'; \
img-src 'self' data:; \
object-src 'none'; \
base-uri 'self'; \
frame-ancestors 'none'; \
form-action 'self'";
/// Sets the security headers on every response that does not already carry them.
///
/// Does not overwrite: a route that sets a narrower policy of its own — the
/// logo endpoint does — has thought about its own case, and a blanket
/// middleware should not undo that.
;