Skip to content

Commit 0126195

Browse files
committed
block requests with # in the path (likely XSS probes)
1 parent 89ec830 commit 0126195

2 files changed

Lines changed: 9 additions & 2 deletions

File tree

crates/bin/docs_rs_web/src/handlers/rustdoc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3364,8 +3364,8 @@ mod test {
33643364
let web = env.web_app().await;
33653365

33663366
web.assert_redirect_cached_unchecked(
3367-
"/minidumper/latest/%23%3c%2f%73%63%72%69%70%74%3e%3c%74%65%73%74%65%3e",
3368-
"/minidumper/latest/%23%3C/script%3E%3Cteste%3E",
3367+
"/minidumper/latest/%3c%2f%73%63%72%69%70%74%3e%3c%74%65%73%74%65%3e",
3368+
"/minidumper/latest/%3C/script%3E%3Cteste%3E",
33693369
CachePolicy::ForeverInCdn(KrateName::from_str("minidumper").unwrap().into()),
33703370
env.config(),
33713371
)

crates/bin/docs_rs_web/src/middleware/security.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ pub(crate) async fn security_middleware(
2525
return StatusCode::NOT_ACCEPTABLE.into_response();
2626
}
2727

28+
// `#` is never allowed in any rustdoc URLs, even encoded
29+
if path.contains('#') {
30+
warn!(%uri, "detected `#` in server-side request path");
31+
return StatusCode::NOT_ACCEPTABLE.into_response();
32+
}
33+
2834
next.run(req).await
2935
}
3036

@@ -46,6 +52,7 @@ mod tests {
4652
#[test_case("/.."; "relative path")]
4753
#[test_case("/asdf/../"; "relative path 2")]
4854
#[test_case("/tiny_http/latest/tiny_http%2f%2e%2e"; "encoded")]
55+
#[test_case("/minidumper/latest/%23%3c%2f%73%63%72%69%70%74%3e%3c%74%65%73%74%65%3e"; "encoded XSS probe")]
4956
async fn test_invalid_path(path: &str) -> Result<()> {
5057
let app = Router::new()
5158
.route("/{*inner}", get(|| async { StatusCode::OK }))

0 commit comments

Comments
 (0)