Skip to content

Commit 8976469

Browse files
committed
Ruby: Model some Rails cookie configuration settings
1 parent 5ce6e63 commit 8976469

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

ruby/ql/lib/codeql/ruby/frameworks/Rails.qll

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,27 @@ private module Settings {
168168

169169
boolean getValue() { result = valueLiteral.getValue() }
170170
}
171+
172+
/**
173+
* A node that sets a Stringlike value.
174+
*/
175+
class StringlikeSetting extends LiteralSetting {
176+
override StringlikeLiteral valueLiteral;
177+
}
178+
179+
/**
180+
* A node that sets a Stringlike value, or `nil`.
181+
*/
182+
class NillableStringlikeSetting extends LiteralSetting {
183+
NillableStringlikeSetting() {
184+
valueLiteral instanceof StringlikeLiteral or
185+
valueLiteral instanceof NilLiteral
186+
}
187+
188+
string getStringValue() { result = valueLiteral.(StringlikeLiteral).getValueText() }
189+
190+
predicate isNilValue() { valueLiteral instanceof NilLiteral }
191+
}
171192
}
172193

173194
/**
@@ -184,5 +205,72 @@ private class AllowForgeryProtectionSetting extends Settings::BooleanSetting,
184205
override boolean getVerificationSetting() { result = this.getValue() }
185206
}
186207

208+
/**
209+
* Sets the cipher to be used for encrypted cookies. Defaults to "aes-256-gcm".
210+
* This can be set to any cipher supported by
211+
* https://ruby-doc.org/stdlib-2.7.1/libdoc/openssl/rdoc/OpenSSL/Cipher.html
212+
*/
213+
private class EncryptedCookieCipherSetting extends Settings::StringlikeSetting,
214+
CookieSecurityConfigurationSetting::Range {
215+
EncryptedCookieCipherSetting() {
216+
this.getReceiver() instanceof Config::ActionDispatchNode and
217+
this.getMethodName() = "encrypted_cookie_cipher="
218+
}
219+
220+
OpenSSLCipher getCipher() { this.getValueText() = result.getName() }
221+
222+
OpenSSLCipher getDefaultCipher() { result.getName() = "aes-256-gcm" }
223+
224+
override string getSecurityWarningMessage() {
225+
this.getCipher().isWeak() and
226+
result = this.getValueText() + " is a weak cipher."
227+
}
228+
}
229+
230+
/**
231+
* If true, signed and encrypted cookies will use the AES-256-GCM cipher rather
232+
* than the older AES-256-CBC cipher. Defaults to true.
233+
*/
234+
private class UseAuthenticatedCookieEncryptionSetting extends Settings::BooleanSetting,
235+
CookieSecurityConfigurationSetting::Range {
236+
UseAuthenticatedCookieEncryptionSetting() {
237+
this.getReceiver() instanceof Config::ActionDispatchNode and
238+
this.getMethodName() = "use_authenticated_cookie_encryption="
239+
}
240+
241+
boolean getDefaultValue() { result = true }
242+
243+
override string getSecurityWarningMessage() {
244+
this.getValue() = false and
245+
result = this.getSettingString() + " selects a weaker block mode for authenticated cookies."
246+
}
247+
}
248+
249+
// TODO: this may also take a proc that specifies how to handle specific requests
250+
/**
251+
* Configures the default value of the `SameSite` attribute when setting cookies.
252+
* Valid string values are `strict`, `lax`, and `none`.
253+
* The attribute can be omitted by setting this to `nil`.
254+
* The default if unset is `:lax`.
255+
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#strict
256+
*/
257+
private class CookiesSameSiteProtectionSetting extends Settings::NillableStringlikeSetting,
258+
CookieSecurityConfigurationSetting::Range {
259+
CookiesSameSiteProtectionSetting() {
260+
this.getReceiver() instanceof Config::ActionDispatchNode and
261+
this.getMethodName() = "cookies_same_site_protection="
262+
}
263+
264+
string getDefaultValue() { result = "lax" }
265+
266+
override string getSecurityWarningMessage() {
267+
// Mark unset as being potentially dangerous, as not all browsers default to "lax"
268+
this.getStringValue().toLowerCase() = "none" and
269+
result = "Setting 'SameSite' to 'None' may make an application more vulnerable to CSRF attacks."
270+
or
271+
this.isNilValue() and
272+
result = "Unsetting 'SameSite' can disable same-site cookie restrictions in some browsers."
273+
}
274+
}
187275
// TODO: initialization hooks, e.g. before_configuration, after_initialize...
188276
// TODO: initializers

0 commit comments

Comments
 (0)