#526 Preventing SSRF due to external resource refs in SVGs

This commit is contained in:
Ashish Chopra 2020-02-25 11:26:16 +05:30
parent a1047edddb
commit 7bf99fb496
4 changed files with 52 additions and 3 deletions

View File

@ -88,6 +88,6 @@
</dependencies>
<properties>
<batik.version>1.9</batik.version>
<batik.version>1.12</batik.version>
</properties>
</project>

View File

@ -80,6 +80,7 @@ import java.util.Map;
*/
public class SVGImageReader extends ImageReaderBase {
private Rasterizer rasterizer;
private boolean allowExternalResources;
/**
* Creates an {@code SVGImageReader}.
@ -88,6 +89,7 @@ public class SVGImageReader extends ImageReaderBase {
*/
public SVGImageReader(final ImageReaderSpi pProvider) {
super(pProvider);
allowExternalResources = true;
}
protected void resetMembers() {
@ -116,6 +118,9 @@ public class SVGImageReader extends ImageReaderBase {
if (pParam instanceof SVGReadParam) {
SVGReadParam svgParam = (SVGReadParam) pParam;
// set the external-resource-resolution preference
allowExternalResources = svgParam.shouldAllowExternalResources();
// Get the base URI
// This must be done before converting the params to hints
String baseURI = svgParam.getBaseURI();
@ -641,6 +646,14 @@ public class SVGImageReader extends ImageReaderBase {
public void displayMessage(String message) {
processWarningOccurred(message.replaceAll("[\\r\\n]+", " "));
}
@Override
public ExternalResourceSecurity getExternalResourceSecurity(ParsedURL resourceURL, ParsedURL docURL) {
if (allowExternalResources) {
return super.getExternalResourceSecurity(resourceURL, docURL);
}
return new NoLoadExternalResourceSecurity();
}
}
}
}

View File

@ -41,6 +41,12 @@ import java.awt.*;
public class SVGReadParam extends ImageReadParam {
private Paint background;
private String baseURI;
private boolean allowExternalResources;
public SVGReadParam() {
super();
allowExternalResources = true;
}
public Paint getBackgroundColor() {
return background;
@ -58,6 +64,14 @@ public class SVGReadParam extends ImageReadParam {
baseURI = pBaseURI;
}
public void allowExternalResources(boolean bAllow) {
allowExternalResources = bAllow;
}
public boolean shouldAllowExternalResources() {
return allowExternalResources;
}
@Override
public boolean canSetSourceRenderSize() {
return true;

View File

@ -49,7 +49,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.Buffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -67,6 +66,7 @@ import static org.mockito.Mockito.*;
* @version $Id: SVGImageReaderTest.java,v 1.0 Apr 1, 2008 10:39:17 PM haraldk Exp$
*/
public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader> {
private SVGImageReaderSpi provider = new SVGImageReaderSpi();
protected List<TestData> getTestData() {
@ -306,4 +306,26 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
reader.dispose();
}
}
@Test(expected = SecurityException.class)
public void testDisallowedExternalResources() throws URISyntaxException, IOException {
URL resource = getClassLoaderResource("/svg/barChart.svg");
SVGImageReader reader = createReader();
TestData data = new TestData(resource, (Dimension) null);
try (ImageInputStream stream = data.getInputStream()) {
reader.setInput(stream);
SVGReadParam param = reader.getDefaultReadParam();
param.setBaseURI(resource.toURI().toASCIIString());
param.allowExternalResources(false);
// `reader.read` for `/svg/barChart.svg` should raise
// a SecurityException when External Resources are blocked
reader.read(0, param);
}
finally {
reader.dispose();
}
}
}