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

Remove unnecessary csrf_exempt from urls #1160

Merged
merged 2 commits into from
Apr 14, 2023

Conversation

EerikSaksi
Copy link
Contributor

Fixes #1099

Description

Properly setup exemptions for CSRF, leaving them where they are needed

Why?

CSRF exemptions are needed in some cases, this pull request removes duplicate exemptions and ensures that they are present for all views which need them.

How?
Experiment which exemptions are needed for no errors to occur.

Fixes #1099

Testing

What type of test did you run?

  • Accessibility test using the WAVE extension.
  • Django unit tests.
  • Selenium tests.
  • Other test. (Add a description below)
  • Manual testing.

Ensure there are no CSRF errors when opening an exercise as a student and when selecting an exercise as a teacher, on both localhost as well as minus.cs + mycourses-test

Did you test the changes in

  • Chrome
  • Firefox
  • This pull request cannot be tested in the browser.

Translation

Programming style

  • Did you follow our style guides?
  • Did you use Python type hinting in all functions that you added or edited? (type hints for function parameters and return values)

Have you updated the README or other relevant documentation?

  • documents inside the doc directory.
  • README.md.
  • Aplus Manual.
  • Other documentation (mention below which documentation).

Is it Done?

  • Reviewer has finished the code review
  • After the review, the developer has made changes accordingly
  • Customer/Teacher has accepted the implementation of the feature

Clean up your git commit history before submitting the pull request!

@markkuriekkinen markkuriekkinen mentioned this pull request Feb 10, 2023
17 tasks
@markkuriekkinen markkuriekkinen self-requested a review April 13, 2023 14:20
@markkuriekkinen markkuriekkinen self-assigned this Apr 13, 2023
EerikSaksi and others added 2 commits April 14, 2023 23:02
In Django's class-based views, function decorators must be used with
`method_decorator`.
https://docs.djangoproject.com/en/3.2/topics/class-based-views/intro/#decorating-the-class

Move the `csrf_exempt` for the class `LtiLaunchView` from urls.py to
the view class definition so that it is more consistent with the other
LTI Tool views. The same view also requires
the `xframe_options_exempt` decorator.

Class `LtiSessionMixin` does not need `csrf_exempt`.
Most of its child classes are able to normally check CSRF tokens
because the HTML forms are first rendered in A+.

Class `LtiExerciseView` needs both `csrf_exempt` and
`xframe_options_exempt`.

* `csrf_exempt` is needed since it is used in class `ExerciseView`
  and the exercise forms loaded from assessment services do not include
  any CSRF tokens.
* `xframe_options_exempt` is needed since LTI Tools may be embedded
  in iframes in the LTI Platform.

Fixes apluslms#1099
Copy link
Collaborator

@markkuriekkinen markkuriekkinen left a comment

Choose a reason for hiding this comment

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

The pull request was still missing a few important fixes, but I have now finished them myself so that we can merge this pull request.

Class-based views can't use function decorators directly. They need to combine the decorators with method_decorator.
https://docs.djangoproject.com/en/3.2/topics/class-based-views/intro/#decorating-in-urlconf
The old code had done this wrong with csrf_exempt and xframe_options_exempt.

The LTI login and launch views are the ones that need csrf_exempt. They receive HTTP POST requests that are not triggered by a typical form and we can't easily add any CSRF tokens there. Since the request can not include a valid CSRF token, the backend must exempt the CSRF check.

In the LTI content selection views (for LTI Deep Linking), A+ renders first normal HTML forms that include the CSRF token. The backend should then check the CSRF tokens. The old code used to exempt all views.

In local testing (under localhost with insecure HTTP protocol), we need to add CSRF_COOKIE_SAMESITE = 'None' to the A-plus Django settings. Otherwise, the browser refuses to send the CSRF cookie in the iframe used with LTI.

Class ExerciseView used in sending new submissions has always used csrf_exempt. The exercise HTML forms do not include any CSRF tokens since the forms are first fetched from the assessment service such as the MOOC-Grader. I believe that A+ could then manually insert the CSRF token to the HTML form, but this has never been implemented thus far. Therefore, class LtiExerciseView must also use csrf_exempt. Due to class inheritance and different decorators used in each class, the dispatch method is defined again in LtiExerciseView with the specific decorators used in that view.

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

Successfully merging this pull request may close these issues.

A+ as LTI Tool v1.3: properly set up CSRF tokens and do not exempt unnecessarily
2 participants