Add support for Upgrade request to a potentially trustworthy URL. (#34986)

* Add support for Upgrade request to a potentially trustworthy URL.

Signed-off-by: Shubham Gupta <shubham13297@gmail.com>

* script: Support inheritable insecure request policy in documents and workers.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

---------

Signed-off-by: Shubham Gupta <shubham13297@gmail.com>
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
Co-authored-by: Shubham Gupta <shubham.gupta@chromium.org>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Shubham Gupta 2025-02-05 20:49:56 +08:00 committed by GitHub
parent 7b36f2beb3
commit 1e164738d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 264 additions and 346 deletions

View file

@ -14,17 +14,17 @@ use crossbeam_channel::Sender;
use devtools_traits::DevtoolsControlMsg;
use headers::{AccessControlExposeHeaders, ContentType, HeaderMapExt};
use http::header::{self, HeaderMap, HeaderName};
use http::{Method, StatusCode};
use http::{HeaderValue, Method, StatusCode};
use ipc_channel::ipc;
use log::warn;
use log::{debug, trace, warn};
use mime::{self, Mime};
use net_traits::filemanager_thread::{FileTokenCheck, RelativePos};
use net_traits::http_status::HttpStatus;
use net_traits::policy_container::{PolicyContainer, RequestPolicyContainer};
use net_traits::request::{
is_cors_safelisted_method, is_cors_safelisted_request_header, BodyChunkRequest,
BodyChunkResponse, CredentialsMode, Destination, Origin, RedirectMode, Referrer, Request,
RequestMode, ResponseTainting, Window,
BodyChunkResponse, CredentialsMode, Destination, InsecureRequestsPolicy, Origin, RedirectMode,
Referrer, Request, RequestMode, ResponseTainting, Window,
};
use net_traits::response::{Response, ResponseBody, ResponseType};
use net_traits::{
@ -251,8 +251,32 @@ pub async fn main_fetch(
// Step 3.
// TODO: handle request abort.
// Step 4.
// TODO: handle upgrade to a potentially secure URL.
// Step 4. Upgrade request to a potentially trustworthy URL, if appropriate.
if should_upgrade_request_to_potentially_trustworty(request, context) {
trace!(
"upgrading {} targeting {:?}",
request.current_url(),
request.destination
);
if let Some(new_scheme) = match request.current_url().scheme() {
"http" => Some("https"),
"ws" => Some("wss"),
_ => None,
} {
request
.current_url_mut()
.as_mut_url()
.set_scheme(new_scheme)
.unwrap();
}
} else {
trace!(
"not upgrading {} targeting {:?} with {:?}",
request.current_url(),
request.destination,
request.insecure_requests_policy
);
}
// Step 5.
if should_be_blocked_due_to_bad_port(&request.current_url()) {
@ -881,3 +905,62 @@ fn is_bad_port(port: u16) -> bool {
BAD_PORTS.binary_search(&port).is_ok()
}
// TODO : Investigate and need to revisit again
pub fn is_form_submission_request(request: &Request) -> bool {
let content_type = request.headers.typed_get::<ContentType>();
content_type.is_some_and(|ct| {
let mime: Mime = ct.into();
mime.type_() == mime::APPLICATION && mime.subtype() == mime::WWW_FORM_URLENCODED
})
}
/// <https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request>
fn should_upgrade_request_to_potentially_trustworty(
request: &mut Request,
context: &FetchContext,
) -> bool {
fn should_upgrade_navigation_request(request: &Request) -> bool {
// Step 2.1 If request is a form submission, skip the remaining substeps, and continue upgrading request.
if is_form_submission_request(request) {
return true;
}
// Step 2.2
// TODO If requests client's target browsing context is a nested browsing context
// Step 2.4
// TODO : check for insecure navigation set after its implemention
// Step 2.5 Return without further modifying request
false
}
// Step 1. If request is a navigation request,
if request.is_navigation_request() {
// Append a header named Upgrade-Insecure-Requests with a value of 1 to
// requests header list if any of the following criteria are met:
// * requests URL is not a potentially trustworthy URL
// * requests URL's host is not a preloadable HSTS host
if !request.current_url().is_origin_trustworthy() ||
!context
.state
.hsts_list
.read()
.unwrap()
.is_host_secure(request.current_url().host_str().unwrap())
{
debug!("Appending the Upgrade-Insecure-Requests header to requests header list");
request
.headers
.insert("Upgrade-Insecure-Requests", HeaderValue::from_static("1"));
}
if !should_upgrade_navigation_request(request) {
return false;
}
}
// Step 4
request.insecure_requests_policy == InsecureRequestsPolicy::Upgrade
}