jupyterhub / ltiauthenticator

A JupyterHub authenticator for LTI
https://ltiauthenticator.readthedocs.io
BSD 3-Clause "New" or "Revised" License
68 stars 54 forks source link

"403 : Forbidden '_xsrf' argument missing from POST" with JupyterHub 4.0.0 #157

Closed regisb closed 1 year ago

regisb commented 1 year ago

Bug description

When running the latest JupyterHub 4.0.0, LTIAuthenticator fails with the following error "403 : Forbidden '_xsrf' argument missing from POST":

Screenshot from 2023-05-09 10-05-05

This error does not occur with JupyterHub 3.1.1.

I only tested this behaviour with LTI 1.1 but I suspect the same error will occur on LTI 1.3.

This error occurs because JupyterHub 4.0.0 examines cross-site request forgery (XSRF) parameters to make sure that requests are not emitted from a rogue website.

I was able to fix this issue by adding the following dummy XSRF validation method to LTI11AuthenticateHandler:

class LTI11AuthenticateHandler(BaseHandler):
    ...

    def check_xsrf_cookie(self):
        return

Alternatively, I believer that the handler could append an _xsrf parameter to all POST requests, based on the value of the _xsrf cookie. I do not have a proof-of-concept for that solution.

Expected behaviour

The notebook should display successfully.

Actual behaviour

The notebook does not load at all.

How to reproduce

See my personal set up below. I have all reasons to believe that this bug will occur on just any LMS, either with LTI 1.1 or 1.3.

Your personal set up

I am integrating JupyterHub with Open edX, using this jupyter-xblock.

welcome[bot] commented 1 year ago

Thank you for opening your first issue in this project! Engagement like this is essential for open source projects! :hugs:
If you haven't done so already, check out Jupyter's Code of Conduct. Also, please try to follow the issue template as it helps other other community members to contribute more effectively. welcome You can meet the other Jovyans by joining our Discourse forum. There is also an intro thread there where you can stop by and say Hi! :wave:
Welcome to the Jupyter community! :tada:

martinclaus commented 1 year ago

Hi @regisb, thank you for reporting this issue!

It seems to be related to https://github.com/jupyterhub/jupyterhub/pull/4032 (cc @minrk). I am suspecting that the problem is related to running Jupyterhub embedded within edX, but need to test this first.

regisb commented 1 year ago

Thanks for the quick response!

I am suspecting that the problem is related to running Jupyterhub embedded within edX

I'm not sure what this means :-/ I'm running JupyterHub in a separate container. JupyterHub is gated by LTIAuthenticator, which does not receive any _xsrf parameter during POST because... well LTI components are pretty generic and blissfully unaware of the need to pass an _xsrf parameter in POST requests. Note that the patch above to LTI11AuthenticateHandler does resolve the issue.

martinclaus commented 1 year ago

I'm not sure what this means :-/

From looking at https://raw.githubusercontent.com/overhangio/jupyter-xblock/main/screenshots/lms.png, it seems that jupyterhub / jupyterlab are embedded into the Open edX UI via and iframe or similar.

It would be great if you could provide log output from Jupyterhub with debugging enabled to see where things go wrong.

regisb commented 1 year ago

Yes, in the screenshot JupyterHub is embedded in an iframe, but the error also occurs when JupyterHub is accessed from a separate tab.

This is what I'm getting from the jupyterhub logs:

tutor_local-jupyterhub-1  | [W 2023-05-09 13:12:17.479 JupyterHub web:1852] 403 POST /hub/lti/launch (172.18.0.9): '_xsrf' argument missing from POST
tutor_local-jupyterhub-1  | [D 2023-05-09 13:12:17.480 JupyterHub base:1369] No template for 403
tutor_local-jupyterhub-1  | [W 2023-05-09 13:12:17.551 JupyterHub log:191] 403 POST /hub/lti/launch (@172.18.0.9) 76.44ms
regisb commented 1 year ago

If my theory is correct, then it is impossible to get ltiauthenticator to work with LTI 1.1 and Jupyter 4.0.0. Has someone achieved this yet?

minrk commented 1 year ago

I don't fully follow the LTI implicit flow, but if the POST is coming from an LTI service, then disabling the xsrf check is fine. The xsrf check blocks cross-site requests, so if a request is expected to be cross-site, explicitly disabling the check on this handler is the right thing to do.

regisb commented 1 year ago

I agree. Should I open a PR?

martinclaus commented 1 year ago

Yes, a PR would be great. Since the issue is with requests from other sites I expect the handler for LTI 1.3 to be affected too, but I will take care about that.

sean-morris commented 1 year ago

Thank you for documenting and providing a fix to this problem. I have run into the same issue with courses using JupyterHub in EdX.

regisb commented 1 year ago

Hi @sean-morris! I'd be curious to hear how you integrate Open edX and JupyterHub, as I recently created the following projects: https://github.com/overhangio/tutor-jupyter https://github.com/overhangio/jupyter-xblock/ Feel free to reach out by email :)

And sorry for going off-topic in this thread!

minrk commented 1 year ago

We've published jupyterhub-ltiauthenticator 1.5.1 with the fix in #158