Created
July 3, 2019 00:23
-
-
Save rantler/e99811b4126621bd5fa469a49fb6c3b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'base64' | |
class ValidateCsrfTokens | |
class << self | |
def validate(form_token:, cookie_token:) | |
decoded_form_token = Base64::decode64(form_token) | |
decoded_cookie_token = Base64::decode64(cookie_token) | |
form_token_length = decoded_form_token.bytes.length | |
cookie_token_length = decoded_cookie_token.bytes.length | |
if cookie_token_length != form_token_length | |
messages = [token_length_messages(cookie_token_length, 'cookie')] | |
messages << token_length_messages(form_token_length, 'form') | |
puts("FAILED: Token length mismatch (#{messages.compact})") | |
end | |
form_otp = decoded_form_token[0..31] | |
form_encrypted_bytes = decoded_form_token[32..-1] | |
cookie_otp = decoded_cookie_token[0..31] | |
cookie_encrypted_bytes = decoded_cookie_token[32..-1] | |
if xor_byte_strings(form_otp, form_encrypted_bytes) == xor_byte_strings(cookie_otp, cookie_encrypted_bytes) | |
puts("PASS: CSRF token checks out!") | |
else | |
puts("FAILED: Invalid CSRF token - decrypted bytes didn't match") | |
end | |
end | |
private | |
def token_length_messages(length, type) | |
case | |
when length < 64 then "#{type} too short" | |
when length > 64 then "#{type} too long" | |
end | |
end | |
# Copy/pasta from Rails internal code | |
def xor_byte_strings(s1, s2) | |
s2 = s2.dup | |
size = s1.bytesize | |
i = 0 | |
while i < size | |
s2.setbyte(i, s1.getbyte(i) ^ s2.getbyte(i)) | |
i += 1 | |
end | |
s2 | |
end | |
end | |
end | |
ValidateCsrfTokens.validate( | |
form_token: 'bm+aqMlmtq49D9SuxNtkwftnharM8yISYJe+rkCAeIcAgkxlpr6uh4SEyOZEueY9IcyCZKV/nu3x2etqt3ykng==', | |
cookie_token: 'CN46Ju+pu2X30xxqKZ9pYZfobje/zHgYnu+Vw7TgBXVmM+zrgHGjTE5YACKp/eudTUNp+dZAxOcPocAHQxzZbA==' | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment