question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow HTML (again!) in st.write/st.markdown — but with kwarg toggle

See original GitHub issue

Until last week, st.write and st.markdown used to allow HTML tags. However this is a security risk, as an app author could write unsafe code like this:

import streamlit as st

USER_INPUT = '''
<input type="button" value="click me" onclick="javascript:alert('You have been pwnd. Now I can steal your cookies')"/>
'''

name = st.text_input("What's your name?", USER_INPUT)
st.write(name)

…which is why we turned it off in #95 .

However, many users still depend on this feature, and we’d would like to (1) not break those users and (2) understand why they need HTML so we can come up with better solutions.

So let’s do this for now:

  • Keep the default behavior of st.write and st.markdown as: no HTML is allowed
  • However, allow the user to pass unsafe_allow_html=True to turn on support for HTML

Also, in the pydoc for st.write and st.markdown we should say the following:

While you can use unsafe_allow_html=True to turn on support for a limited set of HTML tags inside markdown strings, we strongly advise against it. It is hard to write secure HTML, so by using this argument you may be compromising your users’ security. See this Github issue for more information.

Also note that unsafe_allow_html is a temporary measure and may be removed from Streamlit any time.

If you decide to turn on HTML anyway, we ask you to please post in this [this Github issue](ASK THIAGO FOR LINK) telling us your exact use case. This will help us come up with safe APIs that allow you to do what you want.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:4
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

28reactions
markopycommented, Oct 15, 2019

I’m commenting on this issue despite it being closed because it seems the security implications of allowing HTML have been misunderstood. Specifically the “Now I can steal your cookies” part is very far fetched.

Any injected javascript will only have access to cookies set against the origin the streamlit page is served from. By definition the author of the app already has access to these cookies because they are the one running the server (if it’s hosted) or the origin is likely localhost if a user is running the app on their machine. In neither case are any valuable cookies exposed. In fact in the later case the author can just use python code to grab all of the user’s cookies from their browser’s file system store, a much more powerful attack.

It is also important to realize that, because the app author has full control over the python side of things, they can at any time serve arbitrary javascript to any user of the app. There is no way to protect against a malicious app author! The only thing you can hope to protect users against is an incompetent app author who ingests data from an untrusted source and doesn’t properly sanitize it.

In order for this to be a danger someone would have to run a streamlit app and deploy it on a domain which has valuable cookies to steal. Then the author of the app or somebody managing to inject data the author hasn’t escape properly will be able to steal cookies from that domain only.

However this could be mitigated in several ways without removing support for HTML. One is to make the streamlit server send a Content Security Policy that blocks inline scripting and all domains not localhost. It can even block segment.com if the user disabled being tracked in the config. It would also force you to include leaflet.js and not fetch it from unpkg.com which is odd anyway.

Another option is to put markdown/html into an iframe which is sandboxed and disallows all javascript execution. This would work if the html is meant purely for display and doesn’t need to be part of the rest of the page.

Removing the ability for app writers to inject HTML (or even script code) seems like a short sighted and very limiting move. It should be disabled by default, but you will never be able to provide all the features people will want and using custom HTML will provide an escape hatch for experienced developers.

16reactions
4ijicommented, Oct 18, 2019

Still very new to streamlit & very curious to see if there are other ways to achieve this.

I want to use HTML to a) show links to pictures inside dataframes as actual pictures, b) display links in a clickable format

Read more comments on GitHub >

github_iconTop Results From Across the Web

3 Tips to Customize your Streamlit App - Python in Plain English
Snippets to add @st.cache decorator before a defined function: ... Allow HTML (again!) in st.write/st.markdown — but with kwarg toggle ...
Read more >
How can I wrap my markdown in an HTML div? - Stack Overflow
E.g., you can't use Markdown-style emphasis inside an HTML block. But it is explicitly allowed for span-level tags: Unlike block-level HTML tags, Markdown...
Read more >
nbconvert Documentation - Read the Docs
Primarily, the nbconvert tool allows you to convert a Jupyter .ipynb notebook document file into another static format including HTML, LaTeX ...
Read more >
Changelog - Doxygen Manual
Write directory dependency graphs recursively. · Added missing symbols needed to enable SANITIZE_UNDEFINED [view] · Add the xml output format to the image...
Read more >
GitLab Flavored Markdown (GLFM)
The HTML content displays after the front matter. To view an example, you can toggle between the source and rendered version of a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found