Skip to content

Commit 0762805

Browse files
committed
add new method
1 parent 7c91a41 commit 0762805

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

src/main/java/eu/righettod/SecurityUtils.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import javax.xml.stream.XMLInputFactory;
4747
import javax.xml.stream.XMLStreamReader;
4848
import javax.xml.stream.events.XMLEvent;
49+
import javax.xml.validation.Schema;
50+
import javax.xml.validation.SchemaFactory;
4951
import java.awt.*;
5052
import java.awt.image.BufferedImage;
5153
import java.io.*;
@@ -1379,4 +1381,35 @@ public static UUID computeUUIDv7() {
13791381
UUID uuidv7 = new UUID(high, low);
13801382
return uuidv7;
13811383
}
1384+
1385+
/**
1386+
* Ensure that an XSD file does not contain any include/import instruction (prevent exposure to SSRF).
1387+
*
1388+
* @param xsdFilePath Filename of the XSD file to check.
1389+
* @return True only if the file pass all validations.
1390+
* @see "https://portswigger.net/web-security/ssrf"
1391+
* @see "https://www.w3schools.com/Xml/el_import.asp"
1392+
* @see "https://www.w3schools.com/xml/el_include.asp"
1393+
* @see "https://www.linkedin.com/posts/righettod_appsec-appsecurity-java-activity-7344048434326188053-6Ru9"
1394+
* @see "https://docs.oracle.com/en/java/javase/21/docs/api/java.xml/javax/xml/validation/SchemaFactory.html#setProperty(java.lang.String,java.lang.Object)"
1395+
*/
1396+
public static boolean isXSDSafe(String xsdFilePath) {
1397+
boolean isSafe = false;
1398+
try {
1399+
File xsdFile = new File(xsdFilePath);
1400+
if (xsdFile.exists() && xsdFile.canRead() && xsdFile.isFile()) {
1401+
//Parse the XSD file, if an exception occur then it's imply that the XSD specified is not a valid ones
1402+
//Create an schema factory throwing Exception if a external schema is specified
1403+
SchemaFactory schemaFactory = SchemaFactory.newDefaultInstance();
1404+
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
1405+
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
1406+
//Parse the schema
1407+
Schema schema = schemaFactory.newSchema(xsdFile);
1408+
isSafe = (schema != null);
1409+
}
1410+
} catch (Exception e) {
1411+
isSafe = false;
1412+
}
1413+
return isSafe;
1414+
}
13821415
}

src/test/java/eu/righettod/TestSecurityUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,5 +655,19 @@ public void computeUUIDv7() {
655655
history.add(uuidStr);
656656
}
657657
}
658+
659+
@Test
660+
public void isXSDSafe() {
661+
List<String> unsafeFileList = Arrays.asList("test-xsd-with-external-schema-via-import.xsd", "test-xsd-with-external-schema-via-include.xsd");
662+
unsafeFileList.forEach(f -> {
663+
String testFile = getTestFilePath(f);
664+
assertFalse(SecurityUtils.isXSDSafe(testFile), String.format(TEMPLATE_MESSAGE_FALSE_NEGATIVE_FOR_FILE, testFile));
665+
});
666+
List<String> safeFileList = Arrays.asList("test-xsd-no-external-schema.xsd");
667+
safeFileList.forEach(f -> {
668+
String testFile = getTestFilePath(f);
669+
assertTrue(SecurityUtils.isXSDSafe(testFile), String.format(TEMPLATE_MESSAGE_FALSE_POSITIVE_FOR_FILE, testFile));
670+
});
671+
}
658672
}
659673

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/purchaseorder" elementFormDefault="qualified">
3+
<xs:element name="orderId" type="xs:string"/>
4+
</xs:schema>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/purchaseorder" elementFormDefault="qualified">
3+
<xs:import namespace="http://example.com/person" schemaLocation="https://righettod.eu/test.xsd"/>
4+
<xs:element name="orderId" type="xs:string"/>
5+
</xs:schema>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/purchaseorder" elementFormDefault="qualified">
3+
<xs:include schemaLocation="https://righettod.eu/test.xsd"/>
4+
<xs:element name="orderId" type="xs:string"/>
5+
</xs:schema>

0 commit comments

Comments
 (0)