ssrfs-up 0.0.14 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openapi_client/lib/openapi_client.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/api/default_api.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/api_client.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/api_error.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/configuration.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/models/content_type.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/models/method.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/models/redirect.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/models/request.rb +2 -2
- data/lib/openapi_client/lib/openapi_client/models/response.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/models/response_error.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/models/response_success.rb +1 -1
- data/lib/openapi_client/lib/openapi_client/version.rb +1 -1
- data/lib/ssrfs-up.rb +92 -76
- data/lib/ssrfs-up/version.rb +1 -1
- metadata +6 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac607c50569f257378191c69e03d27d136d4644d0cbe64f7f4ac194f91a90a65
|
4
|
+
data.tar.gz: b88301259811836561ea14d322b50eb4e2111fb187eaa4a97e53449f76ff33fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70692d0efeef0ba0ff33f2206024ac3c4daed6c4bf6862ac2ec77d0a42d84719022f8fa669c63c2350595d8b343757dd6278a6a93c1e604377ee9799e2298f5c
|
7
|
+
data.tar.gz: 41bdf36de6586091b5a08f1ee7ec4a49078a759bbdb5a2c1eeb353fbd88c31a2b885a878b8b1a09e2f9efccca7381f38fe176e0312fe5b5f5c09e32aaf4fa753
|
@@ -6,7 +6,7 @@
|
|
6
6
|
The version of the OpenAPI document: 1.0.0-oas3-oas3-oas3
|
7
7
|
Contact: jheath@chanzuckerberg.com
|
8
8
|
Generated by: https://openapi-generator.tech
|
9
|
-
OpenAPI Generator version: 5.
|
9
|
+
OpenAPI Generator version: 5.2.0
|
10
10
|
|
11
11
|
=end
|
12
12
|
|
@@ -160,7 +160,7 @@ module OpenapiClient
|
|
160
160
|
if attributes.key?(:'path')
|
161
161
|
self.path = attributes[:'path']
|
162
162
|
else
|
163
|
-
self.path = '
|
163
|
+
self.path = ''
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
data/lib/ssrfs-up.rb
CHANGED
@@ -1,52 +1,42 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "aws-sdk-lambda"
|
2
|
+
require "uri"
|
3
|
+
require "ssrfs-up/version"
|
4
|
+
require "ostruct"
|
5
|
+
require "ssrf_filter"
|
6
|
+
require "cgi"
|
6
7
|
|
7
8
|
# Common files
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
9
|
+
require "openapi_client/lib/openapi_client/api_client"
|
10
|
+
require "openapi_client/lib/openapi_client/api_error"
|
11
|
+
require "openapi_client/lib/openapi_client/version"
|
12
|
+
require "openapi_client/lib/openapi_client/configuration"
|
12
13
|
|
13
14
|
# Models
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
15
|
+
require "openapi_client/lib/openapi_client/models/content_type"
|
16
|
+
require "openapi_client/lib/openapi_client/models/method"
|
17
|
+
require "openapi_client/lib/openapi_client/models/redirect"
|
18
|
+
require "openapi_client/lib/openapi_client/models/request"
|
19
|
+
require "openapi_client/lib/openapi_client/models/response"
|
20
|
+
require "openapi_client/lib/openapi_client/models/response_error"
|
21
|
+
require "openapi_client/lib/openapi_client/models/response_success"
|
21
22
|
|
22
23
|
# APIs
|
23
|
-
require
|
24
|
+
require "openapi_client/lib/openapi_client/api/default_api"
|
24
25
|
##
|
25
26
|
# This module contains the AWS lambda client and helper methods to easily
|
26
27
|
# make requests to it. All methods take a hostname or URI and a hash or options
|
27
28
|
# for the request.
|
28
29
|
module SSRFsUp
|
29
|
-
Honeycomb.configure do |config|
|
30
|
-
config.write_key = '0dc36d095b2c3aefb237dd04e13f580c'
|
31
|
-
config.dataset = 'ssrfs-up'
|
32
|
-
config.service_name = 'ssrfs-up-ruby-client'
|
33
|
-
config.presend_hook do |fields|
|
34
|
-
fields['aws.session_token'] = '[REDACTED]' if fields.has_key? 'aws.session_token'
|
35
|
-
fields['aws.access_key_id'] = '[REDACTED]' if fields.has_key? 'aws.access_key_id'
|
36
|
-
fields['aws.params.function_name'] = '[REDACTED]' if fields.has_key? 'aws.params.function_name'
|
37
|
-
fields['aws.params.payload'] = '[REDACTED]' if fields.has_key? 'aws.params.payload'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
30
|
class Configuration
|
42
|
-
attr_accessor :func_name, :invoke_type, :log_type, :region, :test
|
31
|
+
attr_accessor :func_name, :invoke_type, :log_type, :region, :test, :proxy
|
43
32
|
|
44
33
|
def initialize
|
45
|
-
@func_name =
|
46
|
-
@invoke_type =
|
47
|
-
@log_type =
|
48
|
-
@region =
|
34
|
+
@func_name = "arn:aws:lambda:us-west-2:871040364337:function:sec-czi-sec-ssrfs-up:sec-czi-sec-ssrfs-up"
|
35
|
+
@invoke_type = "RequestResponse"
|
36
|
+
@log_type = "None"
|
37
|
+
@region = "us-west-2"
|
49
38
|
@test = false
|
39
|
+
@proxy = true
|
50
40
|
end
|
51
41
|
end
|
52
42
|
|
@@ -60,64 +50,64 @@ module SSRFsUp
|
|
60
50
|
# https://github.com/chanzuckerberg/SSRFs-Up/blob/0e18fd30bee3f2b99ff4bc512cb967b83e8d9dcb/openapi.yaml#L97-L119
|
61
51
|
def do(method, host, opts = {})
|
62
52
|
case method.downcase
|
63
|
-
when
|
53
|
+
when "get"
|
64
54
|
get(host, opts)
|
65
|
-
when
|
55
|
+
when "put"
|
66
56
|
put(host, opts)
|
67
|
-
when
|
57
|
+
when "post"
|
68
58
|
post(host, opts)
|
69
|
-
when
|
59
|
+
when "patch"
|
70
60
|
patch(host, opts)
|
71
|
-
when
|
61
|
+
when "delete"
|
72
62
|
delete(host, opts)
|
73
63
|
end
|
74
64
|
end
|
75
65
|
|
76
66
|
# convenience method for making a GET request with do.
|
77
67
|
def get(host, opts = {})
|
78
|
-
opts[
|
68
|
+
opts[:method] = "GET"
|
79
69
|
invoke(host, opts)
|
80
70
|
end
|
81
71
|
|
82
72
|
# convenience method for making a PUT request with do.
|
83
73
|
def put(host, opts = {})
|
84
|
-
opts[
|
74
|
+
opts[:method] = "PUT"
|
85
75
|
invoke(host, opts)
|
86
76
|
end
|
87
77
|
|
88
78
|
# convenience method for making a POST request with do.
|
89
79
|
def post(host, opts = {})
|
90
|
-
opts[
|
80
|
+
opts[:method] = "POST"
|
91
81
|
invoke(host, opts)
|
92
82
|
end
|
93
83
|
|
94
84
|
# convenience method for making a patch request with do.
|
95
85
|
def patch(host, opts = {})
|
96
|
-
opts[
|
86
|
+
opts[:method] = "PATCH"
|
97
87
|
invoke(host, opts)
|
98
88
|
end
|
99
89
|
|
100
90
|
# convenience method for making a DELETE request with do.
|
101
91
|
def delete(host, opts = {})
|
102
|
-
opts[
|
92
|
+
opts[:method] = "DELETE"
|
103
93
|
invoke(host, opts)
|
104
94
|
end
|
105
95
|
|
106
96
|
# takes an ambiguous string or URI and sets the appropriate options based
|
107
97
|
# on if it can be parsed as URI object. If it can't, then the string is assumed
|
108
98
|
# to be a hostname only.
|
109
|
-
def parseAsUri(uri =
|
99
|
+
def parseAsUri(uri = "")
|
110
100
|
uri = uri.to_s
|
111
|
-
opts = {
|
101
|
+
opts = { :host => uri.split("/")[0].split("?")[0].split("#")[0] }
|
112
102
|
u = URI(uri)
|
113
103
|
|
114
104
|
# if the scheme was present, we can parse most of the options from the URI.
|
115
105
|
# otherwise, we can assume the URI was an actual hostname
|
116
106
|
unless u.scheme.nil?
|
117
|
-
opts[
|
118
|
-
opts[
|
119
|
-
opts[
|
120
|
-
opts[
|
107
|
+
opts[:secure] = !(u.scheme == "http")
|
108
|
+
opts[:host] = u.host
|
109
|
+
opts[:path] = u.path unless u.path == ""
|
110
|
+
opts[:params] = CGI.parse(u.query) unless u.query.nil?
|
121
111
|
end
|
122
112
|
opts
|
123
113
|
end
|
@@ -143,37 +133,63 @@ module SSRFsUp
|
|
143
133
|
@client ||= Aws::Lambda::Client.new(region: configuration.region)
|
144
134
|
end
|
145
135
|
|
136
|
+
def fast_check(host, opts)
|
137
|
+
scheme = opts[:secure] ? "https://" : "http://"
|
138
|
+
path = opts[:path].nil? ? "" : opts[:path]
|
139
|
+
params = opts[:params].nil? ? "" : "?" + opts[:params]
|
140
|
+
url = scheme + host + path + params
|
141
|
+
|
142
|
+
filter_opts = { :max_redirects => opts[:redirect].nil? ? 3 : opts[:redirect] }
|
143
|
+
filter_opts[:params] = opts[:params] unless opts[:params].nil?
|
144
|
+
filter_opts[:body] = opts[:body] unless opts[:body].nil?
|
145
|
+
filter_opts[:headers] = opts[:headers] unless opts[:headers].nil?
|
146
|
+
|
147
|
+
begin
|
148
|
+
case opts[:method].downcase
|
149
|
+
when "get"
|
150
|
+
resp = SsrfFilter.get(url, filter_opts)
|
151
|
+
when "put"
|
152
|
+
resp = SsrfFilter.put(url, filter_opts)
|
153
|
+
when "post"
|
154
|
+
resp = SsrfFilter.post(url, filter_opts)
|
155
|
+
when "delete"
|
156
|
+
resp = SsrfFilter.delete(url, filter_opts)
|
157
|
+
when "patch"
|
158
|
+
return { status_code: 404, status_text: "Unsupported method", body: "Cannot use patch with fast path." }
|
159
|
+
end
|
160
|
+
|
161
|
+
{ status_code: resp.code.to_i, status_text: resp.message, body: resp.body }
|
162
|
+
rescue SsrfFilter::PrivateIPAddress => exception
|
163
|
+
{ status_code: 404, status_text: "Invalid destination", body: exception.to_s }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
146
167
|
# invokes the lambda with the provided arguments. It handles all lambda
|
147
168
|
# related errors so developers should assume the data they receive back is straight
|
148
169
|
# from the server they are speaking to.
|
149
170
|
def invoke(host = nil, opts = {})
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
opts = opts.merge(parseAsUri(host))
|
154
|
-
opts = opts.merge({ 'headers' => { 'X-Honeycomb-Trace' => span.to_trace_header } })
|
155
|
-
client.invoke({
|
156
|
-
function_name: configuration.func_name,
|
157
|
-
invocation_type: configuration.invoke_type,
|
158
|
-
log_type: configuration.log_type,
|
159
|
-
payload: payload(opts)
|
160
|
-
})
|
161
|
-
end
|
162
|
-
else
|
163
|
-
client.invoke({
|
164
|
-
function_name: configuration.func_name,
|
165
|
-
invocation_type: configuration.invoke_type,
|
166
|
-
log_type: configuration.log_type,
|
167
|
-
payload: payload(opts)
|
168
|
-
})
|
169
|
-
end
|
170
|
-
if resp['status_code'] == 200
|
171
|
-
OpenStruct.new(JSON.parse(resp&.payload&.string))
|
171
|
+
opts = opts.merge(parseAsUri(host))
|
172
|
+
if (!opts[:proxy].nil? && !opts[:proxy]) || !configuration.proxy
|
173
|
+
OpenStruct.new(fast_check(host, opts))
|
172
174
|
else
|
173
|
-
|
175
|
+
begin
|
176
|
+
resp = client.invoke({
|
177
|
+
function_name: configuration.func_name,
|
178
|
+
invocation_type: configuration.invoke_type,
|
179
|
+
log_type: configuration.log_type,
|
180
|
+
payload: payload(opts),
|
181
|
+
})
|
182
|
+
|
183
|
+
if resp["status_code"] == 200
|
184
|
+
OpenStruct.new(JSON.parse(resp&.payload&.string))
|
185
|
+
else
|
186
|
+
OpenStruct.new({ body: "", status_code: resp[status_code], status_text: "500 Error with proxy" })
|
187
|
+
end
|
188
|
+
rescue StandardError => e
|
189
|
+
# fall back to local check if the lambda wasn't reachable.
|
190
|
+
OpenStruct.new(fast_check(host, opts))
|
191
|
+
end
|
174
192
|
end
|
175
|
-
rescue StandardError => e
|
176
|
-
OpenStruct.new({ body: '', status_code: 500, status_text: e.to_s })
|
177
193
|
end
|
178
194
|
|
179
195
|
# payload builds an API client Request object with the proper defaults and
|
@@ -181,5 +197,5 @@ module SSRFsUp
|
|
181
197
|
def payload(opts = {})
|
182
198
|
toOpenAPIClient(opts).to_json
|
183
199
|
end
|
184
|
-
end
|
200
|
+
end
|
185
201
|
end
|
data/lib/ssrfs-up/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ssrfs-up
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jake Heath
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-lambda
|
@@ -30,26 +30,6 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '1'
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: libhoney
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - "~>"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '1.18'
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: 1.18.0
|
43
|
-
type: :runtime
|
44
|
-
prerelease: false
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - "~>"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '1.18'
|
50
|
-
- - ">="
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: 1.18.0
|
53
33
|
- !ruby/object:Gem::Dependency
|
54
34
|
name: typhoeus
|
55
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,25 +51,19 @@ dependencies:
|
|
71
51
|
- !ruby/object:Gem::Version
|
72
52
|
version: 1.0.1
|
73
53
|
- !ruby/object:Gem::Dependency
|
74
|
-
name:
|
54
|
+
name: ssrf_filter
|
75
55
|
requirement: !ruby/object:Gem::Requirement
|
76
56
|
requirements:
|
77
57
|
- - "~>"
|
78
58
|
- !ruby/object:Gem::Version
|
79
|
-
version: '
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 2.4.0
|
59
|
+
version: '1.0'
|
83
60
|
type: :runtime
|
84
61
|
prerelease: false
|
85
62
|
version_requirements: !ruby/object:Gem::Requirement
|
86
63
|
requirements:
|
87
64
|
- - "~>"
|
88
65
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
90
|
-
- - ">="
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: 2.4.0
|
66
|
+
version: '1.0'
|
93
67
|
- !ruby/object:Gem::Dependency
|
94
68
|
name: bundler
|
95
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -195,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
169
|
- !ruby/object:Gem::Version
|
196
170
|
version: '0'
|
197
171
|
requirements: []
|
198
|
-
rubygems_version: 3.1.
|
172
|
+
rubygems_version: 3.1.6
|
199
173
|
signing_key:
|
200
174
|
specification_version: 4
|
201
175
|
summary: Proxy all requests to avoid SSRF.
|