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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use futures::Future;
use plugins::{Plugin, PluginData};
use hyper::header::StrictTransportSecurity;
use hyper::header::ReferrerPolicy;
header! { (ContentSecurityPolicy, "Content-Security-Policy") => [String] }
header! { (XContentTypeOptions, "X-Content-Type-Options") => [String] }
header! { (XFrameOptions, "X-Frame-Options") => [String] }
header! { (XXssProtection, "X-Xss-Protection") => [String] }
pub enum GcReferrer {
NoReferrer,
SameOrigin
}
impl Default for GcReferrer {
fn default() -> GcReferrer {
GcReferrer::NoReferrer
}
}
pub struct GoodCitizen {
strict_transport_security: Option<StrictTransportSecurity>,
referrer_policy: Option<ReferrerPolicy>,
content_security_policy: Option<String>,
x_content_type_options: Option<String>,
x_frame_options: Option<String>,
x_xss_protection: Option<String>,
}
impl Default for GoodCitizen {
fn default() -> GoodCitizen {
GoodCitizen {
strict_transport_security: Some(
StrictTransportSecurity::including_subdomains(31536000u64)),
referrer_policy: Some(ReferrerPolicy::NoReferrer),
content_security_policy: Some("default-src https:; block-all-mixed-content; upgrade-insecure-requests;".to_owned()),
x_content_type_options: Some("nosniff".to_owned()),
x_frame_options: Some("DENY".to_owned()),
x_xss_protection: Some("1; mode=block".to_owned()),
}
}
}
impl GoodCitizen {
pub fn new() -> GoodCitizen {
Default::default()
}
pub fn disable_strict_transport_security(&mut self) {
self.strict_transport_security = None;
}
pub fn set_strict_transport_security(&mut self, sts: StrictTransportSecurity) {
self.strict_transport_security = Some(sts);
}
pub fn disable_referrer_policy(&mut self) {
self.referrer_policy = None;
}
pub fn set_referrer_policy(&mut self, rp: ReferrerPolicy) {
self.referrer_policy = Some(rp);
}
pub fn disable_content_security_policy(&mut self) {
self.content_security_policy = None;
}
pub fn set_content_security_policy(&mut self, csp: String) {
self.content_security_policy = Some(csp);
}
pub fn disable_x_content_type_options(&mut self) {
self.x_content_type_options = None;
}
pub fn set_x_content_type_options(&mut self, xcto: String) {
self.x_content_type_options = Some(xcto);
}
pub fn disable_x_frame_options(&mut self) {
self.x_frame_options = None;
}
pub fn set_x_frame_options(&mut self, xfo: String) {
self.x_frame_options = Some(xfo);
}
pub fn disable_x_xss_protection(&mut self) {
self.x_xss_protection = None;
}
pub fn set_x_xss_protection(&mut self, xss: String) {
self.x_xss_protection = Some(xss);
}
}
impl<S,E> Plugin<S,E> for GoodCitizen
where S: 'static, E: 'static
{
fn handle(&self, mut data: PluginData<S>)
-> Box<Future<Item = PluginData<S>, Error = E>>
{
if let Some(ref sts) = self.strict_transport_security {
data.response.headers_mut().set(sts.clone());
}
if let Some(ref rp) = self.referrer_policy {
data.response.headers_mut().set(rp.clone());
}
if let Some(ref csp) = self.content_security_policy {
data.response.headers_mut().set(ContentSecurityPolicy(csp.clone()));
}
if let Some(ref xcto) = self.x_content_type_options {
data.response.headers_mut().set(XContentTypeOptions(xcto.clone()));
}
if let Some(ref xss) = self.x_xss_protection {
data.response.headers_mut().set(XXssProtection(xss.clone()));
}
Box::new(::futures::future::ok(data))
}
}