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
Have I Been Pwned Integration (Password security enhancements) #832 #974
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #974 +/- ##
=============================================
- Coverage 67.76% 67.64% -0.13%
- Complexity 1997 2021 +24
=============================================
Files 169 171 +2
Lines 6995 7086 +91
=============================================
+ Hits 4740 4793 +53
- Misses 2255 2293 +38
Continue to review full report at Codecov.
|
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.
The controller is really long... While having private function in the controller is not wrong, I think it would make more sense to put both checkPassword
and checkHash
in a separate (static) class? Would make easier to use those methods elsewhere as well as writing proper tests.
I thought they would probably need to be moved. I will need some guidance on where to move them to... |
Move checkHash and checkPassword
Looks like there are some changes on master that aren't on develop. Probably want to sync it up. Would make the diff clearer. |
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.
Few things to be addressed here. There will likely need to be some discussion in most areas first though.
Add `passwordSecurity` as to `ServicesProviders`
Refactor
Add passwordSecurity service.
Add `cache` and `breaches` options to `enforce_no_compromised`
Add PasswordSecurity as a service
Reorganize to align with contributing style guide
Good catch! This is because the |
Edit a few comments
I believe this is ready for another review. |
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.
A few issues, but the core logic looks good. I haven't tested it this time however.
* | ||
* @return array Array of password hashes in the format c2d18a7d49b0d4260769eb03d027066d29a:181 - or <hash>:<number of breaches. | ||
*/ | ||
private function getHashArrayFromAPI($hashPrefix) |
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.
How would this handle connectivity issues/outage of the HIBP Passwords API? It looks like there isn't any handling for it, potentially it would prevent login.
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.
You're right.
I'll think about the best way to handle this. We probably want to try to query HIBP at least a few times before allowing user to login and bypass the check...
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.
Got to be careful with retry logic. At scale, it can translate to a massive spike in requests for an API.
Possible scenarios include;
- API returns 500 error due to a fault, could be an edge case or everything, retry logic here would easily result in a larger number of requests (CloudFlare wouldn't cache these either, so it would fairly consistently hit the function itself until potentially DDoS protection gets triggered).
- Response codes indicate that retries should not be attempted exist, we would be wasting our own time retrying these.
- Connection timeouts could be attributed to failures anywhere along the connection (local misconfiguration, API hit its own response timeout and terminated).
- Deliberate rate limiting by HIBP (if a UF site were to become heavily used, we could end up hitting this)
Ultimately, it may come down to not retrying at all and logging that the check failed. HIBP passwords should be supplemental to the security such that any UF site doesn't get busted by any issues.
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've tried to fix this in the recent commits. (Also switched over to Guzzle)
app/sprinkles/account/src/Database/Migrations/v430/AddPasswordRestColumnUsersTable.php
Outdated
Show resolved
Hide resolved
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static $dependencies = [ |
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.
Could we use reflection here? E.g;
use \UserFrosting\Sprinkle\Account\Database\Migrations\v400\GroupsTable`;
...
public static $dependencies = [
GroupsTable::class,
...
];
I generally prefer to have source level references where possible as it makes tracking down references later, and performing refactors (with tooling assistance) much quicker.
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 think we could. If this is the preference I should probably update the other two "modifying" migrations in 4.3
.
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.
@lcharette Should I change this and the other migrations that were already merged?
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. Both will work, but reflection is easier to work with in IDE
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.
It seems a leading \
is being added somewhere inside the migrator
.
[ERROR] Unfulfillable migrations found ::
=> \UserFrosting\Sprinkle\Account\Database\Migrations\v430\AddPasswordResetColumnUsersTable (Missing dependency
: UserFrosting\Sprinkle\Account\Database\Migrations\v400\GroupsTable)
Some changes will likely need to be made in the migrator if we want to make this work. Unless we want to try to make those changes for 4.3
, should probably just hold off on this for now.
app/sprinkles/account/src/Database/Migrations/v430/AddPasswordRestColumnUsersTable.php
Outdated
Show resolved
Hide resolved
@@ -33,7 +33,9 @@ class PasswordResetRepository extends TokenRepository | |||
protected function updateUser(UserInterface $user, $args) | |||
{ | |||
$user->password = Password::hash($args['password']); | |||
$user->flag_password_reset_required = false; | |||
// TODO: generate user activity? or do this in controller? |
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.
Technically outside scope of this, but does this have an answer yet? Are we logging updates to the user at all?
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.
It doesn't look like it is happening in controller or here, so I would say no.
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.
It would make sense to log some type of message "User set a new password".
Then the controller would be responsible for logging activity messages related to why a user needs to reset their password. (like HIBP, admin forcing reset, etc..)
Still need to add where to log messages to
Add typecasts
FYI, I tagged this to 4.4.x as I think it will require more testing from both @Silic0nS0ldier and I. |
As can be seen, I'm trying to resurrect this PR nearly 2 years on. Its been synced with master and had some issues resolved (mainly PHP crashes relating to recently completed deprecations and type violations). |
Closing this, as it need to be updated for UF5. It should be implement as it's own sprinkle anyway. |
This will need more work but I feel is at a place to open up for some feedback.
The proposed feature adds two additional
config
values undersite.password_security
.(I am open to suggestions on the naming convention for these).