@@ -168,6 +168,27 @@ private module Settings {
168
168
169
169
boolean getValue ( ) { result = valueLiteral .getValue ( ) }
170
170
}
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
+ }
171
192
}
172
193
173
194
/**
@@ -184,5 +205,72 @@ private class AllowForgeryProtectionSetting extends Settings::BooleanSetting,
184
205
override boolean getVerificationSetting ( ) { result = this .getValue ( ) }
185
206
}
186
207
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
+ }
187
275
// TODO: initialization hooks, e.g. before_configuration, after_initialize...
188
276
// TODO: initializers
0 commit comments