fix(pipelock): allow route ssrf ip policy
This commit is contained in:
@@ -223,9 +223,20 @@ class TestPipelockPolicy(unittest.TestCase):
|
||||
}])
|
||||
self.assertTrue(b.egress.routes[0].Pipelock.TlsPassthrough)
|
||||
|
||||
def test_ssrf_ip_allowlist_route_policy(self):
|
||||
b = _bottle([{
|
||||
"host": "gitea.dideric.is",
|
||||
"pipelock": {"ssrf_ip_allowlist": ["100.78.141.42/32"]},
|
||||
}])
|
||||
self.assertEqual(
|
||||
("100.78.141.42/32",),
|
||||
b.egress.routes[0].Pipelock.SsrfIpAllowlist,
|
||||
)
|
||||
|
||||
def test_tls_passthrough_defaults_false(self):
|
||||
b = _bottle([{"host": "api.openai.com"}])
|
||||
self.assertFalse(b.egress.routes[0].Pipelock.TlsPassthrough)
|
||||
self.assertEqual((), b.egress.routes[0].Pipelock.SsrfIpAllowlist)
|
||||
|
||||
def test_pipelock_policy_must_be_object(self):
|
||||
with self.assertRaises(Die):
|
||||
@@ -238,6 +249,20 @@ class TestPipelockPolicy(unittest.TestCase):
|
||||
"pipelock": {"tls_passthrough": "yes"},
|
||||
}])
|
||||
|
||||
def test_ssrf_ip_allowlist_must_be_array(self):
|
||||
with self.assertRaises(Die):
|
||||
_bottle([{
|
||||
"host": "x.example",
|
||||
"pipelock": {"ssrf_ip_allowlist": "100.78.141.42/32"},
|
||||
}])
|
||||
|
||||
def test_ssrf_ip_allowlist_items_must_be_cidr_or_ip(self):
|
||||
with self.assertRaises(Die):
|
||||
_bottle([{
|
||||
"host": "x.example",
|
||||
"pipelock": {"ssrf_ip_allowlist": ["not-an-ip"]},
|
||||
}])
|
||||
|
||||
def test_unknown_pipelock_key_rejected(self):
|
||||
with self.assertRaises(Die):
|
||||
_bottle([{"host": "x.example", "pipelock": {"wat": True}}])
|
||||
|
||||
@@ -8,6 +8,7 @@ import unittest
|
||||
from bot_bottle.manifest import Manifest
|
||||
from bot_bottle.pipelock import (
|
||||
pipelock_effective_allowlist,
|
||||
pipelock_effective_ssrf_ip_allowlist,
|
||||
pipelock_effective_tls_passthrough,
|
||||
)
|
||||
|
||||
@@ -113,5 +114,29 @@ class TestTlsPassthrough(unittest.TestCase):
|
||||
self.assertEqual(["api.openai.com"], passthrough)
|
||||
|
||||
|
||||
class TestSsrfIpAllowlist(unittest.TestCase):
|
||||
def test_default_empty(self):
|
||||
allowlist = pipelock_effective_ssrf_ip_allowlist(_bottle({}))
|
||||
self.assertEqual([], allowlist)
|
||||
|
||||
def test_route_policy_adds_ssrf_ip_allowlist(self):
|
||||
allowlist = pipelock_effective_ssrf_ip_allowlist(_bottle(_routes([
|
||||
{"host": "gitea.dideric.is",
|
||||
"auth": {"scheme": "token", "token_ref": "G"},
|
||||
"pipelock": {"ssrf_ip_allowlist": ["100.78.141.42/32"]}},
|
||||
])))
|
||||
self.assertEqual(["100.78.141.42/32"], allowlist)
|
||||
|
||||
def test_route_policy_merges_with_extra(self):
|
||||
allowlist = pipelock_effective_ssrf_ip_allowlist(
|
||||
_bottle(_routes([
|
||||
{"host": "gitea.dideric.is",
|
||||
"pipelock": {"ssrf_ip_allowlist": ["100.78.141.42/32"]}},
|
||||
])),
|
||||
("172.20.0.0/16",),
|
||||
)
|
||||
self.assertEqual(["100.78.141.42/32", "172.20.0.0/16"], allowlist)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -111,6 +111,20 @@ class TestBuildConfig(unittest.TestCase):
|
||||
self.assertIn("ssrf", cfg)
|
||||
self.assertEqual({"ip_allowlist": ["172.20.0.0/16"]}, cfg["ssrf"])
|
||||
|
||||
def test_ssrf_block_emitted_from_route_policy(self):
|
||||
bottle = Manifest.from_json_obj({
|
||||
"bottles": {"dev": {"egress": {"routes": [
|
||||
{"host": "gitea.dideric.is",
|
||||
"pipelock": {"ssrf_ip_allowlist": ["100.78.141.42/32"]}},
|
||||
]}}},
|
||||
"agents": {"demo": {"skills": [], "prompt": "", "bottle": "dev"}},
|
||||
}).bottles["dev"]
|
||||
cfg = pipelock_build_config(bottle)
|
||||
self.assertEqual(
|
||||
{"ip_allowlist": ["100.78.141.42/32"]},
|
||||
cfg["ssrf"],
|
||||
)
|
||||
|
||||
def test_seed_phrase_detection_disabled_by_default(self):
|
||||
# Only the broad BIP-39 detector is disabled. The rest of
|
||||
# DLP remains enabled via the `dlp` and request-body sections.
|
||||
|
||||
Reference in New Issue
Block a user