ssrfs-up 0.0.17 → 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: ed38c43272a326e05f87796045f0c9e79debdda9d9ff065afbb61411f647fe9c
4
- data.tar.gz: f5512226009f01dcf116ef1aa8a9a82d286459b52c28287fe4f886e740e16613
3
+ metadata.gz: ac607c50569f257378191c69e03d27d136d4644d0cbe64f7f4ac194f91a90a65
4
+ data.tar.gz: b88301259811836561ea14d322b50eb4e2111fb187eaa4a97e53449f76ff33fe
5
5
  SHA512:
6
- metadata.gz: 0afab3d60b6690dda4cc7bd5dbc74e0da1906a848532b71bc37b7bdcd56e7e1d91bdaf1d7d76309831c18570e13460cff3197bcf146c9d83516338fc0f443753
7
- data.tar.gz: 7c2ff1b829f59d23b7012f054377c2b04591133dda7d4603dd11334b6ff769c40175ac80988546277f3641ad1ce3c0bc71611a9eefc9bc78f15c05ce15916e94
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,39 +1,42 @@
1
- require 'aws-sdk-lambda'
2
- require 'uri'
3
- require 'ssrfs-up/version'
4
- require 'ostruct'
1
+ require "aws-sdk-lambda"
2
+ require "uri"
3
+ require "ssrfs-up/version"
4
+ require "ostruct"
5
+ require "ssrf_filter"
6
+ require "cgi"
5
7
 
6
8
  # Common files
7
- require 'openapi_client/lib/openapi_client/api_client'
8
- require 'openapi_client/lib/openapi_client/api_error'
9
- require 'openapi_client/lib/openapi_client/version'
10
- 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"
11
13
 
12
14
  # Models
13
- require 'openapi_client/lib/openapi_client/models/content_type'
14
- require 'openapi_client/lib/openapi_client/models/method'
15
- require 'openapi_client/lib/openapi_client/models/redirect'
16
- require 'openapi_client/lib/openapi_client/models/request'
17
- require 'openapi_client/lib/openapi_client/models/response'
18
- require 'openapi_client/lib/openapi_client/models/response_error'
19
- 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"
20
22
 
21
23
  # APIs
22
- require 'openapi_client/lib/openapi_client/api/default_api'
24
+ require "openapi_client/lib/openapi_client/api/default_api"
23
25
  ##
24
26
  # This module contains the AWS lambda client and helper methods to easily
25
27
  # make requests to it. All methods take a hostname or URI and a hash or options
26
28
  # for the request.
27
29
  module SSRFsUp
28
30
  class Configuration
29
- attr_accessor :func_name, :invoke_type, :log_type, :region, :test
31
+ attr_accessor :func_name, :invoke_type, :log_type, :region, :test, :proxy
30
32
 
31
33
  def initialize
32
- @func_name = 'arn:aws:lambda:us-west-2:871040364337:function:sec-czi-sec-ssrfs-up:sec-czi-sec-ssrfs-up'
33
- @invoke_type = 'RequestResponse'
34
- @log_type = 'None'
35
- @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"
36
38
  @test = false
39
+ @proxy = true
37
40
  end
38
41
  end
39
42
 
@@ -47,64 +50,64 @@ module SSRFsUp
47
50
  # https://github.com/chanzuckerberg/SSRFs-Up/blob/0e18fd30bee3f2b99ff4bc512cb967b83e8d9dcb/openapi.yaml#L97-L119
48
51
  def do(method, host, opts = {})
49
52
  case method.downcase
50
- when 'get'
53
+ when "get"
51
54
  get(host, opts)
52
- when 'put'
55
+ when "put"
53
56
  put(host, opts)
54
- when 'post'
57
+ when "post"
55
58
  post(host, opts)
56
- when 'patch'
59
+ when "patch"
57
60
  patch(host, opts)
58
- when 'delete'
61
+ when "delete"
59
62
  delete(host, opts)
60
63
  end
61
64
  end
62
65
 
63
66
  # convenience method for making a GET request with do.
64
67
  def get(host, opts = {})
65
- opts['method'] = 'GET'
68
+ opts[:method] = "GET"
66
69
  invoke(host, opts)
67
70
  end
68
71
 
69
72
  # convenience method for making a PUT request with do.
70
73
  def put(host, opts = {})
71
- opts['method'] = 'PUT'
74
+ opts[:method] = "PUT"
72
75
  invoke(host, opts)
73
76
  end
74
77
 
75
78
  # convenience method for making a POST request with do.
76
79
  def post(host, opts = {})
77
- opts['method'] = 'POST'
80
+ opts[:method] = "POST"
78
81
  invoke(host, opts)
79
82
  end
80
83
 
81
84
  # convenience method for making a patch request with do.
82
85
  def patch(host, opts = {})
83
- opts['method'] = 'PATCH'
86
+ opts[:method] = "PATCH"
84
87
  invoke(host, opts)
85
88
  end
86
89
 
87
90
  # convenience method for making a DELETE request with do.
88
91
  def delete(host, opts = {})
89
- opts['method'] = 'DELETE'
92
+ opts[:method] = "DELETE"
90
93
  invoke(host, opts)
91
94
  end
92
95
 
93
96
  # takes an ambiguous string or URI and sets the appropriate options based
94
97
  # on if it can be parsed as URI object. If it can't, then the string is assumed
95
98
  # to be a hostname only.
96
- def parseAsUri(uri = '')
99
+ def parseAsUri(uri = "")
97
100
  uri = uri.to_s
98
- opts = { 'host' => uri.split('/')[0].split('?')[0].split('#')[0] }
101
+ opts = { :host => uri.split("/")[0].split("?")[0].split("#")[0] }
99
102
  u = URI(uri)
100
103
 
101
104
  # if the scheme was present, we can parse most of the options from the URI.
102
105
  # otherwise, we can assume the URI was an actual hostname
103
106
  unless u.scheme.nil?
104
- opts['secure'] = !(u.scheme == 'http')
105
- opts['host'] = u.host
106
- opts['path'] = u.path unless u.path == ''
107
- 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?
108
111
  end
109
112
  opts
110
113
  end
@@ -130,25 +133,63 @@ module SSRFsUp
130
133
  @client ||= Aws::Lambda::Client.new(region: configuration.region)
131
134
  end
132
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
+
133
167
  # invokes the lambda with the provided arguments. It handles all lambda
134
168
  # related errors so developers should assume the data they receive back is straight
135
169
  # from the server they are speaking to.
136
170
  def invoke(host = nil, opts = {})
137
171
  opts = opts.merge(parseAsUri(host))
138
- resp = client.invoke({
139
- function_name: configuration.func_name,
140
- invocation_type: configuration.invoke_type,
141
- log_type: configuration.log_type,
142
- payload: payload(opts)
143
- })
144
-
145
- if resp['status_code'] == 200
146
- OpenStruct.new(JSON.parse(resp&.payload&.string))
172
+ if (!opts[:proxy].nil? && !opts[:proxy]) || !configuration.proxy
173
+ OpenStruct.new(fast_check(host, opts))
147
174
  else
148
- 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
149
192
  end
150
- rescue StandardError => e
151
- OpenStruct.new({ body: '', status_code: 500, status_text: e.to_s })
152
193
  end
153
194
 
154
195
  # payload builds an API client Request object with the proper defaults and
@@ -156,5 +197,5 @@ module SSRFsUp
156
197
  def payload(opts = {})
157
198
  toOpenAPIClient(opts).to_json
158
199
  end
159
- end
200
+ end
160
201
  end
@@ -1,3 +1,3 @@
1
1
  module SSRFsUp
2
- VERSION = '0.0.17'.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.17
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-19 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
@@ -50,6 +50,20 @@ dependencies:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 1.0.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: ssrf_filter
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.0'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.0'
53
67
  - !ruby/object:Gem::Dependency
54
68
  name: bundler
55
69
  requirement: !ruby/object:Gem::Requirement