ssrfs-up 0.0.16 → 0.0.20
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 -70
- data/lib/ssrfs-up/version.rb +1 -1
- metadata +5 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9d88ff9fbf267800010662e3b98fedf819b7af39a57aeb94c0a300c6946d7f8
|
|
4
|
+
data.tar.gz: 2a6853be543339963f3540debab1f1a1f0f008e70c956103187d5c85c109860b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 254d9ce5ddbd089a76fbb1bf5716e1f12afea0d411a4c4066cd42472ad5fc9e220d52ee76f690cc3dc5125dd6fbd3a501d5aa8b38c1ce7fe20b3264726acb9ae
|
|
7
|
+
data.tar.gz: f1214a8b90d9f7a78247a69ab381664c8794513c759b2d6863995f2490c10b40cf26d4de27088d89bd2a29d1e54b27de7a8c1136ab130ba898470bede822a7d8
|
|
@@ -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,47 +1,42 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
require
|
|
1
|
+
require "aws-sdk-lambda"
|
|
2
|
+
require "uri"
|
|
3
|
+
require "ssrfs-up/version"
|
|
4
|
+
require "ostruct"
|
|
5
|
+
require "ssrf_filter"
|
|
6
|
+
require "cgi"
|
|
7
7
|
|
|
8
8
|
# Common files
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
12
|
-
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"
|
|
13
13
|
|
|
14
14
|
# Models
|
|
15
|
-
require
|
|
16
|
-
require
|
|
17
|
-
require
|
|
18
|
-
require
|
|
19
|
-
require
|
|
20
|
-
require
|
|
21
|
-
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"
|
|
22
22
|
|
|
23
23
|
# APIs
|
|
24
|
-
require
|
|
24
|
+
require "openapi_client/lib/openapi_client/api/default_api"
|
|
25
25
|
##
|
|
26
26
|
# This module contains the AWS lambda client and helper methods to easily
|
|
27
27
|
# make requests to it. All methods take a hostname or URI and a hash or options
|
|
28
28
|
# for the request.
|
|
29
29
|
module SSRFsUp
|
|
30
|
-
Honeycomb.configure do |config|
|
|
31
|
-
config.write_key = '0dc36d095b2c3aefb237dd04e13f580c'
|
|
32
|
-
config.dataset = 'ssrfs-upv2'
|
|
33
|
-
config.service_name = 'ssrfs-up-ruby-client'
|
|
34
|
-
end
|
|
35
|
-
|
|
36
30
|
class Configuration
|
|
37
|
-
attr_accessor :func_name, :invoke_type, :log_type, :region, :test
|
|
31
|
+
attr_accessor :func_name, :invoke_type, :log_type, :region, :test, :proxy
|
|
38
32
|
|
|
39
33
|
def initialize
|
|
40
|
-
@func_name =
|
|
41
|
-
@invoke_type =
|
|
42
|
-
@log_type =
|
|
43
|
-
@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"
|
|
44
38
|
@test = false
|
|
39
|
+
@proxy = true
|
|
45
40
|
end
|
|
46
41
|
end
|
|
47
42
|
|
|
@@ -55,64 +50,64 @@ module SSRFsUp
|
|
|
55
50
|
# https://github.com/chanzuckerberg/SSRFs-Up/blob/0e18fd30bee3f2b99ff4bc512cb967b83e8d9dcb/openapi.yaml#L97-L119
|
|
56
51
|
def do(method, host, opts = {})
|
|
57
52
|
case method.downcase
|
|
58
|
-
when
|
|
53
|
+
when "get"
|
|
59
54
|
get(host, opts)
|
|
60
|
-
when
|
|
55
|
+
when "put"
|
|
61
56
|
put(host, opts)
|
|
62
|
-
when
|
|
57
|
+
when "post"
|
|
63
58
|
post(host, opts)
|
|
64
|
-
when
|
|
59
|
+
when "patch"
|
|
65
60
|
patch(host, opts)
|
|
66
|
-
when
|
|
61
|
+
when "delete"
|
|
67
62
|
delete(host, opts)
|
|
68
63
|
end
|
|
69
64
|
end
|
|
70
65
|
|
|
71
66
|
# convenience method for making a GET request with do.
|
|
72
67
|
def get(host, opts = {})
|
|
73
|
-
opts[
|
|
68
|
+
opts[:method] = "GET"
|
|
74
69
|
invoke(host, opts)
|
|
75
70
|
end
|
|
76
71
|
|
|
77
72
|
# convenience method for making a PUT request with do.
|
|
78
73
|
def put(host, opts = {})
|
|
79
|
-
opts[
|
|
74
|
+
opts[:method] = "PUT"
|
|
80
75
|
invoke(host, opts)
|
|
81
76
|
end
|
|
82
77
|
|
|
83
78
|
# convenience method for making a POST request with do.
|
|
84
79
|
def post(host, opts = {})
|
|
85
|
-
opts[
|
|
80
|
+
opts[:method] = "POST"
|
|
86
81
|
invoke(host, opts)
|
|
87
82
|
end
|
|
88
83
|
|
|
89
84
|
# convenience method for making a patch request with do.
|
|
90
85
|
def patch(host, opts = {})
|
|
91
|
-
opts[
|
|
86
|
+
opts[:method] = "PATCH"
|
|
92
87
|
invoke(host, opts)
|
|
93
88
|
end
|
|
94
89
|
|
|
95
90
|
# convenience method for making a DELETE request with do.
|
|
96
91
|
def delete(host, opts = {})
|
|
97
|
-
opts[
|
|
92
|
+
opts[:method] = "DELETE"
|
|
98
93
|
invoke(host, opts)
|
|
99
94
|
end
|
|
100
95
|
|
|
101
96
|
# takes an ambiguous string or URI and sets the appropriate options based
|
|
102
97
|
# on if it can be parsed as URI object. If it can't, then the string is assumed
|
|
103
98
|
# to be a hostname only.
|
|
104
|
-
def parseAsUri(uri =
|
|
99
|
+
def parseAsUri(uri = "")
|
|
105
100
|
uri = uri.to_s
|
|
106
|
-
opts = {
|
|
101
|
+
opts = { :host => uri.split("/")[0].split("?")[0].split("#")[0] }
|
|
107
102
|
u = URI(uri)
|
|
108
103
|
|
|
109
104
|
# if the scheme was present, we can parse most of the options from the URI.
|
|
110
105
|
# otherwise, we can assume the URI was an actual hostname
|
|
111
106
|
unless u.scheme.nil?
|
|
112
|
-
opts[
|
|
113
|
-
opts[
|
|
114
|
-
opts[
|
|
115
|
-
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?
|
|
116
111
|
end
|
|
117
112
|
opts
|
|
118
113
|
end
|
|
@@ -138,36 +133,63 @@ module SSRFsUp
|
|
|
138
133
|
@client ||= Aws::Lambda::Client.new(region: configuration.region)
|
|
139
134
|
end
|
|
140
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? ? "" : "?" + URI.encode_www_form(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
|
+
|
|
141
167
|
# invokes the lambda with the provided arguments. It handles all lambda
|
|
142
168
|
# related errors so developers should assume the data they receive back is straight
|
|
143
169
|
# from the server they are speaking to.
|
|
144
170
|
def invoke(host = nil, opts = {})
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
opts = opts.merge({ 'headers' => { 'X-Honeycomb-Trace' => span.to_trace_header } })
|
|
149
|
-
client.invoke({
|
|
150
|
-
function_name: configuration.func_name,
|
|
151
|
-
invocation_type: configuration.invoke_type,
|
|
152
|
-
log_type: configuration.log_type,
|
|
153
|
-
payload: payload(opts)
|
|
154
|
-
})
|
|
155
|
-
end
|
|
156
|
-
else
|
|
157
|
-
client.invoke({
|
|
158
|
-
function_name: configuration.func_name,
|
|
159
|
-
invocation_type: configuration.invoke_type,
|
|
160
|
-
log_type: configuration.log_type,
|
|
161
|
-
payload: payload(opts)
|
|
162
|
-
})
|
|
163
|
-
end
|
|
164
|
-
if resp['status_code'] == 200
|
|
165
|
-
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(opts[:host], opts))
|
|
166
174
|
else
|
|
167
|
-
|
|
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(opts[:host], opts))
|
|
191
|
+
end
|
|
168
192
|
end
|
|
169
|
-
rescue StandardError => e
|
|
170
|
-
OpenStruct.new({ body: '', status_code: 500, status_text: e.to_s })
|
|
171
193
|
end
|
|
172
194
|
|
|
173
195
|
# payload builds an API client Request object with the proper defaults and
|
|
@@ -175,5 +197,5 @@ module SSRFsUp
|
|
|
175
197
|
def payload(opts = {})
|
|
176
198
|
toOpenAPIClient(opts).to_json
|
|
177
199
|
end
|
|
178
|
-
end
|
|
200
|
+
end
|
|
179
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.20
|
|
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-08-11 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
|