Skip to content

Commit db9f7f4

Browse files
committed
fix: return a 422 if the URL path contains a new line or tab
1 parent 00a31ab commit db9f7f4

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require 'uri'
24

35
# This class is for https://github.com/pact-foundation/pact_broker/issues/101
@@ -6,31 +8,46 @@
68
module Rack
79
module PactBroker
810
class InvalidUriProtection
9-
1011
def initialize app
1112
@app = app
1213
end
1314

1415
def call env
15-
if valid_uri? env
16-
@app.call(env)
16+
if (uri = valid_uri?(env))
17+
if (error_message = validate(uri))
18+
[422, {'Content-Type' => 'text/plain'}, [error_message]]
19+
else
20+
app.call(env)
21+
end
1722
else
1823
[404, {}, []]
1924
end
2025
end
2126

27+
private
28+
29+
attr_reader :app
30+
2231
def valid_uri? env
2332
begin
2433
parse(::Rack::Request.new(env).url)
25-
true
2634
rescue URI::InvalidURIError, ArgumentError
27-
false
35+
nil
2836
end
2937
end
3038

3139
def parse uri
3240
URI.parse(uri)
3341
end
42+
43+
def validate(uri)
44+
decoded_path = URI.decode(uri.path)
45+
if decoded_path.include?("\n")
46+
'URL path cannot contain a new line character.'
47+
elsif decoded_path.include?("\t")
48+
'URL path cannot contain a tab character.'
49+
end
50+
end
3451
end
3552
end
3653
end

spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb

+21-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
module Rack
44
module PactBroker
55
describe InvalidUriProtection do
6+
let(:target_app) { ->(env){ [200, {}, []] } }
7+
let(:app) { InvalidUriProtection.new(target_app) }
8+
let(:path) { URI.encode("/foo") }
69

7-
let(:app) { InvalidUriProtection.new(->(env){ [200,{},[]] }) }
8-
9-
subject { get "/badpath"; last_response }
10+
subject { get(path) }
1011

1112
context "with a URI that the Ruby default URI library cannot parse" do
13+
let(:path) { "/badpath" }
1214

1315
before do
1416
# Can't use or stub URI.parse because rack test uses it to execute the actual test
@@ -24,6 +26,22 @@ module PactBroker
2426
it "passes the request to the underlying app" do
2527
expect(subject.status).to eq 200
2628
end
29+
30+
context "when the URI contains a new line because someone forgot to strip the result of `git rev-parse HEAD`, and I have totally never done this before myself" do
31+
let(:path) { URI.encode("/foo\n/bar") }
32+
33+
it "returns a 422" do
34+
expect(subject.status).to eq 422
35+
end
36+
end
37+
38+
context "when the URI contains a tab because sooner or later someone is eventually going to do this" do
39+
let(:path) { URI.encode("/foo\t/bar") }
40+
41+
it "returns a 422" do
42+
expect(subject.status).to eq 422
43+
end
44+
end
2745
end
2846
end
2947
end

0 commit comments

Comments
 (0)