Add simple implementation of content-security-policy on scripts / styles

This needs a lot more hooks before it'll actually be a good
implementation, but for a start it can help get some feedback on if this
is the right way to go about it.

Part of servo/servo#4577
This commit is contained in:
Michael Howell 2019-09-28 19:42:40 +00:00
parent 6d488f1be2
commit b8f3e8bb2e
16 changed files with 175 additions and 41 deletions

View file

@ -35,6 +35,7 @@ use crate::dom::text::Text;
use crate::dom::virtualmethods::vtable_for;
use crate::network_listener::PreInvoke;
use crate::script_thread::ScriptThread;
use content_security_policy::{self as csp, CspList};
use dom_struct::dom_struct;
use embedder_traits::resources::{self, Resource};
use encoding_rs::Encoding;
@ -736,6 +737,31 @@ impl FetchResponseListener for ParserContext {
.and_then(|meta| meta.content_type)
.map(Serde::into_inner)
.map(Into::into);
// https://www.w3.org/TR/CSP/#initialize-document-csp
// TODO: Implement step 1 (local scheme special case)
let csp_list = metadata.as_ref().and_then(|m| {
let h = m.headers.as_ref()?;
let mut csp = h.get_all("content-security-policy").iter();
// This silently ignores the CSP if it contains invalid Unicode.
// We should probably report an error somewhere.
let c = csp.next().and_then(|c| c.to_str().ok())?;
let mut csp_list = CspList::parse(
c,
csp::PolicySource::Header,
csp::PolicyDisposition::Enforce,
);
for c in csp {
let c = c.to_str().ok()?;
csp_list.append(CspList::parse(
c,
csp::PolicySource::Header,
csp::PolicyDisposition::Enforce,
));
}
Some(csp_list)
});
let parser = match ScriptThread::page_headers_available(&self.id, metadata) {
Some(parser) => parser,
None => return,
@ -744,6 +770,8 @@ impl FetchResponseListener for ParserContext {
return;
}
parser.document.set_csp_list(csp_list);
self.parser = Some(Trusted::new(&*parser));
match content_type {