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

Implement endpoint csrf protection #2057

Merged
merged 125 commits into from
May 2, 2019

Conversation

martijn-tao
Copy link
Contributor

@martijn-tao martijn-tao commented Mar 25, 2019

This PR now contains all the work for:
https://oat-sa.atlassian.net/browse/TAO-7304
https://oat-sa.atlassian.net/browse/TAO-7305
https://oat-sa.atlassian.net/browse/TAO-7306

Description

7304 (Backend part):

  • Added a new Token model that provides a token object
  • Token service can now generate a pool of tokens that will be used by the frontend
  • Validation of an endpoint is done by adding a try { $this->validateCsrf(); } catch(\common_exception_Unauthorized $e) { ... } block
  • CSRF tokens in forms use a hidden element. This gets added by passing [FormContainer::CSRF_PROTECTION_OPTION => true] to the form options.
  • Since the csrf for forms is added as an element, validation is part of the form validation, meaning that a simple $form->isValid() check offers protection.
  • A detailed log entry will be added if CSRF validation fails.

7305 (Frontend part):

  • added core/request module, mixing old functionality of core/dataProvider/request and qtiServiceProxy
  • converted core/dataProvider/request to thin wrapper returning the response body
  • converted taoQtiTest/runner/proxy/qtiServiceProxy to work with this
  • converted core/tokenHandler to manage a store of multiple tokens (fully async, Promise-based)
  • added core/tokenStore to encapsulate the store functionality (fully async, Promise-based)
  • used the core/store backend to ensure a single source of truth for the token pool
  • async unit tests for all these modules

7306 (Implementation in TAO):

  • Backend token pool changed to allow Instance Forms to keep their old method of protection (single token rendered by PHP as hidden input field)
  • Removed cookie-based token implementation, and switched to new core/request with tokens, for the following endpoints:
tao/Users/delete
tao/Users/lockUser
tao/Users/unlockUser
tao/RdfController/addInstance
tao/RdfController/deleteAll
tao/RdfController/deleteClass
tao/RdfController/deleteResource
taoGroups/Groups/addSubClass
taoGroups/Groups/cloneInstance
taoGroups/Groups/delete (deleteResource)
taoTestTaker/TestTaker/delete (deleteResource)
taoItems/QtiCreator/createItem

A more comprehensive view of protected forms and endpoints is being documented here:
https://docs.google.com/spreadsheets/d/1TaXQDKcemsIjbWPzCvzyLsU1_EyH8MJ3vKW_-r4iZz0

To test:

  1. Checkout all branches
  2. Use TAO BackOffice extensively, creating and deleting Items, Groups, Test-Takers, Users, etc.
  3. Try to re-run the same requests your browser is making, with old headers or removed headers
  4. Run some TAO deliveries

Related PRs:

oatymart and others added 30 commits January 11, 2019 14:48
Copy link

@codeclimate codeclimate bot left a comment

Choose a reason for hiding this comment

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

The PR diff size of 6147 lines exceeds the maximum allowed for the inline comments feature.

Copy link

@codeclimate codeclimate bot left a comment

Choose a reason for hiding this comment

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

The PR diff size of 6278 lines exceeds the maximum allowed for the inline comments feature.

Copy link

@codeclimate codeclimate bot left a comment

Choose a reason for hiding this comment

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

The PR diff size of 6278 lines exceeds the maximum allowed for the inline comments feature.

@krampstudio
Copy link
Contributor

Any reason why the HTTP response has a 412 status when the token is invalid ? I'd have expected a 403

@oatymart
Copy link
Contributor

Any reason why the HTTP response has a 412 status when the token is invalid ? I'd have expected a 403

@martijn-tao @siwane could you comment? I didn't catch the exact details of why we changed it.


/** @var TokenStore $tokenStore */
$tokenStore = $tokenService->getOption(TokenService::OPTION_STORE);
$tokenStore->removeTokens();
Copy link
Contributor

Choose a reason for hiding this comment

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

for my own understanding, what the purpose of removing the tokens during an update ?

Copy link
Contributor

@krampstudio krampstudio left a comment

Choose a reason for hiding this comment

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

Still very minor issues regarding the source code, but the overall looks very good !

I've made some testing of the back-office and the test runner which looks working as expected.
I've only encountered one issue on taoDacSimple, which is most likely related to the call of the request itself (so the error belong to that extension) : oat-sa/extension-tao-dac-simple#87 (review)

views/js/layout/actions/common.js Outdated Show resolved Hide resolved
views/js/layout/actions/common.js Outdated Show resolved Hide resolved
views/js/layout/actions/common.js Outdated Show resolved Hide resolved
@krampstudio
Copy link
Contributor

And by the way the status code 403 vs 412 should also sorted out before merging

Copy link

@codeclimate codeclimate bot left a comment

Choose a reason for hiding this comment

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

The PR diff size of 6257 lines exceeds the maximum allowed for the inline comments feature.

Copy link
Contributor

@krampstudio krampstudio left a comment

Choose a reason for hiding this comment

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

Code is ok now from my perspective.
I didn't found any other issue

@martijn-tao
Copy link
Contributor Author

And by the way the status code 403 vs 412 should also sorted out before merging

@krampstudio Done, Changed the status to 403

Copy link

@codeclimate codeclimate bot left a comment

Choose a reason for hiding this comment

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

The PR diff size of 6257 lines exceeds the maximum allowed for the inline comments feature.

Copy link

@codeclimate codeclimate bot left a comment

Choose a reason for hiding this comment

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

The PR diff size of 6257 lines exceeds the maximum allowed for the inline comments feature.

Copy link

@codeclimate codeclimate bot left a comment

Choose a reason for hiding this comment

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

The PR diff size of 6257 lines exceeds the maximum allowed for the inline comments feature.

@siwane siwane marked this pull request as ready for review May 2, 2019 12:50
@siwane siwane merged commit d657a6c into develop May 2, 2019
@siwane siwane deleted the feature/TAO-7306-Implement-endpoint-CSRF-protection branch May 2, 2019 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants