@@ -263,4 +263,35 @@ describe("ssrf pinning", () => {
263263 expect ( pinned . addresses ) . toEqual ( [ "127.0.0.1" ] ) ;
264264 expect ( lookup ) . toHaveBeenCalledTimes ( 1 ) ;
265265 } ) ;
266+
267+ it . each ( [
268+ [ "IPv4 unspecified" , "0.0.0.0" , 4 ] ,
269+ [ "IPv4 unspecified range" , "0.42.42.42" , 4 ] ,
270+ [ "IPv6 unspecified" , "::" , 6 ] ,
271+ [ "IPv4-mapped IPv6 unspecified" , "::ffff:0.0.0.0" , 6 ] ,
272+ [ "NAT64-embedded IPv4 unspecified" , "64:ff9b::0.0.0.0" , 6 ] ,
273+ ] as const ) (
274+ "rejects a trusted private hostname rebound to %s" ,
275+ async ( _name , address , family ) => {
276+ const lookup = vi . fn ( async ( ) => [ { address, family } ] ) as unknown as LookupFn ;
277+
278+ await expect (
279+ resolvePinnedHostnameWithPolicy ( "model.lan" , {
280+ lookupFn : lookup ,
281+ policy : { allowedHostnames : [ "model.lan" ] } ,
282+ } ) ,
283+ ) . rejects . toThrow ( SsrFBlockedError ) ;
284+ } ,
285+ ) ;
286+
287+ it ( "does not allow explicit localhost trust to resolve through an unspecified address" , async ( ) => {
288+ const lookup = vi . fn ( async ( ) => [ { address : "0.0.0.0" , family : 4 } ] ) as unknown as LookupFn ;
289+
290+ await expect (
291+ resolvePinnedHostnameWithPolicy ( "localhost" , {
292+ lookupFn : lookup ,
293+ policy : { allowedHostnames : [ "localhost" ] } ,
294+ } ) ,
295+ ) . rejects . toThrow ( SsrFBlockedError ) ;
296+ } ) ;
266297} ) ;
0 commit comments