Skip to content

Commit e2d16db

Browse files
authored
Merge pull request #54 from hyperlight-dev/fix/block-link-local
fix: block link-local addresses by default in NetworkPolicy
2 parents a4831d7 + 188e138 commit e2d16db

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

host/src/lib.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,24 @@ fn dns_resolvers() -> &'static HashSet<IpAddr> {
365365

366366
impl NetworkPolicy {
367367
fn check(&self, addr: &std::net::SocketAddr) -> Result<()> {
368+
// Block link-local addresses (169.254.0.0/16, fe80::/10) for all
369+
// policy variants. In cloud environments the IPv4 link-local range
370+
// hosts the instance metadata service (169.254.169.254) which hands
371+
// out credentials without authentication.
372+
let is_link_local = match addr.ip() {
373+
std::net::IpAddr::V4(v4) => v4.is_link_local(),
374+
std::net::IpAddr::V6(v6) => {
375+
let seg = v6.segments();
376+
(seg[0] & 0xffc0) == 0xfe80
377+
}
378+
};
379+
if is_link_local {
380+
return Err(anyhow!(
381+
"network policy denies connection to link-local address {}",
382+
addr
383+
));
384+
}
385+
368386
match self {
369387
NetworkPolicy::AllowAll => Ok(()),
370388
NetworkPolicy::AllowList(al) => {
@@ -2724,6 +2742,37 @@ mod tests {
27242742
assert!(result.is_err());
27252743
}
27262744

2745+
#[test]
2746+
fn net_link_local_blocked() {
2747+
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
2748+
2749+
// AllowAll still blocks link-local
2750+
let policy = NetworkPolicy::AllowAll;
2751+
let meta = SocketAddr::new(Ipv4Addr::new(169, 254, 169, 254).into(), 80);
2752+
assert!(
2753+
policy.check(&meta).is_err(),
2754+
"AllowAll must block IPv4 link-local"
2755+
);
2756+
2757+
let link6 = SocketAddr::new(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1).into(), 80);
2758+
assert!(
2759+
policy.check(&link6).is_err(),
2760+
"AllowAll must block IPv6 link-local"
2761+
);
2762+
2763+
// BlockList (even empty) also blocks link-local
2764+
let bl = BlockList::from_hosts(&["192.0.2.1"]).unwrap();
2765+
let policy = NetworkPolicy::BlockList(bl);
2766+
assert!(
2767+
policy.check(&meta).is_err(),
2768+
"BlockList must block IPv4 link-local"
2769+
);
2770+
assert!(
2771+
policy.check(&link6).is_err(),
2772+
"BlockList must block IPv6 link-local"
2773+
);
2774+
}
2775+
27272776
#[test]
27282777
fn net_tools_registered_with_blocklist() {
27292778
let mut tools = ToolRegistry::new();

0 commit comments

Comments
 (0)