super_good-csrf_protection 0.1.0 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9d72a1f2adf6520a6be566c98402df02f4e59adb8567f985ace1823f3400a1a
4
- data.tar.gz: 4e35d9e3cd61d94fc01a279ee0df1485649aa65431b6a27c6b109c24f7006ab2
3
+ metadata.gz: c38d5a4d889a7d8042dd87084aa0f76517d9ffc9b7c5155f2639942eea86f530
4
+ data.tar.gz: '093397982b8dc7e3e844f686a7d67670b1b47872bc1d85847fd33139d0cdeecb'
5
5
  SHA512:
6
- metadata.gz: 4050fb91b22a24569e29c9ce52a0b07b5b693ea587b5d99ef25b1401e46cdc4a6a4860b3a0b58ba542e0c85bb567720fa135a725aabcee6fffe341db10ae5b1f
7
- data.tar.gz: b6b597b61916f68d9416e33770f2826509c603fb4d446c52bc3c3829ea2e41bb5bd6919b2f8e81b008504425105fdb967dc767a7d1b1a6a86cf545d4680edc8b
6
+ metadata.gz: ff7b802cacf1bc487faba29b309cc74cca4ee5919a087d583769bbbcdf2baaa8befa72a3f3414ba4348995ac32e1f038e55d13264cd6877baf26e8697fe1bf3f
7
+ data.tar.gz: 48ac1c0d4c4d4d4a007829dd039eb22bee548ce43c614546436e68e29e2990b79e4071bc0b34eab7b7b6186a64f38b0c9886f0b309111317e2e6a58b41d6d684
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # SuperGood::CSRFProtection
2
2
 
3
- A Rack middleware for CSRF protection using the Sec-Fetch-Site header to prevent cross-site requests.
3
+ This Rack middleware provides CSRF protection using the Sec-Fetch-Site header. It is inspired by Go's `http.CrossOriginProtection` which was introduced in Go 1.25. You can read about it [in this article](https://www.alexedwards.net/blog/preventing-csrf-in-go) and find more information about the `Sec-Fetch-Site` header [on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Sec-Fetch-Site).
4
4
 
5
5
  ## Installation
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'super_good-csrf_protection'
10
+ gem "super_good-csrf_protection"
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -27,12 +27,12 @@ gem install super_good-csrf_protection
27
27
  Add the middleware to your Rack application:
28
28
 
29
29
  ```ruby
30
- require 'super_good/csrf_protection'
30
+ require "super_good/csrf_protection"
31
31
 
32
32
  use SuperGood::CSRFProtection
33
33
  ```
34
34
 
35
- The middleware will automatically reject non-GET requests that don't have a `Sec-Fetch-Site: same-origin` header, providing protection against CSRF attacks.
35
+ The middleware rejects all non-GET requests without the `Sec-Fetch-Site: same-origin` header, providing protection against CSRF attacks.
36
36
 
37
37
  ## Development
38
38
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module SuperGood
4
4
  class CSRFProtection
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
- end
7
+ end
@@ -6,22 +6,48 @@ module SuperGood
6
6
  class CSRFProtection
7
7
  class Error < StandardError; end
8
8
 
9
- def initialize(app)
9
+ SAFE_METHODS = %w[GET HEAD OPTIONS].freeze
10
+ SAFE_SEC_FETCH_SITE_VALUES = %w[same-origin none].freeze
11
+
12
+ def initialize(app, raise_error: false)
10
13
  @app = app
14
+ @raise_error = raise_error
11
15
  end
12
16
 
13
17
  def call(env)
14
- if unsafe_request?(env) && env["HTTP_SEC_FETCH_SITE"] != "same-origin"
15
- raise(Error, "Invalid Sec-Fetch-Site header")
16
- end
18
+ return @app.call(env) unless unsafe_request?(env) && cross_origin?(env)
17
19
 
18
- @app.call(env)
20
+ if @raise_error
21
+ raise(Error, "Cross-origin request denied")
22
+ else
23
+ [403, {"Content-Type" => "text/plain"}, ["Forbidden"]]
24
+ end
19
25
  end
20
26
 
21
27
  private
22
28
 
23
29
  def unsafe_request?(env)
24
- env["REQUEST_METHOD"] != "GET"
30
+ !SAFE_METHODS.include?(env["REQUEST_METHOD"])
31
+ end
32
+
33
+ def cross_origin?(env)
34
+ sec_fetch_site = env["HTTP_SEC_FETCH_SITE"]
35
+ return !SAFE_SEC_FETCH_SITE_VALUES.include?(sec_fetch_site) if sec_fetch_site
36
+
37
+ origin = env["HTTP_ORIGIN"]
38
+ return false unless origin
39
+
40
+ host = env["HTTP_HOST"]
41
+ origin_host = extract_host_from_origin(origin)
42
+
43
+ origin_host != host
44
+ end
45
+
46
+ def extract_host_from_origin(origin)
47
+ uri = URI.parse(origin)
48
+ (uri.port == uri.default_port) ? uri.host : "#{uri.host}:#{uri.port}"
49
+ rescue URI::InvalidURIError
50
+ nil
25
51
  end
26
52
  end
27
- end
53
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: super_good-csrf_protection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sofia Besenski
@@ -13,7 +13,8 @@ bindir: exe
13
13
  cert_chain: []
14
14
  date: 1980-01-02 00:00:00.000000000 Z
15
15
  dependencies: []
16
- description: A Rack middleware for handling the Sec-Fetch-Site header.
16
+ description: A Rack middleware for preventing CSRF attacks using the Sec-Fetch-Site
17
+ header
17
18
  email:
18
19
  - sofia@super.gd
19
20
  - jared@super.gd
@@ -54,5 +55,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
55
  requirements: []
55
56
  rubygems_version: 3.6.9
56
57
  specification_version: 4
57
- summary: A Rack middleware for handling the Sec-Fetch-Site header.
58
+ summary: A Rack middleware for preventing CSRF attacks using the Sec-Fetch-Site header
58
59
  test_files: []