Class: Gloo::Objs::CsrfToken
- Inherits:
-
Object
- Object
- Gloo::Objs::CsrfToken
- Defined in:
- lib/gloo/objs/security/csrf_token.rb
Constant Summary collapse
- TOKEN_LENGTH =
32
- AUTHENTICITY_TOKEN =
'authenticity_token'.freeze
Class Method Summary collapse
-
.compare_tokens(token1, token2) ⇒ Object
Compare two tokens.
-
.generate_csrf_token ⇒ Object
Generate a random token.
-
.get_csrf_token_hidden_field(base_token) ⇒ Object
Return a hidden field with the masked csrf token.
-
.mask_token(base_token) ⇒ Object
Generate a masked token.
-
.unmask_token(masked_token) ⇒ Object
Unmask a masked token.
-
.valid_csrf_token?(base_token, masked_token) ⇒ Boolean
Validate a masked csrf token that came from a form submit.
Class Method Details
.compare_tokens(token1, token2) ⇒ Object
Compare two tokens. Use ActiveSupport::SecurityUtils.secure_compare to avoid timing attacks.
46 47 48 |
# File 'lib/gloo/objs/security/csrf_token.rb', line 46 def self.compare_tokens( token1, token2 ) return ActiveSupport::SecurityUtils.secure_compare( token1, token2 ) end |
.generate_csrf_token ⇒ Object
Generate a random token
20 21 22 |
# File 'lib/gloo/objs/security/csrf_token.rb', line 20 def self.generate_csrf_token SecureRandom.base64( TOKEN_LENGTH ) end |
.get_csrf_token_hidden_field(base_token) ⇒ Object
Return a hidden field with the masked csrf token.
53 54 55 56 57 |
# File 'lib/gloo/objs/security/csrf_token.rb', line 53 def self.get_csrf_token_hidden_field( base_token ) form_token = mask_token( base_token ) return "<input type='hidden' name='#{AUTHENTICITY_TOKEN}' value='#{form_token}' />" end |
.mask_token(base_token) ⇒ Object
Generate a masked token.
27 28 29 30 31 |
# File 'lib/gloo/objs/security/csrf_token.rb', line 27 def self.mask_token( base_token ) one_time_pad = SecureRandom.random_bytes( base_token.bytesize ) masked_token = one_time_pad.bytes.zip( base_token.bytes ).map { |a, b| a ^ b }.pack('C*') return Base64.urlsafe_encode64( one_time_pad + masked_token ) # Encode the result end |
.unmask_token(masked_token) ⇒ Object
Unmask a masked token.
36 37 38 39 40 |
# File 'lib/gloo/objs/security/csrf_token.rb', line 36 def self.unmask_token( masked_token ) decoded = Base64.urlsafe_decode64( masked_token ) one_time_pad, masked_token = decoded[0...decoded.length / 2], decoded[decoded.length / 2..] return one_time_pad.bytes.zip( masked_token.bytes ).map { |a, b| (a ^ b).chr }.join end |
.valid_csrf_token?(base_token, masked_token) ⇒ Boolean
Validate a masked csrf token that came from a form submit.
62 63 64 65 66 67 68 |
# File 'lib/gloo/objs/security/csrf_token.rb', line 62 def self.valid_csrf_token?( base_token, masked_token ) return false unless base_token && masked_token unmasked_token = unmask_token( masked_token ) return compare_tokens( base_token, unmasked_token ) end |