Mohamed-512 / Extra-Streamlit-Components

An all in one place, to find complex or just not available components by default on streamlit.
Apache License 2.0
466 stars 59 forks source link

Is the cookiemanager safe enough to be deployed in production? #49

Open NoNeuronsNoStress opened 1 year ago

NoNeuronsNoStress commented 1 year ago

hey @Mohamed-512
I just built an app, that needs users to authenticate, obviously i want to make this process as safe as possible. You mention in the README the following: Security Note: In shared domains such as share.streamlit.io, other web developers can have access to the cookies you set and the same goes for you. This is not to be treaded as security bug but a circumstance the developer need to be aware of.

I wanted to store permissions for the user & the current user in the cookies. Could this lead to vulnerabilities, where users try to overwrite whatever is in their cookie ? I'm not a web dev, this might be totally incorrect, thats why I'm asking for help.

CHerSun commented 1 year ago

I'm not the author, but my 2 cents:

NoNeuronsNoStress commented 1 year ago

@CHerSun Thanks for the quick reply. I will try to implement that tomorrow, just to see how it works. However if the cookies aren't a good place for this, then how should I fix it ? I mean I don't want the users to log in every time they go on a different page inside the application ?! Streamlit session state also gets removed once the user refreshes / goes on a different page.

CHerSun commented 1 year ago

Well, that really depends on your decisions on how to make that.

In my case I'm using SSO (Keycloak) for auth. Once I do have auth - I generate a random token (well, a session) on my side and store it in local DB on server side and in encrypted cookies on user side. On any refresh / action - I check the token from user's cookies. If it's too old or unknown - send the user to login page. I'm not using multipages in streamlit, as I need to dynamically control what user sees.

btw, that's not really required if you use only SSO (I also have local login + roles caching and views caching not to render everything from scratch), as SSO knows how to generate session tokens, refresh them, etc, so you don't really need to worry about that normally, that's handled on JS side.

Yanni8 commented 8 months ago
  • there's another cookies project for shared environments - streamlit cookies manager. It uses encrypted cookies to allow rather safe usage. It's outdated, but only needs a line or 2 to patch (streamlit cache was changed meanwhile)

@CHerSun can you share the link?

CHerSun commented 8 months ago
  • there's another cookies project for shared environments - streamlit cookies manager. It uses encrypted cookies to allow rather safe usage. It's outdated, but only needs a line or 2 to patch (streamlit cache was changed meanwhile)

@CHerSun can you share the link?

@Yanni8 https://pypi.org/project/streamlit-cookies-manager/

it wasn't updated since Streamlit v 1.18, when streamlit changed caching from @st.cache to @st.cache_data. That's the only line you need to patch really. Everything else works perfectly fine.

That one supports prefixes (to be able to have individual cookies in shared environments; set this to something unique, like your project_instance or something), supports encryption (shared environments again and some degree of safety; remember to set your own token; I prefer to generate a strong one on first run and save that locally to .env - for the ability to change if needed).

It has a good example, which actually covers everything one needs.

Mohamed-512 commented 6 months ago

Hey @NoNeuronsNoStress, as a web developer you shouldn't worry about users tampering with their own cookies, it's built for it to be modified from client side, and you should alway do any sort of validation on the backend, as there are other reasons that could change data coming from the user but before reaching the server.

Based on my note on the package, what you should worry about is using it on shared domains, where more than one developer control code on the same domain name i.e. share.streamlit.io. If developer X makes a website and hosts it there, an uses this or a similar package, they can get all cookies set for the user on the same domain name. Which could have been set on a different project by developer Y.

Also, cookies can have sensitive data such as access tokens or JWTs. It's normal. Encryption won't add any additional layer of security as it could be still grabbed and sent with a plain HTTP request, by the user. But in case you host a sensitive key/information in the cookie on share.streamlit.io, then any other developer can see it if the user access their project.

Odrec commented 6 months ago
  • there's another cookies project for shared environments - streamlit cookies manager. It uses encrypted cookies to allow rather safe usage. It's outdated, but only needs a line or 2 to patch (streamlit cache was changed meanwhile)

@CHerSun can you share the link?

@Yanni8 https://pypi.org/project/streamlit-cookies-manager/

it wasn't updated since Streamlit v 1.18, when streamlit changed caching from @st.cache to @st.cache_data. That's the only line you need to patch really. Everything else works perfectly fine.

That one supports prefixes (to be able to have individual cookies in shared environments; set this to something unique, like your project_instance or something), supports encryption (shared environments again and some degree of safety; remember to set your own token; I prefer to generate a strong one on first run and save that locally to .env - for the ability to change if needed).

It has a good example, which actually covers everything one needs.

There's a patched version of this already: https://github.com/ktosiek/streamlit-cookies-manager/commit/6bf9704f0813f69bc770da2192bd718749ae2d4b

Just do pip install streamlit-cookies-manager-hotpatched

and then you don't have to change any code manually. The only issue I have with this package is that deleting cookies doesn't work.

CHerSun commented 6 months ago

Hey @NoNeuronsNoStress, as a web developer you shouldn't worry about users tampering with their own cookies, it's built for it to be modified from client side, and you should alway do any sort of validation on the backend, as there are other reasons that could change data coming from the user but before reaching the server.

Based on my note on the package, what you should worry about is using it on shared domains, where more than one developer control code on the same domain name i.e. share.streamlit.io. If developer X makes a website and hosts it there, an uses this or a similar package, they can get all cookies set for the user on the same domain name. Which could have been set on a different project by developer Y.

Also, cookies can have sensitive data such as access tokens or JWTs. It's normal. Encryption won't add any additional layer of security as it could be still grabbed and sent with a plain HTTP request, by the user. But in case you host a sensitive key/information in the cookie on share.streamlit.io, then any other developer can see it if the user access their project.

Sorry, but your answer is strange. You first post, that user can tamper with cookies from their side, and then you suggest not to worry about that.

Original question was if permissions could be stored inside cookies. NO, they cannot, as user can easily tamper with that, gaining permissions easily. That's not how permissions should be managed for sure.

JWT argument is invalid here, as JWT is normally at least signed and vaildated against IdM authority from back-end. It is indeed sensitive, but only if it's leaked to another user (or not validated against IdM properly).

Counter-encryption argument is strange as well. Encryption of cookies is managed on back-end in this case (in Streamlit-ran code). So encryption is not reversible by end user, unless they know the token used (which shouldn't be exposed ofc). So it's a way to prevent user tampering with the data + the way to operate in shared environment without other apps freely reading sensitive data (especially true for the Streamlit cloud, where other apps are NOT related to you).

CHerSun commented 6 months ago

@Odrec thank you, didn't know about that. I was just sed-hot-patching original package in Dockerfile.

And yeah, cookies deletion isn't working there, but could always write some garbage.