summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWiktor Kwapisiewicz <wiktor@metacode.biz>2021-03-25 10:13:28 +0100
committerWiktor Kwapisiewicz <wiktor@metacode.biz>2021-03-31 11:40:01 +0200
commitccfa5f6ffc170494a0f3ea5a3906c4b61c2df263 (patch)
tree87772a13cf6c64f8b3ef1863eec2a2542b731996
parent6e943987de1beb3cd8c5406fec27266c313c90ee (diff)
net: Protect against redirection loops in WKD requests.
- Use explicit depth to indicate how many redirects have been executed and break the loop if the number is bigger than 10. - Using `reqwest` was considered but rejected due to Tokio version incompatibility (`reqwest` insists on using Tokio 1 while Sequoia uses 0.2 in many places).
-rw-r--r--net/src/wkd.rs17
1 files changed, 12 insertions, 5 deletions
diff --git a/net/src/wkd.rs b/net/src/wkd.rs
index d061c7ef..cc14613c 100644
--- a/net/src/wkd.rs
+++ b/net/src/wkd.rs
@@ -237,13 +237,18 @@ fn parse_body<S: AsRef<str>>(body: &[u8], email_address: S)
fn get_following_redirects<'a, T>(
client: &'a hyper::client::Client<T>,
url: Uri,
-) -> BoxFuture<'a, hyper::Result<Response<Body>>>
+ depth: i32,
+) -> BoxFuture<'a, Result<Response<Body>>>
where
T: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
{
async move {
let response = client.get(url).await;
+ if depth < 0 {
+ return Err(anyhow::anyhow!("Too many redirects"));
+ }
+
if let Ok(ref resp) = response {
if resp.status().is_redirection() {
let url = resp.headers().get("Location")
@@ -251,12 +256,12 @@ where
.flatten()
.map(|value| value.parse::<Uri>());
if let Some(Ok(url)) = url {
- return get_following_redirects(&client, url).await;
+ return get_following_redirects(&client, url, depth - 1).await;
}
}
}
- response
+ response.map_err(|err| anyhow::anyhow!(err))
}
.boxed()
}
@@ -312,10 +317,12 @@ pub async fn get<S: AsRef<str>>(email_address: S) -> Result<Vec<Cert>> {
let advanced_uri = wkd_url.to_uri(Variant::Advanced)?;
let direct_uri = wkd_url.to_uri(Variant::Direct)?;
+ const REDIRECT_LIMIT: i32 = 10;
+
// First, try the Advanced Method.
- let res = get_following_redirects(&client, advanced_uri)
+ let res = get_following_redirects(&client, advanced_uri, REDIRECT_LIMIT)
// Fall back to the Direct Method.
- .or_else(|_| get_following_redirects(&client, direct_uri))
+ .or_else(|_| get_following_redirects(&client, direct_uri, REDIRECT_LIMIT))
.await?;
let body = hyper::body::to_bytes(res.into_body()).await?;