diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 9eedd748c2d..de41bfa202a 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -143,6 +143,18 @@ pub fn main_fetch(request: Rc, // Step 5 // TODO this step (CSP port/content blocking) + if let Some(port) = request.url().port() { + let is_ftp = request.url().scheme() == "ftp" && (port == 20 || port == 21); + static BAD_PORTS: [u16; 64] = [1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, + 43, 53, 77, 79, 87, 95, 101, 102, 103, 104, 109, 110, 111, + 113, 115, 117, 119, 123, 135, 139, 143, 179, 389, 465, 512, + 513, 514, 515, 526, 530, 531, 532, 540, 556, 563, 587, 601, + 636, 993, 995, 2049, 3659, 4045, 6000, 6665, 6666, 6667, + 6668, 6669]; + if !is_ftp && BAD_PORTS.binary_search(&port).is_ok() { + response = Some(Response::network_error(NetworkError::Internal("Request attempted on bad port".into()))); + } + } // Step 6 // TODO this step (referrer policy) diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs index b2047056253..c88c8b1bf59 100644 --- a/tests/unit/net/fetch.rs +++ b/tests/unit/net/fetch.rs @@ -23,6 +23,7 @@ use hyper::status::StatusCode; use hyper::uri::RequestUri; use msg::constellation_msg::TEST_PIPELINE_ID; use net::fetch::cors_cache::CorsCache; +use net_traits::NetworkError; use net_traits::ReferrerPolicy; use net_traits::request::{Origin, RedirectMode, Referrer, Request, RequestMode}; use net_traits::response::{CacheState, Response, ResponseBody, ResponseType}; @@ -59,6 +60,18 @@ fn test_fetch_response_is_not_network_error() { } } +#[test] +fn test_fetch_on_bad_port_is_network_error() { + let url = ServoUrl::parse("http://www.example.org:6667").unwrap(); + let origin = Origin::Origin(url.origin()); + let request = Request::new(url, Some(origin), false, None); + *request.referrer.borrow_mut() = Referrer::NoReferrer; + let fetch_response = fetch(request, None); + assert!(fetch_response.is_network_error()); + let fetch_error = fetch_response.get_network_error().unwrap(); + assert!(fetch_error == &NetworkError::Internal("Request attempted on bad port".into())) +} + #[test] fn test_fetch_response_body_matches_const_message() { static MESSAGE: &'static [u8] = b"Hello World!"; diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 4bbd447339f..54315c84a42 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -39725,6 +39725,12 @@ "url": "/cssom/shorthand-serialization.html" } ], + "fetch/api/request/request-bad-port.html": [ + { + "path": "fetch/api/request/request-bad-port.html", + "url": "/fetch/api/request/request-bad-port.html" + } + ], "html/semantics/forms/form-submission-0/submit-entity-body.html": [ { "path": "html/semantics/forms/form-submission-0/submit-entity-body.html", diff --git a/tests/wpt/web-platform-tests/fetch/api/request/request-bad-port.html b/tests/wpt/web-platform-tests/fetch/api/request/request-bad-port.html new file mode 100644 index 00000000000..e7535cf50a5 --- /dev/null +++ b/tests/wpt/web-platform-tests/fetch/api/request/request-bad-port.html @@ -0,0 +1,82 @@ + + + + + +