-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Gitea can't render SVG files. #1095
Comments
The problem is serving with the wrong mime type. |
Right now the mime type is read by calling http.DetectContentType. This does not support the "image/svg+xml" mime type. There was a feature request for this (golang/go#15888), but it seems they won't implement it until it is also implemented in the mimesniff spec (whatwg/mimesniff#7). mime.TypeByExtension supports "image/svg+xml" as it has ".svg" in its built-in table. https://github.com/golang/go/blob/release-branch.go1.6/src/mime/type.go#L35 |
fileType := mime.TypeByExtension(path.Ext(filePath))
if fileType == "" {
fileType = http.DetectContentType(buffer)
} It seems change the code to this will fix the bug. |
My render raw files pull request does exactly this, but tboerger seems to think it is a very big security risk. |
Hi, this is text about SVG security. Don't worry, GitHub could do it, so can we! First make sure that we set a good headers safety. The basic HTTP response headers with the SVG file will be:
In addition, the magazine SVG files could be transferred to a separate domain or subdomain that does not require authentication even through mechanisms such as cookies (files can be referenced eg. The GUID, you should also add .svg extension to file names). In such a situation, a successful XSS attack will be much less of a threat. Then, set up a very strict policy Content Security Policy (CSP) - whether it is for a script that returns the content of vector graphics, or the server that serves SVG files from the directory. Setting the CSP value such as Content-Security-Policy: script-src 'none' turns off the ability to execute scripts for the document (ie malicious graphics, SVG). SVG files can also be processed on the server and convert to safer raster image formats (eg. PNG). You can also attempt to remove potentially dangerous scripts - for this purpose can be used, eg. Utility SVG Purifier. As you can see ideas to deal with SVG format is quite a lot, but by far the best option is to use SVG files only by developers and the strict prohibition upload such documents. Say NO SVG files from an untrusted source. |
Is there any plans to add support for SVG in the near future? |
No people are working on this. |
I have reported the issue to the Gogs bug tracker, before even knowing about Gitea. |
I tried to investigate the issue. I have no solution, but some info that I hope will be helpful: SVG embedded in markdownSVG images do not display in rendered markdown. The following
is rendered as
by both Gogs and Gitea. GitHub's rendering is only slightly different: it links to the blob instead of the raw page, it has
This is consistent between the three services tested. See my test repo:
SVGs served by GitHubGitHub has a feature lacking in both Gogs and Gitea: the blob page has buttons for switching between “source blob” and “rendered blob” views, defaulting to the latter. This can be useful since, as stated above, the raw page does not render the image in-browser. The implementation, however, seems quite complex. The “rendered blob” view uses an iframe pointing to render.githubusercontent.com. This iframe uses JavaScript to generate an When serving SVG from raw URLs, GitHub issues a 302 redirect to raw.githubusercontent.com. Following the redirect, the SVG is served with what looks like a lot of security-related headers:
Embedding SVGs containing JavaScriptTesting with my local Web server, I found that neither Firefox nor Chromium would interpret JavaScript embedded in an SVG if that SVG is loaded from an HTML's |
Gitea (and Gogs) does not handle multiple domains, which would be a requirement for this. This has been discussed some over at gogs/gogs#1314 . And there's already |
Don't the headers
provide a reasonable level of protection against these security risks? |
It seems https://git.fsfe.org/reuse/reuse-ci/raw/master/reuse-compliant.svg I would like to include this in a README.md as such:
Adding |
maybe a client render via javascript. |
@lunny That is only slightly worse than rendering it directly 🙁 |
Is somebody still working on this? |
@bluecatchbird I don't think so |
You guys can read this, which uses a |
Markdown in gitea, i cannot display image. |
@kiemrong08 please file another issue if you cannot find similar issue. |
I wasn't aware of of exploits though some are listed here: https://security.stackexchange.com/questions/11384/exploits-or-other-security-risks-with-svg-upload. Why not just parse out any inline JS—which IMO shouldn't be allowed in SVG anyway—and serve from the same domain inside a sandboxed iFrame? |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs during the next 2 weeks. Thank you for your contributions. |
Issue should be closed if the problem is solved, not by time of inactivity. :-/ |
Yeah, this new policy is frankly pretty darn stupid. |
We already have a dom parser/sanitizer (https://github.com/microcosm-cc/bluemonday) that could maybe configure to do this. |
Wouldn't that already be possible with the external render functionality? SVG can contain for example links that would be lost if rendering them to png. Although SVG is what most peope want, are there other files that should be possible to view in raw format? Should be better to find a general solution in that case. |
Rendering SVG to PNG will have several drawbacks:
|
I came here because the lack of support for Would it be an option to support this kind of SVG embedding if the SVG comes from the same repo? |
@jcw problem is that svg can contain JavaScript and someone could create repository with malicious svg file that could be used to attack other users on that server |
Thanks for clarifying, @lafriks. I'm not a front-end developer, so what follows may be wrong:
I understand and fully respect the fact that this issue is non-trivial. Nevertheless, it might be worth considering moving towards a limited resolution (or perhaps passing the risk on to gitea admins, by having a site config setting as to whether embedded SVG is allowed). I'm just trying to help find a gentle way out. SVG's scale independence makes it very useful for visual diagrams, given the wide range of screen sizes used to browse on a gitea site. |
The variant edgar-bonet mentioned sounds very good to me. JS from inside the image wouldn't have any access to the parent if SVG images would be replaced with an iframe which has the And for the paranoid ones, this feature could be optional, maybe? Also removing dangerous things were mentioned a few times. I guess the Go library bluemonday is made for exactly this. Furthermore it is already a dependency anyway (it should be updated though because Gitea uses a version from 2016!). But attackers are sometimes also finding some sanitizer issues (i.e. if projects are using outdated versions 😉 ). So I guess it would make sense to make the sandboxed iframe-solution mandatory to have at least a level of security if the browser works correctly. And I guess it would be a nice bonus if a lib like bluemonday is used additionaly. |
A while ago I created a repo just for testing the handling of SVG images in a README file:
Visiting this repo again, I notice that now GitHub does render the inline SVGs. The GitHub issue “Fix relative SVG rendering” has accordingly been closed. The GitHub solution seems to rely on multiple layers of defence:
|
Can allowing unsecure svgs just be made a config option? On a semi-private Gitea instance, it really should matter that svgs aren't "technically" secure, because only people you trust have accounts. In my case, I'd like to be able to embed svgs in README.md files, but Gitea is forcing the mime-type to be set to text/plain. |
Exactly - that's what I suggested 2 months ago. For precisely the same reason. |
From testing in #8024 we could use bluemonday to clean-up svg but to be secure (at least in it current state) it need to block some svg functionality like url() linking to some gradient. I suggest we could add a config (SVG_RENDER_METHOD) that would be set to "none" (or reject) by default and can be set to "filtered" (limited set of func) or "insecure" (the raw source). |
It's not only about trusting the people on your server (or yourself) but also about not using the mirroring feature of gitea. Because you could obviously also mirror a repository that is safe today, but includes a malicious SVG that hijacks your Gitea credentials tomorrow. Just to be sure: is there any reason against rendering the SVG in a sandboxed iFrame? And to clarify this: I'm not against stripping dangerous tags, as mentioned earlier. I just believe that browsers should be pretty secure if used correctly and I guess some smart people implemented the sandbox feature. |
To add to what I'd said earlier, I'd like to see Gitea add a "semi-dangerous" option to allow some svg features, and another "more-dangerous" option with more warnings that allows object tags to enable embedding svgs with fonts, something that can't currently be done with img tags. |
I'd prefer @alexanderadam 's idea of sandboxing the SVGs, via a config on/off setting. Luckily the suggested solutions are not mutually exclusive. |
This issue is also relevant to Codeberg.org, where there also have been discussion about this: https://codeberg.org/Codeberg/Community/issues/220 One possible solution would be to implement a media proxy as suggested in #916 |
I see that #8024 is closed now due to inactivity. What's the status of that or some other filtering approach? Is anyone still working on that angle? |
tbh we would like to see sandboxing for all rendering of user-provided content and previews. |
I didn't think of it before but of course you're absolutely right. Putting rendered markdown and other content completely within a sandboxed frame also avoids the problem of mapping sizes of the SVG to its containing frame. PS: Also paths probably have to be still rewritten (for having the SVG within an iFrame) and/or dangerous attributes still removed because users could still be tricked by adding an infographic that you want to see in full screen. Click here to see the full size graphic:
[![Click here to see the full size graphic](/malicious/infographic.svg)](/malicious/infographic.svg) It doesn't appear evil, since it's still the same domain and many users probably won't know its implications accessing the SVG directly. |
Can't we just embed in an
|
As far as I can tell from @edgar-bonet's test repo, GitHub doesn't strip Edit: it does serve from a different domain using a 302 redirect. |
I propose the following changes to close this issue:
What's wrong with this proposed solution? It handles SVG files with embedded script tags, without a separate domain, and makes no assumptions about the trustworthiness of the files. It handles displaying the SVG when navigating in the source tree, going directly to the raw file, and when embedding the raw image file in markdown. It does it without a whitelist of things to filter and without adding any new configuration options. So what am I missing? |
@jtran wrote:
The user can bypass this by right-clicking on the image and selecting “View Image” (Firefox) or “Open image in new tab” (Chromium). From what I see on GitHub, it seems that the |
Check out PR #14101 where I implemented the above. |
Hello!
Gitea can't render SVG files.
It is a matter of settings?
or
Do not implement functionality?
GITEA:
GITHUB:
The text was updated successfully, but these errors were encountered: