mirror of https://github.com/apache/nifi.git
NIFI-4125 Added secure transform feature and configuration to TransformXML processor to mitigate XXE file system leaks.
This closes #1946. Signed-off-by: Andy LoPresto <alopresto@apache.org>
This commit is contained in:
parent
3089d9dce0
commit
3bf1d12706
|
@ -28,6 +28,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.transform.OutputKeys;
|
import javax.xml.transform.OutputKeys;
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
|
@ -98,6 +99,16 @@ public class TransformXml extends AbstractProcessor {
|
||||||
.addValidator(StandardValidators.BOOLEAN_VALIDATOR)
|
.addValidator(StandardValidators.BOOLEAN_VALIDATOR)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
public static final PropertyDescriptor SECURE_PROCESSING = new PropertyDescriptor.Builder()
|
||||||
|
.name("secure-processing")
|
||||||
|
.displayName("Secure processing")
|
||||||
|
.description("Whether or not to mitigate various XML-related attacks like XXE (XML External Entity) attacks.")
|
||||||
|
.required(true)
|
||||||
|
.defaultValue("true")
|
||||||
|
.allowableValues("true", "false")
|
||||||
|
.addValidator(StandardValidators.BOOLEAN_VALIDATOR)
|
||||||
|
.build();
|
||||||
|
|
||||||
public static final PropertyDescriptor CACHE_SIZE = new PropertyDescriptor.Builder()
|
public static final PropertyDescriptor CACHE_SIZE = new PropertyDescriptor.Builder()
|
||||||
.name("cache-size")
|
.name("cache-size")
|
||||||
.displayName("Cache size")
|
.displayName("Cache size")
|
||||||
|
@ -135,6 +146,7 @@ public class TransformXml extends AbstractProcessor {
|
||||||
final List<PropertyDescriptor> properties = new ArrayList<>();
|
final List<PropertyDescriptor> properties = new ArrayList<>();
|
||||||
properties.add(XSLT_FILE_NAME);
|
properties.add(XSLT_FILE_NAME);
|
||||||
properties.add(INDENT_OUTPUT);
|
properties.add(INDENT_OUTPUT);
|
||||||
|
properties.add(SECURE_PROCESSING);
|
||||||
properties.add(CACHE_SIZE);
|
properties.add(CACHE_SIZE);
|
||||||
properties.add(CACHE_TTL_AFTER_LAST_ACCESS);
|
properties.add(CACHE_TTL_AFTER_LAST_ACCESS);
|
||||||
this.properties = Collections.unmodifiableList(properties);
|
this.properties = Collections.unmodifiableList(properties);
|
||||||
|
@ -166,8 +178,17 @@ public class TransformXml extends AbstractProcessor {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Templates newTemplates(String path) throws TransformerConfigurationException {
|
private Templates newTemplates(ProcessContext context, String path) throws TransformerConfigurationException {
|
||||||
|
final Boolean secureProcessing = context.getProperty(SECURE_PROCESSING).asBoolean();
|
||||||
TransformerFactory factory = TransformerFactory.newInstance();
|
TransformerFactory factory = TransformerFactory.newInstance();
|
||||||
|
|
||||||
|
if (secureProcessing) {
|
||||||
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
// don't be overly DTD-unfriendly forcing http://apache.org/xml/features/disallow-doctype-decl
|
||||||
|
factory.setFeature("http://saxon.sf.net/feature/parserFeature?uri=http://xml.org/sax/features/external-parameter-entities", false);
|
||||||
|
factory.setFeature("http://saxon.sf.net/feature/parserFeature?uri=http://xml.org/sax/features/external-general-entities", false);
|
||||||
|
}
|
||||||
|
|
||||||
return factory.newTemplates(new StreamSource(path));
|
return factory.newTemplates(new StreamSource(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +207,7 @@ public class TransformXml extends AbstractProcessor {
|
||||||
cache = cacheBuilder.build(
|
cache = cacheBuilder.build(
|
||||||
new CacheLoader<String, Templates>() {
|
new CacheLoader<String, Templates>() {
|
||||||
public Templates load(String path) throws TransformerConfigurationException {
|
public Templates load(String path) throws TransformerConfigurationException {
|
||||||
return newTemplates(path);
|
return newTemplates(context, path);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -218,7 +239,7 @@ public class TransformXml extends AbstractProcessor {
|
||||||
if (cache != null) {
|
if (cache != null) {
|
||||||
templates = cache.get(xsltFileName);
|
templates = cache.get(xsltFileName);
|
||||||
} else {
|
} else {
|
||||||
templates = newTemplates(xsltFileName);
|
templates = newTemplates(context, xsltFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Transformer transformer = templates.newTransformer();
|
final Transformer transformer = templates.newTransformer();
|
||||||
|
|
Loading…
Reference in New Issue