aboutsummaryrefslogtreecommitdiffstats
path: root/components/net/fetch/methods.rs
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2019-09-28 19:42:40 +0000
committerMichael Howell <michael@notriddle.com>2019-10-16 19:46:45 +0000
commitb8f3e8bb2e9bed269a06134c902a139cfa42eb1c (patch)
tree01351cae22488ad49307a5a51f141ba3e29274b2 /components/net/fetch/methods.rs
parent6d488f1be24c1b679931d6d02703f4a10759eb49 (diff)
downloadservo-b8f3e8bb2e9bed269a06134c902a139cfa42eb1c.tar.gz
servo-b8f3e8bb2e9bed269a06134c902a139cfa42eb1c.zip
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
Diffstat (limited to 'components/net/fetch/methods.rs')
-rw-r--r--components/net/fetch/methods.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs
index b60265ce2b8..fd225991568 100644
--- a/components/net/fetch/methods.rs
+++ b/components/net/fetch/methods.rs
@@ -8,6 +8,7 @@ use crate::filemanager_thread::{fetch_file_in_chunks, FileManager, FILE_CHUNK_SI
use crate::http_loader::{determine_request_referrer, http_fetch, HttpState};
use crate::http_loader::{set_default_accept, set_default_accept_language};
use crate::subresource_integrity::is_response_integrity_valid;
+use content_security_policy as csp;
use crossbeam_channel::{unbounded, Receiver, Sender};
use devtools_traits::DevtoolsControlMsg;
use headers::{AccessControlExposeHeaders, ContentType, HeaderMapExt, Range};
@@ -138,6 +139,30 @@ pub fn fetch_with_cors_cache(
main_fetch(request, cache, false, false, target, &mut None, &context);
}
+/// https://www.w3.org/TR/CSP/#should-block-request
+pub fn should_request_be_blocked_by_csp(request: &Request) -> csp::CheckResult {
+ let origin = match &request.origin {
+ Origin::Client => return csp::CheckResult::Allowed,
+ Origin::Origin(origin) => origin,
+ };
+ let csp_request = csp::Request {
+ url: request.url().into_url(),
+ origin: origin.clone().into_url_origin(),
+ redirect_count: request.redirect_count,
+ destination: request.destination,
+ initiator: csp::Initiator::None,
+ nonce: String::new(),
+ integrity_metadata: request.integrity_metadata.clone(),
+ parser_metadata: csp::ParserMetadata::None,
+ };
+ // TODO: Instead of ignoring violations, report them.
+ request
+ .csp_list
+ .as_ref()
+ .map(|c| c.should_request_be_blocked(&csp_request).0)
+ .unwrap_or(csp::CheckResult::Allowed)
+}
+
/// [Main fetch](https://fetch.spec.whatwg.org/#concept-main-fetch)
pub fn main_fetch(
request: &mut Request,
@@ -163,8 +188,18 @@ pub fn main_fetch(
}
}
+ // Step 2.2.
+ // TODO: Report violations.
+
+ // Step 2.4.
+ if should_request_be_blocked_by_csp(request) == csp::CheckResult::Blocked {
+ response = Some(Response::network_error(NetworkError::Internal(
+ "Blocked by Content-Security-Policy".into(),
+ )))
+ }
+
// Step 3.
- // TODO: handle content security policy violations.
+ // TODO: handle request abort.
// Step 4.
// TODO: handle upgrade to a potentially secure URL.