oauth 1.1.4 → 1.1.6

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +42 -1
  4. data/CITATION.cff +6 -6
  5. data/CODE_OF_CONDUCT.md +0 -0
  6. data/CONTRIBUTING.md +88 -34
  7. data/FUNDING.md +6 -9
  8. data/LICENSE.md +71 -0
  9. data/README.md +222 -166
  10. data/RUBOCOP.md +0 -0
  11. data/SECURITY.md +1 -4
  12. data/certs/pboling.pem +27 -0
  13. data/lib/oauth/auth_sanitizer.rb +36 -0
  14. data/lib/oauth/client/action_controller_request.rb +0 -0
  15. data/lib/oauth/client/em_http.rb +0 -0
  16. data/lib/oauth/client/helper.rb +0 -0
  17. data/lib/oauth/client/net_http.rb +0 -0
  18. data/lib/oauth/client.rb +0 -0
  19. data/lib/oauth/consumer.rb +70 -18
  20. data/lib/oauth/errors/error.rb +0 -0
  21. data/lib/oauth/errors/problem.rb +0 -0
  22. data/lib/oauth/errors/unauthorized.rb +0 -0
  23. data/lib/oauth/errors.rb +0 -0
  24. data/lib/oauth/helper.rb +0 -0
  25. data/lib/oauth/oauth.rb +0 -0
  26. data/lib/oauth/oauth_test_helper.rb +0 -0
  27. data/lib/oauth/optional.rb +0 -0
  28. data/lib/oauth/request_proxy/action_controller_request.rb +0 -0
  29. data/lib/oauth/request_proxy/action_dispatch_request.rb +0 -0
  30. data/lib/oauth/request_proxy/base.rb +0 -0
  31. data/lib/oauth/request_proxy/curb_request.rb +0 -0
  32. data/lib/oauth/request_proxy/em_http_request.rb +0 -0
  33. data/lib/oauth/request_proxy/jabber_request.rb +0 -0
  34. data/lib/oauth/request_proxy/mock_request.rb +0 -0
  35. data/lib/oauth/request_proxy/net_http.rb +0 -0
  36. data/lib/oauth/request_proxy/rack_request.rb +0 -0
  37. data/lib/oauth/request_proxy/rest_client_request.rb +0 -0
  38. data/lib/oauth/request_proxy/typhoeus_request.rb +0 -0
  39. data/lib/oauth/request_proxy.rb +0 -0
  40. data/lib/oauth/server.rb +0 -0
  41. data/lib/oauth/signature/base.rb +2 -2
  42. data/lib/oauth/signature/hmac/sha1.rb +0 -0
  43. data/lib/oauth/signature/hmac/sha256.rb +0 -0
  44. data/lib/oauth/signature/plaintext.rb +0 -0
  45. data/lib/oauth/signature/rsa/sha1.rb +0 -0
  46. data/lib/oauth/signature.rb +0 -0
  47. data/lib/oauth/token.rb +0 -0
  48. data/lib/oauth/tokens/access_token.rb +0 -0
  49. data/lib/oauth/tokens/consumer_token.rb +0 -0
  50. data/lib/oauth/tokens/request_token.rb +0 -0
  51. data/lib/oauth/tokens/server_token.rb +0 -0
  52. data/lib/oauth/tokens/token.rb +2 -2
  53. data/lib/oauth/version.rb +1 -1
  54. data/lib/oauth.rb +2 -1
  55. data/sig/oauth/consumer.rbs +1 -1
  56. data/sig/oauth/signature/base.rbs +1 -1
  57. data/sig/oauth/tokens/token.rbs +1 -1
  58. data/sig/oauth/version.rbs +6 -0
  59. data.tar.gz.sig +0 -0
  60. metadata +138 -106
  61. metadata.gz.sig +0 -0
  62. data/LICENSE.txt +0 -22
  63. data/REEK +0 -2
data/RUBOCOP.md CHANGED
File without changes
data/SECURITY.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Version | Supported |
6
6
  |----------|-----------|
7
- | 1.latest | ✅ |
7
+ | 1.1.latest | ✅ |
8
8
 
9
9
  ## Security contact information
10
10
 
@@ -12,8 +12,6 @@ To report a security vulnerability, please use the
12
12
  [Tidelift security contact](https://tidelift.com/security).
13
13
  Tidelift will coordinate the fix and disclosure.
14
14
 
15
- More detailed explanation of the process is in [IRP.md][IRP].
16
-
17
15
  ## Additional Support
18
16
 
19
17
  If you are interested in support for versions older than the latest release,
@@ -21,4 +19,3 @@ please consider sponsoring the project / maintainer @ https://liberapay.com/pbol
21
19
  or find other sponsorship links in the [README].
22
20
 
23
21
  [README]: README.md
24
- [IRP]: IRP.md
data/certs/pboling.pem ADDED
@@ -0,0 +1,27 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl
3
+ ci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW
4
+ A2NvbTAeFw0yNTA1MDQxNTMzMDlaFw00NTA0MjkxNTMzMDlaMEMxFTATBgNVBAMM
5
+ DHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
6
+ LGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAruUoo0WA
7
+ uoNuq6puKWYeRYiZekz/nsDeK5x/0IEirzcCEvaHr3Bmz7rjo1I6On3gGKmiZs61
8
+ LRmQ3oxy77ydmkGTXBjruJB+pQEn7UfLSgQ0xa1/X3kdBZt6RmabFlBxnHkoaGY5
9
+ mZuZ5+Z7walmv6sFD9ajhzj+oIgwWfnEHkXYTR8I6VLN7MRRKGMPoZ/yvOmxb2DN
10
+ coEEHWKO9CvgYpW7asIihl/9GMpKiRkcYPm9dGQzZc6uTwom1COfW0+ZOFrDVBuV
11
+ FMQRPswZcY4Wlq0uEBLPU7hxnCL9nKK6Y9IhdDcz1mY6HZ91WImNslOSI0S8hRpj
12
+ yGOWxQIhBT3fqCBlRIqFQBudrnD9jSNpSGsFvbEijd5ns7Z9ZMehXkXDycpGAUj1
13
+ to/5cuTWWw1JqUWrKJYoifnVhtE1o1DZ+LkPtWxHtz5kjDG/zR3MG0Ula0UOavlD
14
+ qbnbcXPBnwXtTFeZ3C+yrWpE4pGnl3yGkZj9SMTlo9qnTMiPmuWKQDatAgMBAAGj
15
+ fzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQE8uWvNbPVNRXZ
16
+ HlgPbc2PCzC4bjAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG
17
+ A1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD
18
+ ggGBAJbnUwfJQFPkBgH9cL7hoBfRtmWiCvdqdjeTmi04u8zVNCUox0A4gT982DE9
19
+ wmuN12LpdajxZONqbXuzZvc+nb0StFwmFYZG6iDwaf4BPywm2e/Vmq0YG45vZXGR
20
+ L8yMDSK1cQXjmA+ZBKOHKWavxP6Vp7lWvjAhz8RFwqF9GuNIdhv9NpnCAWcMZtpm
21
+ GUPyIWw/Cw/2wZp74QzZj6Npx+LdXoLTF1HMSJXZ7/pkxLCsB8m4EFVdb/IrW/0k
22
+ kNSfjtAfBHO8nLGuqQZVH9IBD1i9K6aSs7pT6TW8itXUIlkIUI2tg5YzW6OFfPzq
23
+ QekSkX3lZfY+HTSp/o+YvKkqWLUV7PQ7xh1ZYDtocpaHwgxe/j3bBqHE+CUPH2vA
24
+ 0V/FwdTRWcwsjVoOJTrYcff8pBZ8r2MvtAc54xfnnhGFzeRHfcltobgFxkAXdE6p
25
+ DVjBtqT23eugOqQ73umLcYDZkc36vnqGxUBSsXrzY9pzV5gGr2I8YUxMqf6ATrZt
26
+ L9nRqA==
27
+ -----END CERTIFICATE-----
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OAuth
4
+ AUTH_SANITIZER = begin
5
+ auth_sanitizer_requirement = Gem::Requirement.new("~> 0.1", ">= 0.1.3")
6
+ auth_sanitizer_spec = Gem.loaded_specs["auth-sanitizer"]
7
+ unless auth_sanitizer_spec && auth_sanitizer_requirement.satisfied_by?(auth_sanitizer_spec.version)
8
+ # :nocov:
9
+ auth_sanitizer_spec = Gem::Specification.find_by_name("auth-sanitizer", auth_sanitizer_requirement)
10
+ # :nocov:
11
+ end
12
+
13
+ auth_sanitizer_loader_path = File.join(
14
+ auth_sanitizer_spec.full_gem_path,
15
+ "lib/auth_sanitizer/loader.rb",
16
+ )
17
+ unless File.file?(auth_sanitizer_loader_path)
18
+ # :nocov:
19
+ raise LoadError, "oauth requires auth-sanitizer #{auth_sanitizer_requirement}; " \
20
+ "loader not found at #{auth_sanitizer_loader_path}"
21
+ # :nocov:
22
+ end
23
+
24
+ auth_sanitizer_loader_namespace = Module.new
25
+ auth_sanitizer_loader_namespace.module_eval(
26
+ File.read(auth_sanitizer_loader_path),
27
+ auth_sanitizer_loader_path,
28
+ 1,
29
+ )
30
+
31
+ auth_sanitizer_loader_namespace
32
+ .const_get(:AuthSanitizer)
33
+ .const_get(:Loader)
34
+ .load_isolated
35
+ end
36
+ end
File without changes
File without changes
File without changes
File without changes
data/lib/oauth/client.rb CHANGED
File without changes
@@ -10,10 +10,10 @@ require "cgi"
10
10
  module OAuth
11
11
  # Consumer credentials and request configuration for OAuth 1.0 / 1.0a flows.
12
12
  #
13
- # Includes {Auth::Sanitizer::FilteredAttributes} so inspect output redacts the
13
+ # Includes {OAuth::AUTH_SANITIZER::FilteredAttributes} so inspect output redacts the
14
14
  # consumer secret while leaving non-sensitive configuration visible.
15
15
  class Consumer
16
- include Auth::Sanitizer::FilteredAttributes
16
+ include OAuth::AUTH_SANITIZER::FilteredAttributes
17
17
 
18
18
  # Instance attributes exposed by the consumer.
19
19
  #
@@ -89,6 +89,12 @@ module OAuth
89
89
  body_hash_enabled: true,
90
90
 
91
91
  oauth_version: "1.0",
92
+
93
+ # Token endpoint redirects are followed only within the same origin by
94
+ # default. Cross-origin redirects can re-sign token requests for an
95
+ # attacker-controlled endpoint, so they require explicit opt-in.
96
+ token_request_max_redirects: 10,
97
+ token_request_cross_origin_redirects: false,
92
98
  },
93
99
  )
94
100
 
@@ -294,14 +300,13 @@ module OAuth
294
300
  end
295
301
 
296
302
  # Creates a request and parses the result as url_encoded. This is used internally for the RequestToken and AccessToken requests.
297
- def token_request(http_method, path, token = nil, request_options = {}, *arguments)
298
- request_options[:token_request] ||= true
299
- response = request(http_method, path, token, request_options, *arguments)
303
+ def token_request(http_method, path, token = nil, request_options = {}, *arguments, &block)
304
+ response = request(http_method, path, token, token_request_options(request_options), *arguments)
300
305
  case response.code.to_i
301
306
 
302
307
  when (200..299)
303
- if block_given?
304
- yield response.body
308
+ if block
309
+ block.call(response.body)
305
310
  else
306
311
  # symbolize keys
307
312
  # TODO this could be considered unexpected behavior; symbols or not?
@@ -312,19 +317,17 @@ module OAuth
312
317
  end
313
318
  end
314
319
  when (300..399)
315
- # Parse redirect to follow
316
- uri = URI.parse(response["location"])
317
- our_uri = URI.parse(site)
318
-
319
- # Guard against infinite redirects
320
- response.error! if uri.path == path && our_uri.host == uri.host
320
+ current_uri = token_request_uri(path)
321
+ redirected_uri = token_request_redirect_uri(current_uri, response)
322
+ response.error! unless redirected_uri
321
323
 
322
- if uri.path == path && our_uri.host != uri.host
323
- options[:site] = "#{uri.scheme}://#{uri.host}"
324
- @http = create_http
325
- end
324
+ redirect_count = request_options[:token_request_redirect_count].to_i + 1
325
+ response.error! if redirect_count > token_request_max_redirects(request_options)
326
+ response.error! if token_request_cross_origin?(current_uri, redirected_uri) &&
327
+ !token_request_cross_origin_redirects?(request_options)
326
328
 
327
- token_request(http_method, uri.path, token, request_options, arguments)
329
+ redirect_options = request_options.merge(token_request_redirect_count: redirect_count)
330
+ token_request(http_method, token_request_redirect_path(current_uri, redirected_uri), token, redirect_options, *arguments, &block)
328
331
  when (400..499)
329
332
  raise OAuth::Unauthorized, response
330
333
  else
@@ -332,6 +335,55 @@ module OAuth
332
335
  end
333
336
  end
334
337
 
338
+ def token_request_options(request_options)
339
+ request_options.merge(token_request: true).tap do |options|
340
+ options.delete(:token_request_redirect_count)
341
+ options.delete(:token_request_max_redirects)
342
+ options.delete(:token_request_cross_origin_redirects)
343
+ end
344
+ end
345
+
346
+ def token_request_uri(path)
347
+ uri = URI.parse(path)
348
+ return uri if uri.absolute?
349
+
350
+ URI.parse(site).merge(path)
351
+ end
352
+
353
+ def token_request_redirect_uri(current_uri, response)
354
+ location = response["location"]
355
+ return if location.nil? || location.to_s.empty?
356
+
357
+ current_uri.merge(location)
358
+ end
359
+
360
+ def token_request_redirect_path(current_uri, redirected_uri)
361
+ return redirected_uri.to_s if token_request_cross_origin?(current_uri, redirected_uri)
362
+
363
+ redirected_uri.request_uri
364
+ end
365
+
366
+ def token_request_max_redirects(request_options)
367
+ request_options[:token_request_max_redirects] || options[:token_request_max_redirects]
368
+ end
369
+
370
+ def token_request_cross_origin_redirects?(request_options)
371
+ request_options.fetch(:token_request_cross_origin_redirects, options[:token_request_cross_origin_redirects])
372
+ end
373
+
374
+ def token_request_cross_origin?(current_uri, redirected_uri)
375
+ current_uri.scheme.to_s.downcase != redirected_uri.scheme.to_s.downcase ||
376
+ current_uri.host.to_s.downcase != redirected_uri.host.to_s.downcase ||
377
+ token_request_effective_port(current_uri) != token_request_effective_port(redirected_uri)
378
+ end
379
+
380
+ def token_request_effective_port(uri)
381
+ return uri.port if uri.port
382
+ return 443 if uri.scheme == "https"
383
+
384
+ 80 if uri.scheme == "http"
385
+ end
386
+
335
387
  # Sign the Request object. Use this if you have an externally generated http request object you want to sign.
336
388
  def sign!(request, token = nil, request_options = {})
337
389
  request.oauth!(http, self, token, options.merge(request_options))
File without changes
File without changes
File without changes
data/lib/oauth/errors.rb CHANGED
File without changes
data/lib/oauth/helper.rb CHANGED
File without changes
data/lib/oauth/oauth.rb CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/lib/oauth/server.rb CHANGED
File without changes
@@ -9,11 +9,11 @@ module OAuth
9
9
  module Signature
10
10
  # Base class for OAuth signature implementations.
11
11
  #
12
- # Includes {Auth::Sanitizer::FilteredAttributes} so inspect output redacts
12
+ # Includes {OAuth::AUTH_SANITIZER::FilteredAttributes} so inspect output redacts
13
13
  # secret-bearing fields captured during signature construction.
14
14
  class Base
15
15
  include OAuth::Helper
16
- include Auth::Sanitizer::FilteredAttributes
16
+ include OAuth::AUTH_SANITIZER::FilteredAttributes
17
17
 
18
18
  # Signature construction options.
19
19
  #
File without changes
File without changes
File without changes
File without changes
File without changes
data/lib/oauth/token.rb CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -3,12 +3,12 @@
3
3
  module OAuth
4
4
  # Superclass for the various tokens used by OAuth.
5
5
  #
6
- # Includes {Auth::Sanitizer::FilteredAttributes} so inspect output redacts the
6
+ # Includes {OAuth::AUTH_SANITIZER::FilteredAttributes} so inspect output redacts the
7
7
  # token value and token secret while leaving object identity and non-sensitive
8
8
  # fields visible.
9
9
  class Token
10
10
  include OAuth::Helper
11
- include Auth::Sanitizer::FilteredAttributes
11
+ include OAuth::AUTH_SANITIZER::FilteredAttributes
12
12
 
13
13
  # Token attributes.
14
14
  #
data/lib/oauth/version.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module OAuth
4
4
  module Version
5
- VERSION = "1.1.4"
5
+ VERSION = "1.1.6"
6
6
  end
7
7
  VERSION = Version::VERSION # Traditional Constant Location
8
8
  end
data/lib/oauth.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # third party gems
4
- require "auth/sanitizer"
5
4
  require "snaky_hash"
6
5
  require "version_gem"
6
+ require_relative "oauth/version"
7
7
 
8
8
  require "oauth/version"
9
+ require "oauth/auth_sanitizer"
9
10
 
10
11
  require "oauth/oauth"
11
12
 
@@ -1,6 +1,6 @@
1
1
  module OAuth
2
2
  class Consumer
3
- include Auth::Sanitizer::FilteredAttributes
3
+ include OAuth::AUTH_SANITIZER::FilteredAttributes
4
4
 
5
5
  attr_accessor options: untyped
6
6
  attr_accessor key: untyped
@@ -1,7 +1,7 @@
1
1
  module OAuth
2
2
  module Signature
3
3
  class Base
4
- include Auth::Sanitizer::FilteredAttributes
4
+ include OAuth::AUTH_SANITIZER::FilteredAttributes
5
5
 
6
6
  attr_accessor options: untyped
7
7
  attr_reader token_secret: untyped
@@ -1,6 +1,6 @@
1
1
  module OAuth
2
2
  class Token
3
- include Auth::Sanitizer::FilteredAttributes
3
+ include OAuth::AUTH_SANITIZER::FilteredAttributes
4
4
 
5
5
  attr_accessor token: untyped
6
6
  attr_accessor secret: untyped
@@ -0,0 +1,6 @@
1
+ module OAuth
2
+ module Version
3
+ VERSION: String
4
+ end
5
+ VERSION: String
6
+ end
data.tar.gz.sig CHANGED
Binary file