-
Notifications
You must be signed in to change notification settings - Fork 478
Additional XXE mitigation #873
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
Additional XXE mitigation #873
Conversation
@gmwalker: Since this builds on your work, perhaps you have some comments, specifically about the use of the static property? @H1Gdev, @mrbean-bremen: You were both part of reviewing #870 a few days ago. (Sorry if tagging you like this is unnecessary.) |
@tebjan , @wieslawsoltes : I'm not really comfortable with reviewing this, having no experience with handling of vulnerabilities in C# - if one of you has more experience, it would be nice to get a review. Same goes for @gmwalker or anyone else with more knowledge in this field. |
@kimsey0 - thanks for the pull request, we appreciate the effort to make the library more secure! |
It looks like quite a few (190) of the W3C test suite SVG's use external references, specifically for fonts, for example:
I have very little information about how SVG.NET is used elsewhere. It might be common and expected to load and render SVG's with external font references. However, in our use-case, we render user-uploaded SVG's, and would like to prevent them from both loading local files and making web requests. That also seems to be the concern of @gmwalker in #869 (comment). It could be that these W3C suite tests should be run with |
For now, I enabled |
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.
FWIW, the changes look good to me, but as I wrote -- I have no experience here and probably wouldn't find any missing checks, so I'll wait a bit for someone else to have a look.
I also think that having ResolveExternalSources
default to false
is the correct way, we just have to make sure that this is made clear in the release notes. As this is a breaking change, we'll probably need a new major release version, if we want to follow semantic versioning -- @tebjan , what do you think?
I've added image comparison tests that render an SVG with an external image reference and one with a text reference, and check that the image and text is only shown if
I agree. If loading external images and other references is disabled by default, it's a breaking change and should be a new major version. |
@@ -28,6 +28,9 @@ public class ImageComparisonTest | |||
[TestCaseSource(typeof(ImageTestDataSource), nameof(ImageTestDataSource.PassingTests))] | |||
public void CompareSvgImageWithReference(ImageTestDataSource.TestData testData) | |||
{ | |||
// W3C Test Suites use external references to local fonts | |||
SvgDocument.ResolveExternalResources = true; |
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.
Is it possible to move this line to head of CompareSvgImageWithReferenceImpl
method ?
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.
I did so in an earlier commit, but moved it back here because I now also use CompareSvgImageWithReferenceImpl
from XxeVulnerabilityTests
, which need XxeVulnerabilityTests
to not be overwritten. I've added a few suggestions for alternative organization of the test here #873 (comment).
I can also make the value for ResolveExternalResources
a parameter of CompareSvgImageWithReferenceImpl
and pass it in from CompareSvgImageWithReference
and XxeResolveExternalImage
? However you'd prefer.
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.
In XxeVulnerabilityTests
, please evaluate DOM value etc. instead of comparing reference images.
Now in ImageComparisonTest
, I think that I do is only in case of SvgDocument.ResolveExternalResources = true
.
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.
For both <image xlink:href="..." />
and <tref xlink:href="..."/>
, resolving the external reference only seems to happen during rendering, and even after calling Draw
, I can't see anything that has changed in the DOM which a test could look for. Am I overlooking something?
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.
Please add property or method to evaluate.
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.
I think setting this feature with Boolean
value will significantly reduce usability.
In most cases, we want to disable external file reference
, but we want to display images.
What do you want to disable in this PR ?
@@ -28,6 +28,9 @@ public class ImageComparisonTest | |||
[TestCaseSource(typeof(ImageTestDataSource), nameof(ImageTestDataSource.PassingTests))] | |||
public void CompareSvgImageWithReference(ImageTestDataSource.TestData testData) | |||
{ | |||
// W3C Test Suites use external references to local fonts | |||
SvgDocument.ResolveExternalResources = true; |
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.
Please add property or method to evaluate.
@H1Gdev: I'm not sure I quite understand your questions.
Do you mean to suggest having multiple different Boolean properties controlling the different types of external resources that can be loaded: public bool ResolveExternalXmlEntites { get; set } = false;
public bool ResolveExternalImages { get; set; } = true;
public bool ResolveExternalElements { get; set } = true; Or something similar with an enum or flags enum?
The current implementation in this pull request allows displaying images via <!-- Displayed when SvgDocument.ResolveExternalResources == false -->
<image href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />
<!-- Not displayed when SvgDocument.ResolveExternalResources == false -->
<image href="../../MySecretImages/Secret.png" />
<image href="https://example.org/External.png" /> Are you saying that, in most cases, we want to allow loading external images from the local file system and the web?
Our use-case is to allow users to upload SVG files and to generate previews of them. When rendering these previews, we want to:
I'm not sure where I should add a property or method to evaluate what? |
@mrbean-bremen sorry for the late reply. Yes, I agree with what you said about the versioning, since it's a breaking change. Regarding code, it's out of my comfort zone a bit. But from what I've seen, it's definitely an improvement, even if it isn't mitigating all possible vulnerabilities. |
I think However, we haven't been able to identify use cases, so I'm wondering what kind of interfaces should be defined.
This depends on intended use of users.
It seems that default values are different on server side or client side...
Please add it to corresponding element. public ExternalType ResolveExternalResources { get; set } if (ResolveExternalResources.HasFlag(ExternalType.Local))
{
}
if (ResolveExternalResources.HasFlag(ExternalType.Remote))
{
} |
Split into ResolveExternalXmlEntites, ResolveExternalImages, and ResolveExternalElements, each of which can allow local and/or remote resources
OK. I went with your design 1, since I think it makes both setup and usage of the properties more clear and makes it harder to accidentally overwrite flags for other resource types. Have a look!
I'm not exactly sure how this should be accomplished. We can't reliably determine which environment SVG.NET is being used in, so it would have to be configurable. We could add additional properties or configuration methods like (shorthand): public static void ConfigureServerSecurity() => ResolveExternalXmlEntites = ResolveExternalImages = ResolveExternalElements = ExternalType.None; But I'm not sure that would be any more discoverable or understandable than just setting the properties manually. I've set
|
@@ -39,6 +41,35 @@ public void XxeResolveExternalResources(bool resolveExternalResources) | |||
DeleteSecretFile(secretFilePath); | |||
} | |||
} | |||
|
|||
[TestCase(ExternalType.None, "__pull_request-873-01", "__pull_request-873-01-ExternalReferencesDisabled")] |
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.
Include this test in ImageComparisonTest
.
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.
There is no need for this, as the image comparison tests are already executed here.
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.
I commented that DOM test should be done here because images comparison test is uncertain...
I think tests like PR #870 is ideal.
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.
Ok, I obviously didn't get this, sorry. If you want to change this, you can add a new PR, of course. There are still 2 open issues that can go into the next release, so we may wait with a release a couple of days anyway.
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.
If it looks like it will be in time for this release, I will create a PR.
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.
Go ahead 👍
|
||
private void CompareSvgImageWithReferenceImpl(string baseName, | ||
public static void CompareSvgImageWithReferenceImpl(string baseName, |
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.
Please revert this line.
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.
This is used in the other test, so it cannot be private. Can be made internal instead.
At this time, there is no need to initialize. A place that has access to direct It may be better to have it in |
If we want to make it stronger, you can force users to set it. How do you think we should decide (default value ? client ? server ? require ?) ? 😟 |
Sorry for the long delay - I missed the question, and I didn't follow up here, as I was busy with other stuff. |
It looks like some code hasn't been fixed yet. |
You refer to the private method made public, and the reference to the test? Yes, these could be changed, though these are minor things. Anything else? |
Maybe that's it. |
…d Generators Nuget README.md Samples Source Tests doc docfx.json index.md license.txt Don't load external elements when resolving external resources is disabled BuildProcessTemplates CONTRIBUTING.md Generators Nuget README.md Samples Source Tests doc docfx.json index.md license.txt Enable resolving external resources for rendering tests BuildProcessTemplates CONTRIBUTING.md Generators Nuget README.md Samples Source Tests doc docfx.json index.md license.txt Add image comparison tests for loading external images and text BuildProcessTemplates CONTRIBUTING.md Generators Nuget README.md Samples Source Tests doc docfx.json index.md license.txt Add release notes BuildProcessTemplates CONTRIBUTING.md Generators Nuget README.md Samples Source Tests doc docfx.json index.md license.txt Split ResolveExternalResources into three properties (ResolveExternalXmlEntites, ResolveExternalImages, and ResolveExternalElements)
Hey @mrbean-bremen , |
I'm not aware of a possibility to do that. Generally I think this is what the release notes are for - the user has to check if a newer version fixes some known vulneribilities. |
Reference Issue
#872
What does this implement/fix? Explain your changes.
This prevents loading external images and elements when
SvgDocument.ResolveExternalResources
isfalse
.Any other comments?
This is just a draft pull request to get the ball rolling.
ResolveExternalResources
? The property name seems to indicate that it controls the loading of all kinds of external resources, but there might be users who expect to be able to include external images?SvgImage
andSvgElementIdManager
access the staticSvgDocument.ResolveExternalResources
like this or should it somehow be passed down to them, like forSvgDtdResolver
?