-
Notifications
You must be signed in to change notification settings - Fork 583
Refuse to set signed or encrypted cookies with an insecure default secret #2252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
It seems a little overengineered, but i also don't know a better solution. |
my $secret = $app->secrets->[0]; | ||
my $moniker = $app->moniker; | ||
|
||
Carp::croak 'Your secret passphrase must be changed to set session data (see FAQ for more)' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think these secrets are "passphrase"s (and the FAQ doesn't call them that either)
my $moniker = $app->moniker; | ||
|
||
Carp::croak 'Your secret passphrase must be changed to set signed cookies (see FAQ for more)' | ||
if !$ENV{MOJO_ALLOW_INSECURE_SECRET} and (!length $secret or $secret eq $moniker); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to move this check into $app->session
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no session
method for Mojolicious; that would be calling the session
helper, which just forwards to the session
method on the controller which is handled above (albeit with some issues as described in the initial comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, sorry, github threw away my comment, and i crankly re-typed it wrong.
I mean should it be in $app->secrets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That attribute may be accessed by applications that don't actually do anything with it, such as Mojolicious::Plugin::Mount. But perhaps we can work around that more easily than the problems with this approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces stricter checks to prevent the setting of signed or encrypted cookies when using insecure application secrets by comparing the secret with the application moniker. It also updates several test applications to use dynamically generated secrets.
- Updates tests in multiple files to use generate_secret for secure default secrets.
- Adds runtime checks in the Controller methods (encrypted_cookie, session, signed_cookie) to enforce secret validation.
- Enhances documentation to clearly indicate the security requirement and the bypass option.
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
t/mojolicious/validation_lite_app.t | Updated to use generate_secret for secure defaults |
t/mojolicious/session_lite_app.t | Added subtests for insecure secret handling in session contexts |
t/mojolicious/rebased_lite_app.t | Updated to use generate_secret for secure defaults |
t/mojolicious/longpolling_lite_app.t | Updated to use generate_secret for secure defaults |
t/mojolicious/embedded_lite_app.t | Updated to use generate_secret for secure defaults |
t/mojolicious/app.t | Updated to use generate_secret for secure defaults |
lib/Mojolicious/Controller.pm | Added security checks and documentation updates in cookie methods |
Comments suppressed due to low confidence (1)
lib/Mojolicious/Controller.pm:63
- [nitpick] Consider refactoring the duplicate insecure-secret checks (found in encrypted_cookie, session, and signed_cookie methods) into a common helper function to improve maintainability and reduce redundancy.
Carp::croak 'Your secret passphrase must be changed to set encrypted cookies (see FAQ for more)' if !$ENV{MOJO_ALLOW_INSECURE_SECRET} and (!length $secret or $secret eq $moniker);
my $session = $stash->{'mojo.session'} //= {}; | ||
|
||
# Require changed secret if session data will be set | ||
my $set_operation = !!(@_ > 1 || ref $_[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The use of double negation (!!) can reduce readability; consider using an explicit boolean expression to check for a set operation.
my $set_operation = !!(@_ > 1 || ref $_[0]); | |
my $set_operation = (@_ > 1 || ref $_[0]) ? 1 : 0; |
Copilot uses AI. Check for mistakes.
subtest 'Insecure secret' => sub { | ||
subtest 'Insecure secret (signed cookie)' => sub { | ||
$t->reset_session; | ||
$t->app->secrets([app->moniker]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] For clarity and consistency with other parts of the code, consider using $t->app->moniker instead of app->moniker when setting insecure secrets in tests.
$t->app->secrets([app->moniker]); | |
$t->app->secrets([$t->app->moniker]); |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is actually good!
Summary
Rough attempt at taking the approach of dying if encrypted or signed cookies are requested to be set but the application secret is still set to the default of the application moniker.
This is fairly straightforward to do in the signed_cookie and encrypted_cookie methods, but this also requires a check in the session method, because setting the session cookie occurs too late to error out sensibly.
I'm not satisfied with this check in the session method, because: there still may be instances where this session method is called while a response is already being rendered; and session data can be set by assigning to
$c->session->{foo}
and there's no way to know that will happen at this juncture.Additionally, this check does not help cases where the secret has been set to a value that is also insecure but is not the current application's moniker, such as with Mojolicious::Plugin::Mount.
I am not sure if these issues can be solved, but wanted to put this idea into practice for others to review.
This also affects use of features using the session implicitly, such as the flash and csrf_token default helpers.
The
MOJO_ALLOW_INSECURE_SECRET
env variable is provided as a bypass option for applications that can't be made secure for whatever reason.Motivation
The risk of insecure secrets being used in applications using signed or encrypted cookies is not sufficiently mitigated by the annoying warning in the logs. But we don't want to cause applications to fail if they are not using these features.
References
Implements a part of #2200 by refusing to set signed or encrypted cookies by default unless the secret has been changed from the default.