X-Git-Url: http://git.osdn.net/view?p=mikutoga%2FTogaGem.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fjp%2Fsfjp%2Fmikutoga%2Fxml%2FSchemaUtil.java;h=a8dbadfe1f5fc2ce415bf813e58b15eb4f3f93c9;hp=7950c83e77c9e7180cc8b7c27a81c582b4483db4;hb=f9b9e3018b46180c0e88812c25211e8630137a8c;hpb=d1cde1f17131ca29f084ea7dc8ee0ef72cab7cfc diff --git a/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java b/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java index 7950c83..a8dbadf 100644 --- a/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java +++ b/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java @@ -22,14 +22,47 @@ import javax.xml.validation.Schema; 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スキーマの各種ビルダ。 + * XML schema (XSD) utilities. */ 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()); + } + + /** - * 隠しコンストラクタ。 + * Hidden constructor. */ private SchemaUtil(){ assert false; @@ -38,32 +71,67 @@ public final class SchemaUtil { /** - * 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. + * + *

Includes some considerations for XXE vulnerabilities. + * + *

Restrict access to + * External Entity Reference & external DTDs + * in xml schema file. + * + *

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); - // schemaFactory.setFeature(name, value); - // schemaFactory.setProperty(name, object); + try{ + // Prevent denial of service attack. + schemaFactory.setFeature( + XMLConstants.FEATURE_SECURE_PROCESSING, true); + }catch(SAXNotRecognizedException | SAXNotSupportedException e){ + // FEATURE MUST BE SUPPORTED + assert false; + } + + 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; } @@ -93,7 +161,7 @@ public final class SchemaUtil { * @throws MalformedURLException 不正なURI * @throws IOException オープンエラー */ - private static Source[] toLocalSourceArray(LocalXmlResource[] resArray) + private static Source[] toLocalSourceArray(LocalXmlResource... resArray) throws MalformedURLException, IOException{ List sourceList = new ArrayList<>(resArray.length); @@ -116,10 +184,14 @@ public final class SchemaUtil { * @param resArray ローカルスキーマ情報並び * @return スキーマ */ - public static Schema newSchema(XmlResourceResolver resolver, - LocalXmlResource... resArray ){ + public static Schema newSchema( + XmlResourceResolver resolver, + LocalXmlResource... resArray){ + XmlResourceResolver totalResolver = buildXmlXsdResolver(); + totalResolver.putRedirected(resolver); + for(LocalXmlResource resource : resArray){ - resolver.putRedirected(resource); + totalResolver.putRedirected(resource); } Source[] sources; @@ -130,7 +202,7 @@ public final class SchemaUtil { throw new AssertionError(e); } - SchemaFactory schemaFactory = newSchemaFactory(resolver); + SchemaFactory schemaFactory = newSchemaFactory(totalResolver); Schema result; try{