From b2d6678405f56e5a0cfdefa31990d2b55d08999c Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Thu, 9 Apr 2020 20:11:48 +0800 Subject: [PATCH] sanitize proxied remote content response re-construct the Response object to make sure no strange headers slip into our own response. --- Cargo.toml | 1 + src/lib.rs | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 75b2d73..7f3a06e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ "Crypto", "Headers", + "ReadableStream", "Request", "RequestInit", "RequestRedirect", diff --git a/src/lib.rs b/src/lib.rs index 5d8e2d5..fc9eda0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,6 +54,12 @@ extern "C" { fn fetch(req: &Request) -> Promise; } +macro_rules! get_header { + ($headers:expr, $name:expr) => { + $headers.get($name).internal_err()?.ok_or(Error::InternalError())? + }; +} + // A caching proxy for images inserted into articles // to protect user's privacy and accelerate page load async fn proxy_remote_image(req: Request, url: Url) -> MyResult { @@ -74,7 +80,17 @@ async fn proxy_remote_image(req: Request, url: Url) -> MyResult { RequestInit::new() .method("GET") .redirect(RequestRedirect::Follow)).internal_err()?; - Ok(JsFuture::from(fetch(&new_req)).await.internal_err()?.into()) + let remote_resp: Response = JsFuture::from(fetch(&new_req)).await.internal_err()?.into(); + let remote_headers = remote_resp.headers(); + + Response::new_with_opt_readable_stream_and_init( + remote_resp.body().as_ref(), + ResponseInit::new() + .status(remote_resp.status()) + .headers(headers!{ + "Content-Type" => &get_header!(remote_headers, "content-type") + }.as_ref()) + ).internal_err() } async fn default_route(_req: Request, url: Url) -> MyResult {