-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Allow displaying SVG images securely in gr.Image
and gr.Gallery
components
#10269
base: main
Are you sure you want to change the base?
Conversation
🪼 branch checks and previews
Install Gradio from this PR pip install https://gradio-pypi-previews.s3.amazonaws.com/4984ba1b66eb06d778db3417f7e3ee9e66c1137d/gradio-5.9.1-py3-none-any.whl Install Gradio Python Client from this PR pip install "gradio-client @ git+https://github.com/gradio-app/gradio@4984ba1b66eb06d778db3417f7e3ee9e66c1137d#subdirectory=client/python" Install Gradio JS Client from this PR npm install https://gradio-npm-previews.s3.amazonaws.com/4984ba1b66eb06d778db3417f7e3ee9e66c1137d/gradio-client-1.8.0.tgz Use Lite from this PR <script type="module" src="https://gradio-lite-previews.s3.amazonaws.com/4984ba1b66eb06d778db3417f7e3ee9e66c1137d/dist/lite.js""></script> |
🦄 change detectedThis Pull Request includes changes to the following packages.
With the following changelog entry.
Maintainers or the PR author can modify the PR title to modify this entry.
|
gr.Image
component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small thing to make sure sanitization works in SSR and CSR,
js/image/shared/Image.svelte
Outdated
@@ -1,5 +1,6 @@ | |||
<script lang="ts"> | |||
import type { HTMLImgAttributes } from "svelte/elements"; | |||
import DOMPurify from "dompurify"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have our own special sanitizer package that works in both server and client environments. See import here: https://github.com/gradio-app/gradio/blob/main/js/markdown-code/MarkdownCode.svelte#L6.
We need to
import { sanitize } from "@gradio/sanitize";
You can see the usage here:https://github.com/gradio-app/gradio/blob/main/js/markdown-code/MarkdownCode.svelte#L62
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @pngwn I'll switch to that. We use dompurify directly here:
import DOMPurify from "dompurify"; |
Does this need to be switched out too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we should for consistency, although its less problematic in that case because we only launch toasts on the client.
Ok finally have a relatively clean solution. The basic idea is that for SVG files, we set the FileData.url attribute to be the actual SVG code instead of the URL. This allows SVGs to get rendered securely inside of the Tested and works both in SSR and SPA modes, with both kinds of demos: import gradio as gr
def image_mod(image):
return image
demo = gr.Interface(
image_mod,
gr.Image(type="filepath"),
"image",
)
if __name__ == "__main__":
demo.launch() import gradio as gr
with gr.Blocks() as demo:
gr.Image("test.svg")
demo.launch(ssr_mode=True) |
Yes if you have an Image input you need to set type=filepath to support SVGs as the docs mention. See my example above |
thanks for the quick fix! looks like the same have to be put on Gr.Gallery as well? |
ah yes thank you, I'll fix that |
Fixed for import gradio as gr
def test(x):
return x
gr.Interface(test, "gallery", "gallery").launch() |
gr.Image
componentgr.Image
and gr.Gallery
components
Hmm can't reproduce this. Are you sure you've pulled the latest and built the frontend? |
Previously, we disabled displaying SVG images in
gr.Image
by using the content_disposition_type = "attachment" header. Now, SVG images will be displayed in the both thegr.Image
input and output components, as can be verified by a simple demo:We should think through the security implications of this PR. In order to make this PR work, we need to dump the SVG contents inline instead of using the<img>
tag (since the<img>
tag will not display the image if the content disposition is "attachment"). (And we should keep the content disposition as is because it affects many other things e.g. what happens if a user directly pastes the SVG url in their browser). In order to provide a good experience to to Gradio users and dipslay the image preview, this PR dumps the svg contents inline, but this should be secure because we sanitize ths SVG contents first.Closes: #10261