import javax.xml.validation.SchemaFactory;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
/**
* XMLスキーマの各種ビルダ。
*/
public final class SchemaUtil {
+
+ /** XML Schema. */
+ public static final String SCHEMA_XML =
+ "http://www.w3.org/2001/xml.xsd";
+
+ /** XSD namespace. */
+ public static final String NS_XSD =
+ "http://www.w3.org/2001/XMLSchema-instance";
+
+ private static final String LOCAL_SCHEMA_XML =
+ "resources/xmlspace.xsd";
+
+ private static final URI URI_XSD_ORIG;
+ private static final URI URI_XSD_LOCAL;
+
+ private static final String ALLOWED_USCHEMA = "http";
+
+ private static final Class<?> THISCLASS = SchemaUtil.class;
+
+
+ static{
+ URL redirectRes = THISCLASS.getResource(LOCAL_SCHEMA_XML);
+ String redirectResName = redirectRes.toString();
+
+ URI_XSD_ORIG = URI.create(SCHEMA_XML);
+ URI_XSD_LOCAL = URI.create(redirectResName);
+
+ assert ALLOWED_USCHEMA.equalsIgnoreCase(URI_XSD_ORIG.getScheme());
+ }
+
+
/**
* 隠しコンストラクタ。
*/
/**
- * XML Schema 用のスキーマファクトリを返す。
- * @return スキーマファクトリ
+ * build xml.xsd redirection info.
+ *
+ * @return resolver
*/
- public static SchemaFactory newSchemaFactory(){
- SchemaFactory result = newSchemaFactory(null);
+ public static XmlResourceResolver buildXmlXsdResolver(){
+ XmlResourceResolver result = new XmlResourceResolver();
+ result.putRedirected(URI_XSD_ORIG, URI_XSD_LOCAL);
return result;
}
/**
- * XML Schema 用のスキーマファクトリを返す。
- * @param resolver カスタムリゾルバ。nullも可。
- * @return スキーマファクトリ
+ * Build SchemaFactory for XML Schema but safety.
+ *
+ * <p>Includes some considerations for XXE vulnerabilities.
+ *
+ * <p>Restrict access to
+ * External Entity Reference & external DTDs
+ * in xml schema file.
+ *
+ * <p>Restrict access to External schema file access in xml schema file,
+ * but HTTP access is allowed.
+ * This special limit considers access to
+ * importing http://www.w3.org/2001/xml.xsd
+ * in top of common xml schema file.
+ * If HTTP access controll is needed, customize resolver yourself.
+ *
+ * @param resolver Custom resolver for reading xml schema.
+ * Resolve reference to nothing if null.
+ * @return schema factory
*/
public static SchemaFactory newSchemaFactory(
LSResourceResolver resolver ){
- SchemaFactory schemaFactory =
- SchemaFactory.newInstance(
- XMLConstants.W3C_XML_SCHEMA_NS_URI
- );
+ SchemaFactory schemaFactory;
+ schemaFactory = SchemaFactory.newInstance(
+ XMLConstants.W3C_XML_SCHEMA_NS_URI);
+
+ try{
+ // Prevent denial of service attack.
+ schemaFactory.setFeature(
+ XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ }catch(SAXNotRecognizedException | SAXNotSupportedException e){
+ // FEATURE MUST BE SUPPORTED
+ assert false;
+ }
- // schemaFactory.setFeature(name, value);
- // schemaFactory.setProperty(name, object);
+ try{
+ // Disallow external entity reference & external DTD access.
+ schemaFactory.setProperty(
+ XMLConstants.ACCESS_EXTERNAL_DTD, "");
+ // Allow only HTTP external schema file.
+ schemaFactory.setProperty(
+ XMLConstants.ACCESS_EXTERNAL_SCHEMA, ALLOWED_USCHEMA);
+ }catch(SAXNotRecognizedException | SAXNotSupportedException e){
+ // PROPERTY MUST BE SUPPORTED JAXP1.5 or later
+ assert false;
+ }
- schemaFactory.setErrorHandler(BotherHandler.HANDLER);
schemaFactory.setResourceResolver(resolver);
+ schemaFactory.setErrorHandler(BotherHandler.HANDLER);
+
return schemaFactory;
}
* @throws MalformedURLException 不正なURI
* @throws IOException オープンエラー
*/
- private static Source[] toLocalSourceArray(LocalXmlResource[] resArray)
+ private static Source[] toLocalSourceArray(LocalXmlResource... resArray)
throws MalformedURLException, IOException{
- List<Source> sourceList = new ArrayList<Source>(resArray.length);
+ List<Source> sourceList = new ArrayList<>(resArray.length);
for(LocalXmlResource resource : resArray){
Source localSource = toLocalSource(resource);