duo-labs / py_webauthn

Pythonic WebAuthn 🐍
https://duo-labs.github.io/py_webauthn
BSD 3-Clause "New" or "Revised" License
856 stars 171 forks source link

flask demo: webauthn origin mismatch #73

Closed gradyy closed 3 years ago

gradyy commented 4 years ago

Starting the flask server at '0.0.0.0' causes an origin mismatch for some browsers. Though 'https://0.0.0.0:5000' and 'https://localhost:5000' are both ways to navigate to the same server, the browser may treat these as separate origins and disallow webauthn operations. This change ensures that the flask server's hostname matches the expected origin of the webauthn credential. This change also enables the server to run on a different port.

This commit requires testing on more browsers.

The choice to build the origin string from the host and port vs. parsing the host and port out of a complete origin string was arbitrary.

nickmooney commented 4 years ago

Thanks for this PR, @gradyy! I worry about binding these too closely. I am imagining the situation where I want to set up a staging server for example.com through a proxy frontend -- the call to app.run would fail to bind.

Were you running into this issue in a specific set of circumstances? Maybe binding directly to localhost is the right move, or just having two separate config variables...

gradyy commented 4 years ago

The Flask startup message displays the url of the arguments to app.run, in this case 'https://0.0.0.0:5000'. My browser treats 'https://0.0.0.0:5000' as an context for the origin of 'https://localhost:5000' and raises an exception for webauthn operations. This mismatch has the potential to cause a lot of confusion. There is no indication that the user must browse to the server from a different address.

I can't think of any reason why this demo must call app.run specifically with host='0.0.0.0' so I don't expect this change to cause any new problems. However, I haven't thoroughly tested how this affects other browsers and platforms. Should I open an issue to request help with the testing?

You bring up a valid point with the proxy frontend. This PR might incorrectly imply that the origin must be 'https://localhost:5000' when the Flask server is running at 'localhost'. However, the demo could be set up at 'example.com' with an origin of 'https://example.com' while the Flask server is still running at 'localhost' for the server at 'example.com'.

The string formatting might be 'too clever' in this instance. Having the host, port, and origin as independent variables might set a clearer example. Another approach may be to add a comment to explain how the origin matches the host and the port for this particular instance but could be an arbitrary address.

CLAassistant commented 3 years ago

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.