|
1 | | -require 'active_support/security_utils' |
2 | 1 | require 'base64' |
3 | 2 | require 'openssl' |
| 3 | +require 'json' |
4 | 4 | require 'perimeterx/internal/exceptions/px_cookie_decryption_exception' |
5 | 5 |
|
6 | 6 | module PxModule |
@@ -123,26 +123,34 @@ def decrypt(px_cookie) |
123 | 123 | cipher.iv = iv |
124 | 124 | plaintext = cipher.update(cipher_text) + cipher.final |
125 | 125 |
|
126 | | - return eval(plaintext) |
| 126 | + return JSON.parse(plaintext, symbolize_names: true) |
127 | 127 | rescue Exception => e |
128 | 128 | @logger.debug("PerimeterxCookie[decrypt]: Cookie decrypt fail #{e.message}") |
129 | 129 | raise PxCookieDecryptionException.new("Cookie decrypt fail => #{e.message}"); |
130 | 130 | end |
131 | 131 | end |
132 | 132 |
|
133 | 133 | def decode(px_cookie) |
134 | | - return eval(Base64.decode64(px_cookie)) |
| 134 | + return JSON.parse(Base64.decode64(px_cookie), symbolize_names: true) |
135 | 135 | end |
136 | 136 |
|
137 | 137 |
|
138 | 138 | def hmac_valid?(hmac_str, cookie_hmac) |
139 | 139 | hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, @cookie_secret, hmac_str) |
140 | | - # ref: https://thisdata.com/blog/timing-attacks-against-string-comparison/ |
141 | | - password_correct = ActiveSupport::SecurityUtils.secure_compare( |
142 | | - ::Digest::SHA256.hexdigest(cookie_hmac), |
143 | | - ::Digest::SHA256.hexdigest(hmac) |
144 | | - ) |
| 140 | + password_correct = secure_compare(hmac, cookie_hmac) |
| 141 | + end |
| 142 | + |
| 143 | + def secure_compare(a, b) |
| 144 | + # https://github.com/rails/rails/blob/main/activesupport/lib/active_support/security_utils.rb |
| 145 | + if (a.bytesize != b.bytesize) |
| 146 | + return false |
| 147 | + end |
| 148 | + |
| 149 | + l = a.unpack "C#{a.bytesize}" |
145 | 150 |
|
| 151 | + res = 0 |
| 152 | + b.each_byte { |byte| res |= byte ^ l.shift } |
| 153 | + res == 0 |
146 | 154 | end |
147 | 155 | end |
148 | 156 | end |
0 commit comments