Skip to content
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

Add input validation for Activation Code and Document Number #415

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

tvdijen
Copy link
Contributor

@tvdijen tvdijen commented Jan 4, 2024

This PR:

  • Restricts document numbers to 6 characters, being A-Z, 0-9 or a hyphen
  • Restricts activation codes to 8 characters, being A-Z or 0-9
  • Replaces test-values with 'real-life' values instead of 'dumb' dummy-values like 'REGCODE'

Debatable:

  • The value for an 'unknown' document was a non-default character (I think it's an 'En Dash' from Extended ASCII table No. 150), but I couldn't get the regexp to match it. Since it really doesn't seem to represent anything (seems to be stored as NULL in the database), I've changed the code to accept null for unknown documents.
  • Should we accept anything other than A-Z + 0-9 for document numbers anyway? The dialog asks the RA for the last 'six characters'. We may want to disregard any hyphen or other special characters.

Related: OpenConext/Stepup-RA#310

P.S.: There is a warning about an undefined method in the tests that is unrelated to this PR, but may need fixing by the maintainers. Should the code say RecoveryTokenStatus::active instead?

Copy link
Member

@MKodde MKodde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Tim, I'm a bit late with reviewing this code. I'm about to start upgrading MW to SF6.4 so I wanted to clear as many PR's as possible before having at that.

I'm not comfortable at merging your PR at this stage. I/We need to do some thorough testing and impact analysis before we can go ahead with this.

For now I did leave you some code review pointers. And be aware that I'm going to upgrade the MW. This includes removing the develop branch and renaming master -> main. So be aware of that too.

) {
if (!is_string($registrationCode)) {
throw InvalidArgumentException::invalidType('string', 'registrationCode', $registrationCode);
if (!preg_match('/^[A-Z0-9]{8}$/i', $registrationCode)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love to have a more specific input validation here. It might be a good idea to introduce a registration code value object that is tasked with validating the code? That's more in line with the way the domain is set up. For now we kept it primitive because we did not realy bother with elaborate validation.

Copy link
Contributor Author

@tvdijen tvdijen Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to go the extra mile, then please be my guest. I'm not going to solve the world's problems here, just the ones reported by our auditor ;)
Also not sure what you mean with 'more specific'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I think it's just a first guard on "sane" input as a defense-in-depth: does this even look like a registration code? The actual validity of the given code will be verified later obviously. So I can imagine that it's just fine to do the basic check that Tim implemented.

{
return new self('—');
return new self(null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this not cause problems when an identitie is forgotten (right to be forgotten) and the entry pops up in the audit log? The value that is set for an unknown document number is displayed then and there in the audit log.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really beyond my understanding... If you can get the regexp to work with this 'funny' character, we can leave this 'as-is'...

{
if (!is_string($documentNumber) || empty($documentNumber)) {
if ($documentNumber === null) {
// Created using the static ::unknown method
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some work remains to be done here, also see my previous comment about a forgotten Identity.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a defense in depth measure. Since we do not know what the format is of the document numbers – these are whatever the issuer decided to put on the document – retroactively setting a limit in the middleware in this way can cause issues when there are existing document numbers in the event stream that do not validate anymore. Limiting what is allowed in is fine, but this should be done on entry. We could do this in the middleware, but as a defense in depth it is best placed in the RA when the form post is received, not in the middleware.

SInce we do generate the activation codes, we know exactly what they look like so we could validate them in the middleware without additional risk.

Copy link
Contributor Author

@tvdijen tvdijen Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did that at first, but Peter didn't want it there :-/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants