@@ -54,10 +54,6 @@ describeMatrix("security: path encoding bypass", (ctx, { it, expect }) => {
5454 expect ( res . status ) . not . toBe ( 200 ) ;
5555 } ) ;
5656
57- it ( "should NOT bypass auth via double encoding" , async ( ) => {
58- const res = await ctx . fetch ( "/api/%2561dmin/users" ) ;
59- expect ( res . status ) . not . toBe ( 200 ) ;
60- } ) ;
6157} ) ;
6258
6359describeMatrix ( "security: path encoding bypass with wildcard routes" , ( ctx , { it, expect } ) => {
@@ -81,10 +77,19 @@ describeMatrix("security: path encoding bypass with wildcard routes", (ctx, { it
8177 expect ( res . status ) . toBe ( 403 ) ;
8278 } ) ;
8379
84- // Known issue: wildcard routes match encoded paths that bypass middleware pathname checks
85- // The middleware sees "%61dmin" (raw) while the wildcard catches everything under /api/**
8680 it ( "should NOT bypass auth with wildcard via /api/%61dmin/users" , async ( ) => {
8781 const res = await ctx . fetch ( "/api/%61dmin/users" ) ;
8882 expect ( res . status ) . not . toBe ( 200 ) ;
8983 } ) ;
84+
85+ // Double-encoded %2561 decodes to %61 (one layer), which is a distinct path from "admin".
86+ // The wildcard /api/** correctly matches this as a valid sub-path, and the middleware
87+ // for /api/admin/** correctly does NOT match because %61dmin !== admin.
88+ // This is expected behavior — recursive decoding would create security mismatches
89+ // with upstream proxies/WAFs that treat these paths as distinct.
90+ it ( "double-encoded /api/%2561dmin/users is a distinct path (not an admin bypass)" , async ( ) => {
91+ const res = await ctx . fetch ( "/api/%2561dmin/users" ) ;
92+ expect ( res . status ) . toBe ( 200 ) ;
93+ expect ( await res . json ( ) ) . toEqual ( { path : "/api/%61dmin/users" } ) ;
94+ } ) ;
9095} ) ;
0 commit comments