ssrfs-up 0.0.14 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79a89488772f10f51bacee766112aa17c601361a98ec04ef3fd881efbf416ba3
4
- data.tar.gz: 0c35e3c62444e4b9331146c77ef6ce282ceeafcf9145e413b7dbcdf8365ae199
3
+ metadata.gz: ac607c50569f257378191c69e03d27d136d4644d0cbe64f7f4ac194f91a90a65
4
+ data.tar.gz: b88301259811836561ea14d322b50eb4e2111fb187eaa4a97e53449f76ff33fe
5
5
  SHA512:
6
- metadata.gz: '081d9147f84e5120a963d1f022347d5d6ab4c074420aad40e05e2be5725ff488a1df364fbb10c6e1c6374861cd96543edbcc0ce4993b88bb10b6d0bbe252fbf7'
7
- data.tar.gz: d663b3859ca75bf3a762ca78ce85f3c286d17aa24c99cb6aa410d969996261addb3f411dbda78e22e25469c7f09eca9879b928fd71c7de3265598983e21380f6
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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
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
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
@@ -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.1.0
9
+ OpenAPI Generator version: 5.2.0
10
10
 
11
11
  =end
12
12
 
data/lib/ssrfs-up.rb CHANGED
@@ -1,52 +1,42 @@
1
- require 'aws-sdk-lambda'
2
- require 'uri'
3
- require 'ssrfs-up/version'
4
- require 'ostruct'
5
- require 'honeycomb-beeline'
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 'openapi_client/lib/openapi_client/api_client'
9
- require 'openapi_client/lib/openapi_client/api_error'
10
- require 'openapi_client/lib/openapi_client/version'
11
- require 'openapi_client/lib/openapi_client/configuration'
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 'openapi_client/lib/openapi_client/models/content_type'
15
- require 'openapi_client/lib/openapi_client/models/method'
16
- require 'openapi_client/lib/openapi_client/models/redirect'
17
- require 'openapi_client/lib/openapi_client/models/request'
18
- require 'openapi_client/lib/openapi_client/models/response'
19
- require 'openapi_client/lib/openapi_client/models/response_error'
20
- require 'openapi_client/lib/openapi_client/models/response_success'
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 'openapi_client/lib/openapi_client/api/default_api'
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 = 'arn:aws:lambda:us-west-2:871040364337:function:sec-czi-sec-ssrfs-up'
46
- @invoke_type = 'RequestResponse'
47
- @log_type = 'None'
48
- @region = 'us-west-2'
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 'get'
53
+ when "get"
64
54
  get(host, opts)
65
- when 'put'
55
+ when "put"
66
56
  put(host, opts)
67
- when 'post'
57
+ when "post"
68
58
  post(host, opts)
69
- when 'patch'
59
+ when "patch"
70
60
  patch(host, opts)
71
- when 'delete'
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['method'] = 'GET'
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['method'] = 'PUT'
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['method'] = 'POST'
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['method'] = 'PATCH'
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['method'] = 'DELETE'
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 = { 'host' => uri.split('/')[0].split('?')[0].split('#')[0] }
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['secure'] = !(u.scheme == 'http')
118
- opts['host'] = u.host
119
- opts['path'] = u.path unless u.path == ''
120
- opts['params'] = CGI.parse(u.query) unless u.query.nil?
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
- resp = if !configuration.test
151
- Honeycomb.start_span(name: 'invoke') do |span|
152
- span.add_field('host', host)
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
- OpenStruct.new({ body: '', status_code: resp[status_code], status_text: '500 Error with proxy' })
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
@@ -1,3 +1,3 @@
1
1
  module SSRFsUp
2
- VERSION = '0.0.14'.freeze
2
+ VERSION = "0.0.18".freeze
3
3
  end
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.14
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-04-02 00:00:00.000000000 Z
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: honeycomb-beeline
54
+ name: ssrf_filter
75
55
  requirement: !ruby/object:Gem::Requirement
76
56
  requirements:
77
57
  - - "~>"
78
58
  - !ruby/object:Gem::Version
79
- version: '2.4'
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: '2.4'
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.4
172
+ rubygems_version: 3.1.6
199
173
  signing_key:
200
174
  specification_version: 4
201
175
  summary: Proxy all requests to avoid SSRF.