The directory's refresher refuses internal addresses (#329)
The refresher fetches every feed a snapshot names, and anyone with a write token sends snapshots; a listed feed's redirect goes wherever its publisher likes. Nothing checked the destination, so the directory fetched loopback, its Docker network and the LAN, and what answered became a listing's title and description on its public pages. Its client now has ipx-feed's guard (#320) with nothing allowed: no feed the directory lists is on this network. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -144,6 +144,9 @@ impl Directory {
|
||||
.read_timeout(ipx_feed::FEED_SILENCE)
|
||||
.redirect(reqwest::redirect::Policy::none())
|
||||
.user_agent(concat!("ipx-directory/", env!("CARGO_PKG_VERSION")))
|
||||
// The feeds are named by whoever holds a write token, and redirect where their
|
||||
// publishers like; none is on this network, so nothing here is fetched (#329).
|
||||
.connector_layer(ipx_feed::guard::Guard::new(Default::default()))
|
||||
.build()?;
|
||||
Ok(Arc::new(Self {
|
||||
store,
|
||||
@@ -568,6 +571,16 @@ mod tests {
|
||||
assert_eq!(got["accepted"], 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn the_refresher_fetches_nothing_on_this_network() {
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
tokio::spawn(async move { while listener.accept().await.is_ok() {} });
|
||||
let (_, dir) = app().await;
|
||||
let err = dir.client.get(format!("http://{addr}/feed.xml")).send().await.unwrap_err();
|
||||
assert!(format!("{err:?}").contains("internal address"), "{err:?}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn the_public_pages_read_the_list_once_a_minute() {
|
||||
let (_, dir) = app().await;
|
||||
|
||||
Reference in New Issue
Block a user