@@ -77,6 +77,32 @@ module GenericTests
7777      assert_includes  context . payloads ,  stub_payload ( :body ,  "7" ,  "y.w.j" ) 
7878    end 
7979
80+     test  "relative path arrays in complex parameter structures are joined for File.join"  do 
81+       context  =  build_context_for ( "/path?path1[]=..&path1[]=..&path1[]=..&path1[]=etc&path1[]=passwd" ,  { 
82+         method : "POST" , 
83+         params : { path2 : [ ".." ,  ".." ,  ".." ,  "etc" ,  "passwd" ] } 
84+       } ) 
85+ 
86+       assert_includes  context . payloads ,  stub_payload ( :query ,  "../../../etc/passwd" ,  "path1.__File.join__" ) 
87+ 
88+       assert_includes  context . payloads ,  stub_payload ( :body ,  "../../../etc/passwd" ,  "path2.__File.join__" ) 
89+     end 
90+ 
91+     test  "absolute path arrays in complex parameter structures are joined for File.join"  do 
92+       context  =  build_context_for ( "/path?path1[]=&path1[]=etc&path1[]=passwd&path2[]=/&path2[]=etc&path2[]=passwd&&path3[]=/etc&path3[]=passwd" ,  { 
93+         method : "POST" , 
94+         params : { path4 : [ "/" ,  "etc" ,  "passwd" ] ,  path5 : [ "" ,  "etc" ,  "passwd" ] ,  path6 : [ "/etc" ,  "passwd" ] } 
95+       } ) 
96+ 
97+       assert_includes  context . payloads ,  stub_payload ( :query ,  "/etc/passwd" ,  "path1.__File.join__" ) 
98+       assert_includes  context . payloads ,  stub_payload ( :query ,  "/etc/passwd" ,  "path2.__File.join__" ) 
99+       assert_includes  context . payloads ,  stub_payload ( :query ,  "/etc/passwd" ,  "path3.__File.join__" ) 
100+ 
101+       assert_includes  context . payloads ,  stub_payload ( :body ,  "/etc/passwd" ,  "path4.__File.join__" ) 
102+       assert_includes  context . payloads ,  stub_payload ( :body ,  "/etc/passwd" ,  "path5.__File.join__" ) 
103+       assert_includes  context . payloads ,  stub_payload ( :body ,  "/etc/passwd" ,  "path6.__File.join__" ) 
104+     end 
105+ 
80106    test  "#protection_disabled? allows requests from allowed IPs"  do 
81107      settings  =  Aikido ::Zen . runtime_settings 
82108      settings . update_from_json ( { 
@@ -103,6 +129,7 @@ class RackRequestTest < ActiveSupport::TestCase
103129
104130    setup  do 
105131      Aikido ::Zen . config . request_builder  =  Aikido ::Zen ::Context ::RACK_REQUEST_BUILDER 
132+       Aikido ::Zen . config . harden  =  false 
106133    end 
107134
108135    def  build_context_for ( path ,  env  =  { } ) 
@@ -196,6 +223,7 @@ class RailsRequestTest < ActiveSupport::TestCase
196223
197224    setup  do 
198225      Aikido ::Zen . config . request_builder  =  Aikido ::Zen ::Context ::RAILS_REQUEST_BUILDER 
226+       Aikido ::Zen . config . harden  =  false 
199227    end 
200228
201229    def  env_for ( path ,  env  =  { } ) 
@@ -238,6 +266,28 @@ def stub_payload(source, value, path)
238266      assert_includes  context . payloads ,  stub_payload ( :body ,  3 ,  "array.2" ) 
239267    end 
240268
269+     test  "relative path arrays in body payloads read from JSON-encoded bodies are joined for File.join"  do 
270+       context  =  build_context_for ( "/example" ,  { 
271+         :method  =>  "POST" , 
272+         :input  =>  %({"path":["..", "..", "..", "etc", "passwd"]}) , 
273+         "CONTENT_TYPE"  =>  "application/json" 
274+       } ) 
275+ 
276+       assert_includes  context . payloads ,  stub_payload ( :body ,  "../../../etc/passwd" ,  "path.__File.join__" ) 
277+     end 
278+ 
279+     test  "absolute path arrays in body payloads read from JSON-encoded bodies are joined for File.join"  do 
280+       context  =  build_context_for ( "/example" ,  { 
281+         :method  =>  "POST" , 
282+         :input  =>  %({"path1": ["/", "etc", "passwd"], "path2": ["", "etc", "passwd"], "path3": ["/etc", "passwd"]}) , 
283+         "CONTENT_TYPE"  =>  "application/json" 
284+       } ) 
285+ 
286+       assert_includes  context . payloads ,  stub_payload ( :body ,  "/etc/passwd" ,  "path1.__File.join__" ) 
287+       assert_includes  context . payloads ,  stub_payload ( :body ,  "/etc/passwd" ,  "path2.__File.join__" ) 
288+       assert_includes  context . payloads ,  stub_payload ( :body ,  "/etc/passwd" ,  "path3.__File.join__" ) 
289+     end 
290+ 
241291    test  "route payloads are read from the data extracted by the router"  do 
242292      router  =  MockedRailsRouter . build  do 
243293        match  "/example/:resource(/:id)(.:format)" , 
0 commit comments