Skip to content

Commit 105dfe9

Browse files
authored
Enforce same origin for all resources of an RRDP server. (#953)
This PR enforces that all resources fetched for an RRDP server have the same origin as the URI provided in the CA certificate. It checks this for all URIs provided in the server’s notification file and restricts redirects to URIs with the same origin.
1 parent 4b8a3d5 commit 105dfe9

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/collector/rrdp/http.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::time::Duration;
55
use bytes::Bytes;
66
use chrono::{DateTime, Utc};
77
use log::{error, warn};
8-
use reqwest::header;
8+
use reqwest::{header, redirect};
99
use reqwest::{Certificate, Proxy, StatusCode};
1010
use reqwest::blocking::{Client, ClientBuilder, RequestBuilder, Response};
1111
use rpki::uri;
@@ -52,6 +52,9 @@ impl HttpClient {
5252
builder = builder.user_agent(&config.rrdp_user_agent);
5353
builder = builder.tcp_keepalive(config.rrdp_tcp_keepalive);
5454
builder = builder.timeout(None); // Set per request.
55+
builder = builder.redirect(
56+
redirect::Policy::custom(Self::redirect_policy)
57+
);
5558
if let Some(timeout) = config.rrdp_connect_timeout {
5659
builder = builder.connect_timeout(timeout);
5760
}
@@ -256,6 +259,29 @@ impl HttpClient {
256259
}
257260
}
258261
*/
262+
263+
/// The redirect policy.
264+
///
265+
/// We allow up to 10 redirects (reqwest’s default policy) but only if
266+
/// the origin stays the same.
267+
fn redirect_policy(attempt: redirect::Attempt) -> redirect::Action {
268+
if attempt.previous().len() > 9 {
269+
return attempt.stop();
270+
}
271+
let orig = match attempt.previous().first() {
272+
Some(url) => url,
273+
None => return attempt.follow() // Shouldn’t happen?
274+
};
275+
let new = attempt.url();
276+
let orig = (orig.scheme(), orig.host(), orig.port());
277+
let new = (new.scheme(), new.host(), new.port());
278+
if orig == new {
279+
attempt.follow()
280+
}
281+
else {
282+
attempt.stop()
283+
}
284+
}
259285
}
260286

261287

src/collector/rrdp/update.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ impl Notification {
9898
warn!("RRDP {}: {}", uri, err);
9999
Failed
100100
})?;
101+
if !content.has_matching_origins(&uri) {
102+
warn!("RRDP {}: snapshot or delta files with different origin",
103+
uri
104+
);
105+
return Err(Failed)
106+
}
101107
content.sort_deltas();
102108
Ok(Notification { uri, content, etag, last_modified })
103109
}

0 commit comments

Comments
 (0)