v0.29.0
This commit is contained in:
1 parent
65e082b9d1
commit
76cb4acef0
72 files changed
+6134
-4709
No files matched your search
@@ -367,6 +367,50 @@ fn validate_route_rewrite(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_location_redirect(redirect: Option<&crate::vhost::LocationRedirect>) -> Result<Option<crate::config::CompiledLocationRedirect>> {
|
||||
let Some(redirect) = redirect else {
|
||||
return Ok(None);
|
||||
};
|
||||
ensure!(
|
||||
matches!(redirect.status, 301 | 302 | 303 | 307 | 308),
|
||||
"location redirect status must be 301, 302, 303, 307 or 308"
|
||||
);
|
||||
ensure!(
|
||||
!redirect.target.is_empty()
|
||||
&& redirect.target.len() <= 2048
|
||||
&& !redirect.target.chars().any(char::is_control),
|
||||
"invalid location redirect target"
|
||||
);
|
||||
// Replace capture references with a harmless segment so URL structure can
|
||||
// be validated before requests reach the data plane.
|
||||
let authority_end = redirect.target.find("://").and_then(|start| {
|
||||
let rest = &redirect.target[start + 3..];
|
||||
rest.char_indices().find(|(_, ch)| matches!(ch, '/' | '?' | '#')).map(|(offset, _)| start + 3 + offset).or(Some(redirect.target.len()))
|
||||
}).ok_or_else(|| anyhow::anyhow!("location redirect target must be an absolute URL"))?;
|
||||
ensure!(!redirect.target[..authority_end].contains('$'), "location redirect captures are not allowed in the URL authority");
|
||||
let sample = regex::Regex::new(r"\$\{?[A-Za-z0-9_]+\}?")
|
||||
.expect("static capture regex")
|
||||
.replace_all(&redirect.target, "capture");
|
||||
let parsed = url::Url::parse(&sample).context("location redirect target must be an absolute URL")?;
|
||||
ensure!(matches!(parsed.scheme(), "http" | "https") && parsed.host_str().is_some(), "location redirect target must use http/https and include a host");
|
||||
ensure!(parsed.username().is_empty() && parsed.password().is_none(), "location redirect target cannot contain credentials");
|
||||
let rewrite_regex = match redirect.rewrite_pattern.as_deref() {
|
||||
None | Some("") => None,
|
||||
Some(pattern) => {
|
||||
ensure!(pattern.len() <= 1024 && !pattern.chars().any(char::is_control), "invalid location redirect rewrite regex");
|
||||
let mut builder = regex::RegexBuilder::new(pattern);
|
||||
builder.size_limit(2 * 1024 * 1024).dfa_size_limit(2 * 1024 * 1024);
|
||||
Some(builder.build().context("invalid location redirect rewrite regex")?)
|
||||
}
|
||||
};
|
||||
Ok(Some(crate::config::CompiledLocationRedirect {
|
||||
status: redirect.status,
|
||||
target: redirect.target.clone(),
|
||||
rewrite_regex,
|
||||
preserve_query: redirect.preserve_query,
|
||||
}))
|
||||
}
|
||||
|
||||
fn validate_location_response(response: Option<&crate::vhost::LocationResponse>) -> Result<()> {
|
||||
let Some(response) = response else {
|
||||
return Ok(());
|
||||
|
||||
Reference in new issue
Block a user