-
Notifications
You must be signed in to change notification settings - Fork 439
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
Fix AdminGroupSchema
CSRF protection
#9333
Conversation
Doing `super().__init__(validator=username_validator)` overrides the Colander schema's global validator function, with the result that the base `CSRFSchema` class's `validator()` method never gets called and there is no CSRF protection. Replace this with a subclass `validator()` method that calls the superclass's method first.
AdminGroupSchema
CSRF protection
@@ -139,7 +139,7 @@ def group_organization_select_widget(_node, kwargs): | |||
|
|||
class AdminGroupSchema(CSRFSchema): | |||
def __init__(self, *args): | |||
super().__init__(validator=username_validator, *args) # noqa: B026 | |||
super().__init__(*args) |
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 *args
looks like it's unused: we never instantiate AdminGroupSchema()
with any arguments. But in fact Colander itself does instantiate further AdminGroupSchema
instances for us, with arguments.
def test_it_raises_if_csrf_token_missing(self, group_data, bound_schema): | ||
del bound_schema.bindings["request"].headers["X-CSRF-Token"] | ||
|
||
with pytest.raises(BadCSRFToken): | ||
bound_schema.deserialize(group_data) | ||
|
||
def test_it_raises_if_csrf_token_wrong(self, group_data, bound_schema): | ||
bound_schema.bindings["request"].headers["X-CSRF-Token"] = "foobar" | ||
|
||
with pytest.raises(BadCSRFToken): | ||
bound_schema.deserialize(group_data) |
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.
By default Pyramid will read the CSRF token from either a csrf_token
form field or an X-CSRF-Token
header. In practice our pages use the form field. But our tests use the header (via the pyramid_csrf_request
fixture).
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.
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
Comments suppressed due to low confidence (1)
tests/unit/h/schemas/forms/admin/group_test.py:27
- Add a test case to ensure that the
username_validator
is called in thevalidator
method.
def test_it_raises_if_csrf_token_wrong(self, group_data, bound_schema):
Doing
super().__init__(validator=username_validator)
overrides the Colander schema's global validator function, with the result that the baseCSRFSchema
class'svalidator()
method never gets called and there is no CSRF protection.Replace this with a subclass
validator()
method that calls the superclass's method first.This is the same way as it's done in several other
CSRFSchema
subclasses throughout the code.Testing
"csrf_token"
form fieldOn
main
the form submission will succeed with no CSRF token. On this branch it'll fail.