Problem/Motivation
People want to use SVGs on their websites. Unfortunately SVGs are a security disaster as they allow embedded CSS and JS. Which means that allowing users to upload SVGs should be viewed in the same was as allowing them to upload JS or create inline JS. In other words: SVG uploads are a big risk that require some kind of mitigation.
Here is a good presentation about SVGs from OWASP - the summary is
Allowing SVG for upload == allowing HTML for upload
Proposed resolution
Requiring additional permissions to upload SVGs is probably not going to happen since we don't have that type of granular permissions on fields. Also people want to make image styles play nice with SVGs - see #2652138: Image styles do not play nicely with SVGs.
A widely accepted solution is to use the content security policy header to prevent this. A Content Security Policy is how GitHub does it. This is a nice solution since it protects in a focused way without interfering with any user tasks.
Remaining tasks
None.
User interface changes
None
API changes
None
Data model changes
None
Issue fork drupal-2868079
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
mondrakeAdding related issue.
Comment #3
alexpottComment #4
phenaproxima+1 for this idea. It's important to maintain strong security around SVG, but also important to allow reasonable, legitimate use of the format.
A look at https://content-security-policy.com raises two questions for me:
1) What will our security policy for SVGs look like? My feeling is that we should initially lock it down completely in core and either open it up as needed in the future, or allow site builders to override and loosen it if they need to. One possibility is to make this a configuration setting in the Image module, but not introduce a UI to change (i.e., developers will be able to mess with it easily but the casual site builder or author won't).
2) What are we going to do about older browsers that don't support the CSP header, or only partially support it?
Comment #5
gappleContent Security Policy is supported by IE 10+ (though as
X-Content-Security-Policyin IE 10 and 11), so the only browser left out is IE9, which is no longer supported as of April 2017 (see also #2842298: [policy, no patch] Drop IE9 and IE10 support from Drupal 8.4.x)Comment #7
rgpublicCame here from #2650260. About @phenaproxima's questions, I'd say:
1) Scripts should not be allowed to run in SVG files. Plain and simple. I think this alone would fix all security concerns with SVG. Or is there another attack vector in SVGs except script execution we need to care about?
2) We should check whether IE10/11 properly support the Script blocking. Per 1) I guess we don't need any other features. For even older browsers, I would honestly say: Not our problem. It might sound a bit extreme at first, but, looking more closely: Those browsers are usually no longer supported by their respective manufacturers for a long time. And they are possibly running on Operating systems that are no longer supported as well. Those people don't get security updates. Not for their browser, not for their OS. And they don't care. They probably by now have more security holes in their environment than Swiss cheese. I highly doubt that it's now the SVG upload that'll break the camels back. BTW: As detailed in #2650260, I highly favor an option in "settings.php" to enable SVG upload support in general. With an added warning about the implications if you do this (e.g. people have to make sure .htaccess is actually respected etc.). Why not leave it then up to the site administrators if they want to allow this? For example, we have LOTS of Drupal websites here, where there is only a tiny audience of editors (or even only a single one) who can actually log in at all. For users without any credentials, there's not much the SVG can steal anyway.
Comment #10
geek-merlinI'd rather see that we take the best from SVG Formatter (Source) and SVG Sanitizer (Source) that both rely on darylldoyle/svg-sanitizer (Packagist: enshrined/svg-sanitize).
Am i improving or hijacking this? Feel free to revert if you think the latter.
Comment #11
gregglesWhy not both? I suggest CSP as a good first step regardless and an svg formatter/sanitizer as another good idea.
Comment #12
rgpublicYeah, I'd also say both can't hurt. Though I somewhat fear the complexity introduced by a decent sanitizer and the wrong illusion of security it might give if it doesnt work 100%.
BTW, I just found this while researching the topic:
https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
Interesting stuff in there IMHO, we might want to check. Especially the:
background-image: url('javascript:alert(8);')
On a very cursory glance, the sanitizer doesnt seem to sanitize stylesheets at all yet. I might be wrong, though...
Comment #13
geek-merlinQuickly tested: On http://svg.enshrined.co.uk/ i quickly entered a
style="background-image: url('javascript:alert(8);')"which (was not sanitized away and) came to my browser in an unwrapped xml element, but did not have any alertbox effects.Comment #14
geek-merlinFrom https://www.w3.org/wiki/SVG_Security#SVG_as_image
> The SVG document is not allowed to fetch any resources.
> Scripts must not be executed.
Are we done then?
EDIT: Maybe for browser viewing, but not for the User-saves-and-views-SVG attack described here.
Comment #15
rgpublicI think we are not done, because this whole issue is not about SVGs that are loaded as part of another webpage (e.g. IMG src tag). They usually don't pose a security risk exactly for the reasons you cited. The problem is about calling SVGs directly.
I'm not sure whether the style attacks and other attacks mentioned in the OWASP doc really don't work in all recent browsers. It certainly isnt sufficient to just test it in some...
I'd also really, realy like to see SVG support in Drupal, but I think we definitvely have to tread forward extra-careful here, because we are opening a security can of worms. If we don't watch out, we inadvertently create bad security holes...
What I'm currently missing is the reasoning behind why the sanitizer is really sufficient. Which vectors exist? And how are they catched by the sanitizer. Just taking the sanitizer and just hoping everything would be alright is a bit to easy, I guess.
Comment #16
geek-merlinYes i also won't bet too much on the sanitizer, it may be a good start though.
> The problem is about calling SVGs directly.
What do you mean? If we can box untrusted SVG in an img tag, why would we risk something else?
Note that the owasp article is from 2011, while the W3C wiki page is based on a chat in 2014.
(Which does not necessarily mean everything-is-bright-and-shiny now, but it gives historical context.)
Comment #17
rgpublicI meant: When the user uploads an SVG, by default it ends up in sites/default/files. And then you can call:
http://www.goodandhonestsite.com/sites/default/files/evil.svg
It doesnt matter how you actually use the image in the site. The possibility to call it that way is immediately there after the users uploads the file.
Comment #18
gappleComment #22
bkosborneHmm I think the issue summary should be updated to indicate that the security issue is restricted to SVGs being embedded directly "inline" via an
element or by viewing the SVG directly in your browser. Embedding an SVG as an img src seems safe.Comment #23
rgpublic@bkosborne: Well, the summary talks about uploads, specifically. And, just to be clear, it doesn't help if you actually use the uploaded SVG only inside an img tag. As stated, the problem is that the upload usually ends up in a public directory and the resulting image can as such be called via /sites/default/files/evil.svg. This, by itself, is already the security hole - no matter however the image will actually be used on the site later on. Perhaps you are already aware of this, I'd like to emphasize it again though, because the "...is restricted to..." part sounded *a bit* like "Hey, it only causes problems in rare cases".
Comment #24
bkosborneI hear you, I appreciate the emphasis on security.
Comment #25
gappleHere's a patch to try out, that adds a CSP header via the root .htaccess file.
Comment #26
geek-merlin#25: I don't grok the CSP header but modulo its correctness the patch looks good to me. If it's that easy we may well drop the (my) proposal to sanitize.
Comment #27
gappleI just copied the header value from what Github uses on their CDN.
It's restrictive by default (
default-src 'none'), which doesn't allow loading any external resources.It then opens up exceptions for embedded raster image data (
img-src data:), and inline style attributes (style-src 'unsafe-inline')There's another Github issue about allowing inline font data: https://github.com/github/markup/issues/1164
----
An alternative to setting this in the root .htaccess would be to apply it to the .htaccess in the files directory, so that only uploaded SVG files receive the header.
Comment #28
geek-merlinGood findings! We might consider a code comment about this.
> There's another Github issue about allowing inline font data:
That makes a lot of sense to me.
> An alternative to setting this in the root .htaccess would be to apply it to the .htaccess in the files directory, so that only uploaded SVG files receive the header.
That's an interesting point to bikeshed about ;-). I'd tend to apply to all served files until we know a reason to not do.
Which brings me to another point: How do we tackle SVGs uploaded to private filesystem and served by Drupal...?
Comment #29
rgpublicUmm, what about the following:
Let's say we have Drupal commerce shop or a Drupal forum site or whatever. IE11 is supported:
https://www.drupal.org/docs/system-requirements/browser-requirements
"The latest supported release of the latest major version of: Internet Explorer".
The latest major release of Internet Explorer is IE11 (because it's called Edge after that).
Apart from that, even if it wasn't officially supported... the website might happily accept forum or shop users using IE11 and perhaps they won't notice anything not working.
Now, let's upload an SVG which contains a malicious script. The script is under: sites/default/files/evil.svg.
Now, I go to a URL shortener website and create an alias for this: bitly.com/blabla
Now, I publish that URL on my twitter account and say: Hey, celebrity XY totally XXX (you know what).
IE11 user is logged into his shop. Clicks on the link. CSP doesn't work:
https://stackoverflow.com/questions/42937146/content-security-policy-doe...
Bam!
How do we avoid that? Do we even *want* to avoid that or ignore that risk?
IMHO, doing the sanitizing stuff is still useful in addition, after all. It creates a fallback for those cases.
It also creates a fallback if .htaccess doesn't work for some reason. (e.g. if AllowOverride is configured to false etc). What I think is dangerous about the above patch is that nobody will even notice if the webserver or browser doesn't support it. Everything will work just fine. But in fact the/some user(s) are then susceptible to evil cross-site scripting attacks.
Comment #30
gappleThis introduces a response subscriber to add a header to all
BinaryFileResponseinstances, which will protect private files.CSP isn't relevant to most file types, but the subscriber still sets a restrictive policy (just
default-src 'none'). Modules are able to override this header value through their own subscriber if necessary.----
csp.module currently sets the same header value on private file responses as it does on page responses, but should probably be updated to send a different value like in this patch.
Comment #39
mr.baileys* Converted the patch to a MR, rerolled for 11.x
* Added a test to confirm the presence of the CSP header for file downloads.
I'm not sure we should be adding the CSP header (Content-Security-Policy: "default-src 'none') for none image/svg+xml downloads, as that seems out of scope for this issue and might break existing functionality.
Comment #40
rgpublic@mr.baileys: It should probably at least work properly with the "csp" module. An easy solution would be to the set the priority of the respond event such that our event handler is guaranteed to run after their event handler. Then we could check whether the header is already set and do nothing in this case and just hope that the user knows what they're doing.
Comment #41
mr.baileysRe-titling, since the scope of this issue has shifted to adding a content security policy header, rather than sanitizing the file.
@rgpublic: makes sense, I added a condition so that the default CSP header is only set if none has been set earlier. I think it's up to CSP and other contrib modules to alter/set handler priorities?
Comment #42
rgpublic@mr.baileys: Yes, you are probably right. Currently they don't do this (I just checked, I see no explicit priority in their code), but I hope/assume their code gets after ours anyway because this is in core and their code is in contrib. If not, they could easily solve this by adding a priority - so: fine for me.
Comment #43
damienmckennaThere's also seckit which also can set the CSP headers.
Comment #44
rgpublicThe evil thing is: If we set sth. here and anyone keeps overwriting it they can inadvertently create a security hole because people can upload SVGs with a XSS payload again :-(
But I don't want to spoil the party. Glad this is finally moving forward.
In a perfect world, core would provide a CSP service that anyone can *add* their stuff to if they want so nothing gets destroyed except intentionally. But this is probably way out-of-scope for this issue...
It's quite an unfortunate situtation, but OTOH seckit / csp etc. are not modules anyone not savvy with these security issues will probably install lightheartedly. So perhaps we can just assume IF they change sth. they should know that then THEY have full responsibility over what security problems arise. Perhaps these contrib module owners should be informed that this is happening and add an appropriate readme note or sth. to their installation instructions...
Just my 0,02€
Comment #45
xmacinfoCan we set the CSP heasers on both public and private served files? Is Seckit able to add CSP headers on files?
Comment #46
mr.baileys@xmacinfo: for public files, I think the only way to add the header is through via web server directives (MR here includes a change to .htaccess for this reason)
Comment #47
gapple👋 CSP module maintainer here.
CSP module provides APIs for modules to amend a site's policy. In most cases it's pretty straightforward, but gets more involved for cases where it's not just adding an additional external domain to a directive. The goal of the module is that anyone can install the module for a security improvement, that it's easily configurable for site builders to add exceptions not captured automatically (& ideally harden the default config with basic knowledge), but also flexible for developers to handle any more complex uses (and to do so safely without breaking other site functionality).
Module subscribers with the same priority will execute after core, so it's the module's responsibility to preserve/amend/replace any value previously set by core.
CSP has its own issue for applying a different policy to private files (#3163371: Provide different CSP policy for private files), though there hasn't been any work done on it so far. If a special value is added to core for SVGs, then I'll update the module to match. If there's consensus on what should be added to core, I'll probably have a new release of the module before it's committed to core 🙂.
Alternately, the CSP module would be a good way to evaluate a potential solution (at least for private files, I'm not sure about the module altering htaccess), with users who have opted in to using a policy on their site. It would have to be an optional feature for the current major version, but could be enabled by default for new modules installs (and a site status message could prompt existing sites to try enabling it).
This issue for core would add a static policy that can be configured in a service parameter: #2513356: Add a default Content-Security-Policy and clickjacking defence to core
Instead of providing a single policy set, maybe it should be keyed policies to allow for additional cases (e.g. default, private-files, svg, etc, each with report-only and enforced values).
Comment #48
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #49
gregglesTried to address the feedback from the bot in #48.
Comment #50
gregglesThere were some test fails.
The core.services.yml definition needed to be updated after #3401730: Add default autoconfigure to all *.services.yml and remove event_subscriber tags.
Since this issue is about updating the htaccess we also need to update the scaffold htaccess.
The other test fails didn't look related to me, but I'm not sure.
Comment #51
rgpublicGreat there's finally so much progress on this. SVGs are an important part of modern scalable webistes. Just read the issue description again, though, after all that time and noticed:
* web.config
*Consider adding warning to image fields when people allow SVGs to be uploaded.
Both still valid IMHO. We'd need the web.config to support Windows servers. This is in scope for this issue, I guess.
And - the second point - if people finally allow SVGs to be uploaded a warning should be visible to double-check whether these restrictions actually work. If e.g people haven't enabled AllowOverride on their Apache server, all hell breaks lose. This is such a serious security hazard that we shouldn't take this too light-heartedly. Perhaps a reference to a drupal.org-hosted page where people can download an example evil.svg to easily test their installation? This could be spun-off into a separate issue of course. It might be out-of-scope for this issue, but I still think such a warnig is very important before we can actually reap the benefits i.e. people finally being able to actually upload SVGs without worrying too much about security.
Comment #52
mr.baileysIf this is D11 only, then we are no longer shipping web.config, so no changes required unless we backport to D10.
Comment #53
gregglesBackporting to 10.x can be a followup, IMO, so I removed the web.config from the issue summary.
It seems better for this issue to ship the CSP and consider that good enough. I removed the idea bout labels from the issue summary as well.
Comment #54
smustgrave commentedVery neat!
Think we will need a change record for the new service and maybe a 2nd CR for the change to htaccess? Know we got a few projects where we disabled the scafold of that so we would have to manually add that change.
Comment #55
rgpublicAlthough it'd only become relevant IF people actually uploaded SVGs - and that would IMHO still require a lot more than a mere CR (Explicit warning, Test SVG provided etc). I hope people won't allow it right now without that protection. This issue can just be considered a first step. It only tightens security where there wasn't any security whatsoever up until now. This should perhaps at least be clarified in the CR. People can already add these lines in their htaccess if they want to if they have auto-scaffolding disabled for some reason. It doesn't mean (by itself) that they should/could already allow SVG uploads... Just my 0,02€
Comment #56
gregglesI added change records as suggested in #54. Thanks for the review!
Comment #57
alexpottFixing link
Comment #58
gregglesThanks, alexpott. I did a bit more of an update to the issue summary to make it more of a focused summary of the conversation and current status.
There's currently a failing test and I'm unsure if it's related or what the cause is.
Comment #59
alexpott@greggles I retested - it was a random fail. So all green again.
Comment #60
phenaproximaI did a code review here and everything looks good. No complaints.
I cannot attest to the quality of the fix itself because security policy is very much not my forte. But if it's good enough for GitHub, and the security team members who have reviewed this issue, then I trust their judgment.
Tests are green, so I say ship it.
Comment #61
gregglesThanks @phenaproxima!
mr.baileys and I are doing another round of testing and will ping others to get more eyes on the security component of this.
Comment #62
gregglesI did some more manual testing and realized that the previous rule allowed `malicious.sVg` to bypass the protection. I updated the htaccess rule to be case insensitive. I've now manually confirmed this protection works on public and private svg files.
Thanks for the feedback, @larowlan. I accepted the one suggested change.
The proposed new header for all private files was introduced by gapple (CSP maintainer) so it feels pretty likely to be widely acceptable.
Comment #63
gappleApplying
default-src 'none'to other private files should only have an impact if sites were serving HTML files, and would be irrelevant to other responses like image files, so it might be worth leaving for discussion in #2513356: Add a default Content-Security-Policy and clickjacking defence to core or breaking out to a separate issue. It could then be done in combination to applying the same change for the files directory htaccess so that private and public files would have consistent behaviour, like SVGs would with this issue.Comment #64
gregglesThanks for your thoughts, gapple, and setting back to RTBC.
I forgot to mention I confirmed this is the header used by github for svgs content they serve.
I agree with gapple's comments that the change to all private binaryresponses could be broken out to another issue and we would still have most of the value in this issue.
Comment #65
alexpottI definitely think this issue should be only about setting a CSP for SVG files - the bit where we add a default CSP for all other private files needs discussion and additional thought.
Comment #66
gregglesMR is green again and I addressed the feedback in #65.
Comment #67
gregglesSome other questions to consider - I've added numbers to them to facilitate discussion.
Great question. I don't think it's very common for svgs to use these features (I've only seen it once on a non-Drupal mapping site) but it made me realize the change could be inside of the htaccess for the files directory and therefore only apply to a subset of files. That feels like it reduces the risk this change will negatively impact while still retaining most of the value in protecting sites from malicious files. I asked mr.baileys and he agreed on that idea, but we could certainly discuss it more.
I think they do pose a risk, but solving it feels like a separate problem to me. I filed #3494583: Filter SVGs before uploading by default and linked it to this as related for followup that could address this risk. The situation today is that site admins are enabling SVG uploads on their site often and there is no protection for a variety of risks that creates. This issue attempts to solve one of the risks (XSS), but is not a complete protection against all risks.
As far as I understand those risks they are not relevant on a typical Drupal site and would only be relevant on sites that parse the XML of the SVG file. These changes don't affect that for better/worse.
I'm not sure this mitigates all possible threats (several additional threats are mentioned in this issue already). I'm sure the change in this issue is progress in securing sites against cross site scripting, but not a solution to all risks of SVG files.
Comment #68
alexpott@greggles great idea only changing the .htaccess in the files directory. This move made me think 2 things.
1. We need a update function to rewrite existing sites .htaccess files I think
2. What about sites which use nginx or another server... what would be neat is something on the status report that confirms this protection is working. That way we could point to documentation on how to set this up.
Comment #69
mr.baileysI added an update hook (system_update_11103) to update existing .htaccess files.
Comment #70
mr.baileysI added a hook_requirements-check to test for the presence of a CSP-header on public SVG-files. I'm assuming that if there is a CSP-header, the site owner knows what they are doing, if it is missing we issue the warning. We could make it more strict and check the contents of the header if necessary.
Currently linking to the change record for more information.
Comment #71
mr.baileysComment #72
rgpublicI don't think that will work properly: The URL of the website would have to be specified from the command line. That's not necessarily the case. Neither is it guaranteed that the web server is really routed in such a way that it can call itself. And the check will only check for the existence of any header. Not that the protection really works. So, I have some doubts it's the best approach. IMHO much better would be a test on /admin/reports/status. This test could be an entry that is initially always under the "Warnings" category and says
"SVG security could not be tested properly. Please make sure you have an appropriate Content-Security-Policy header configured before allowing the upload of SVG files".
If there are any JS errors or JS is disabled in the browser this warning will just remain. We won't convey a false impression of safety.
Then there's an object-tag after that entry including an SVG file under public:// with a JS payload. An object tag and not an img tag because in this case scripts are executed. That JS payload would remove that entry and put a different entry under the "OK/Verified section".
Then there's a fallback JS that would move it to the "Error" category and say: "SVG security test failed."
A check along these lines would be way better IMHO. It avoids the problems mentioned above and is really a functional test that will make absolutely sure that scripts are not executed.
Comment #73
mr.baileys@rgpublic: I understand your concerns, consider that code a poc (I think this might also be a candidate to be handled in a follow-up issue)
Would there be a risk that the JS-test gives a false positive: embedded scripts blocked due to browser/browser config on the administrator's machine, while not blocked for other contexts/browsers/users? (compared to checking for the header, which guarantees that the change made in this issue works across the board)
Comment #74
rgpublic@mr.baileys: A very valid concern IMO, thanks for bringing this up! The server-based check, however, could also lead to false positives: If the CSP header is there but configured in such a way that it won't properly apply we have a problem right there. In this case we'd need to parse the whole CSP and see if it really applys. Or if the URL leads to a proxy and the proxy returns a different/404 page which has that header etc. Just two problems I see with a server-based check (apart from the other problems mentioned). We *could* in theory add a different, JS based check and fetch the header with XMLHttpRequest from JS. This would circumvent at least the domain not reachable/domain not configured from the command line problem and give an additional line of security.
If we checked that JS inside the object SVG is not executed AND fetch the headers via JS and check whether they are really there, I think this would be quite safe.
Comment #75
alexpott@rgpublic system_requirements is how admin/reports/status is generated - I agree we should only do this when not in the CLI. We already have quite a few requirements that only run when
if ($phase === 'runtime' && PHP_SAPI !== 'cli') {The current implementation in system_requirements is problematic because of adding the file to public... and then removing it. That's not free. Not sure I have a better idea yet. And maybe that means punting the system_requirement part to a follow-up is a good idea.
Comment #76
gregglesThe concept of the check for CSP header on the status page feels a like a pretty big additional functionality for core. It seems like something security_review could handle, so I filed #3495022: Check for CSP on private and public SVG files to track it there.
Comment #77
rgpublic@alexpott: Ah, understood. Thanks for the clarification. I'm not sure if it's necessary to remove the test file again. It could be created if it doesn't exist yet and otherwise just used. Still, I think a JS based approach would be safer. At the very least the CSP header should be checked for more than its mere existence, I guess.
Comment #78
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #80
prudloff commentedMerged the latest 11.x.
I encountered some errors in system_requirements() and confirm there are some potential problems with checking if the CSP is correctly added. So I removed this part of the MR and created a followup issue: #3525167: Check that the CSP header is added to SVG files
Tests are failing because we hit Yarn's rate limit :/Comment #81
prudloff commentedComment #82
smustgrave commentedGoing through a backlog of issues, sorry took so long but appears this one needs to be re-based. Surprised the bot never picked it up.
Comment #83
prudloff commentedAre you sure? I already rebased it 3 days ago and now GitLab does not find any conflict.
Comment #84
smustgrave commentedFairly positive, see screenshot
Comment #85
prudloff commentedThe screenshot does not say that it needs to be rebased. It just says that the latest automatic rebase failed (so I did a manual merge instead) and that merging is blocked because someone asked for changes in a review. (I don't have permission to mark the threads as resolved.)
If you expand the merge checks, you can see that the conflict and rebase checks pass (cf. screenshot).
Comment #86
smustgrave commentedGoing to leave this ticket for others then,
Comment #87
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #88
prudloff commentedI merged the latest 11.x and tried to address comments on the MR.
Comment #89
smustgrave commentedLeft some small comments.
Comment #90
prudloff commentedI made the requested changes.
Comment #92
smustgrave commentedBelieve feedback for this one has been addressed.
Comment #93
godotislateMR needs conflict resolution.
Comment #94
smustgrave commentedRebased as I'm waiting for this to write a security check for the Security Review module.
I didn't change the update hook number because 12000 isn't out yet so (I imagine) 11301 would be safe
Comment #95
godotislateCan someone take a pass at updating the CR. The first sentence is incomplete.
Comment #96
greggles@godotislate - good call, I fixed it.
Comment #97
sivaji_ganesh_jojodae commentedRebase failed: Rebase locally, resolve all conflicts, then push the branch.
Comment #98
prudloff commentedI merged the latest main but now CspHtaccessTest is failing.
Comment #99
prudloff commentedI fixed the test.
Comment #100
smustgrave commentedTest fix looks good. Would be good to see this one land so I can add a check to security review
Comment #101
gapple1. Whether the header is added by htaccess which checks for the
.svgfile extension, or the private file handler which checks the Content-Type, there may be the possibility of different behaviour between public and private files (depending on if/where the content type is inferred). The conditions used for adding the header should probably match, and possibly either case (file extension or content type) should result in adding the header.2. Modules can override the header for private files with their own event subscriber (and currently CSP module does apply its configured site-wide policy), but I don't see a mechanism for modules to alter the contents inserted into the htaccess file.
I think at the very least there needs to be a guide for devs on how to override the value included in the htaccess file, better if the policy could be changed for both methods through one service parameter (possibly enabling a Report-Only policy as well if configured), and ideally modules have a straightforward means of altering / overriding core consistently.
Comment #102
prudloff commentedI would suggest doing 2 in a followup issue too avoid expanding the scope of this issue too much.
Comment #103
samlerner commentedWhat's the work that needs done here? I'm running a site using Drupal 11.3.5 and I can still see the issue with uploading malicious SVGs that I originally reported to the security team. I tried applying MR !9919 as a patch, but some files like
composer/Plugin/VendorHardening/FileSecurity.phpdon't exist in my installation, and other pieces seem to already be implemented in core.Let me know what work is needed to finish this, I'd love to close this security issue as soon as possible.
Comment #104
prudloff commentedI created a followup for the second point of #101: #3584559: Provide a way to alter the CSP for public SVG files
Comment #105
samlerner commentedThanks @prudloff!
I was also able to fix the security issue using the code in https://www.drupal.org/node/3493998 and adding that to my .htaccess file at the bottom in the
<IfModule mod_headers.c>block. You want to make sure it's specific to SVGs though, otherwise you'll block all kinds of files. This was the final snippet:Comment #106
godotislateIf I'm reading #101 correctly, seems like the work to be done is the first bullet: that the condition for adding the header should be the same between public and private files, and account for both file extension and content-type.
Comment #107
samlerner commentedThanks @godotislate I'll stay tuned.
I also realized during testing that the
FilesMatchstatement I posted in #105 wasn't working for all cases, so I replaced it with this statement that checks the content type instead of the file extension:Comment #108
damienmckennaWould it be worth moving CSP_SVG_HEADER to a separate trait that is loaded in multiple places, rather than having to define the same string multiple times?