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=9e2ae10abbfef778b97cb5c54ee4ecd58941e3c7;hp=8afddf4baad2eb54f1de6c73d78b8069c1bf4eee;hb=793abb8865022e44be6cbf607902bcdf8d726892;hpb=3fd0f125fb25fb0955bf2d7f7a557f488b4fd98a diff --git a/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java b/src/main/java/jp/sfjp/mikutoga/xml/SchemaUtil.java index 8afddf4..9e2ae10 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,64 @@ 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. + * + * @return schema factory */ - public static SchemaFactory newSchemaFactory( - LSResourceResolver resolver ){ - SchemaFactory schemaFactory = - SchemaFactory.newInstance( - XMLConstants.W3C_XML_SCHEMA_NS_URI - ); + public static SchemaFactory newSchemaFactory(){ + 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; + } - schemaFactory.setErrorHandler(BotherHandler.HANDLER); + 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; + } + + LSResourceResolver resolver = buildXmlXsdResolver(); schemaFactory.setResourceResolver(resolver); + schemaFactory.setErrorHandler(BotherHandler.HANDLER); + return schemaFactory; } @@ -93,9 +158,9 @@ 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); + List sourceList = new ArrayList<>(resArray.length); for(LocalXmlResource resource : resArray){ Source localSource = toLocalSource(resource); @@ -112,16 +177,10 @@ public final class SchemaUtil { * *

任意のリゾルバを指定可能 * - * @param resolver リゾルバ * @param resArray ローカルスキーマ情報並び * @return スキーマ */ - public static Schema newSchema(XmlResourceResolver resolver, - LocalXmlResource... resArray ){ - for(LocalXmlResource resource : resArray){ - resolver.putRedirected(resource); - } - + public static Schema newSchema(LocalXmlResource... resArray){ Source[] sources; try{ sources = toLocalSourceArray(resArray); @@ -130,7 +189,7 @@ public final class SchemaUtil { throw new AssertionError(e); } - SchemaFactory schemaFactory = newSchemaFactory(resolver); + SchemaFactory schemaFactory = newSchemaFactory(); Schema result; try{