diff --git a/rules/REQUEST-945-APPLICATION-ATTACK-XML.conf b/rules/REQUEST-945-APPLICATION-ATTACK-XML.conf
new file mode 100644
index 000000000..adfd7a257
--- /dev/null
+++ b/rules/REQUEST-945-APPLICATION-ATTACK-XML.conf
@@ -0,0 +1,146 @@
+# ------------------------------------------------------------------------
+# OWASP ModSecurity Core Rule Set ver.3.1.0
+# Copyright (c) 2006-2017 Trustwave and contributors. All rights reserved.
+#
+# The OWASP ModSecurity Core Rule Set is distributed under
+# Apache Software License (ASL) version 2
+# Please see the enclosed LICENSE file for full details.
+# ------------------------------------------------------------------------
+
+#
+# -= Paranoia Level 0 (empty) =- (apply unconditionally)
+#
+# This rule skip all XML attacks rules if Content-Type is not
+# one of the following:
+#
+# - text/xml
+# - application/xml
+#
+# Keep in mind that an application may parses XML input
+# even if the Content-Type is not one of them listed above.
+# Uncomment this rule only if you're confident about what's
+# the application behavior with different content-types.
+#
+#SecRule !REQUEST_HEADERS:Content-Type "@rx (?:application(?:/soap\+|/)|text/)xml" \
+# "id:945000,\
+# phase:1,\
+# t:none,\
+# t:lowercase,\
+# pass,\
+# nolog,\
+# skipAfter:END-REQUEST-945-XML"
+
+
+SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:945011,phase:1,pass,nolog,skipAfter:END-REQUEST-945-XML"
+SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:945012,phase:2,pass,nolog,skipAfter:END-REQUEST-945-XML"
+#
+# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher)
+#
+SecRule REQUEST_BODY "@rx ]>&xxe;"
+ output:
+ log_contains: "id \"945100\""
+
+ -
+ test_title: 945000-2
+ desc: XXE Local File Inclusion
+ stages:
+ -
+ stage:
+ input:
+ dest_addr: "127.0.0.1"
+ port: 80
+ headers:
+ Host: "localhost"
+ Accept: "*/*"
+ User-Agent: "ModSecurity CRS 3 Tests"
+ Content-Type: "text/html"
+ method: POST
+ version: HTTP/1.0
+ uri: /
+ data: " ]>&example;"
+ output:
+ log_contains: "id \"945110\""
diff --git a/util/regression-tests/tests/REQUEST-945-APPLICATION-ATTACK-XML/945200.yaml b/util/regression-tests/tests/REQUEST-945-APPLICATION-ATTACK-XML/945200.yaml
new file mode 100644
index 000000000..61075a2f4
--- /dev/null
+++ b/util/regression-tests/tests/REQUEST-945-APPLICATION-ATTACK-XML/945200.yaml
@@ -0,0 +1,28 @@
+---
+ meta:
+ author: "theMiddle"
+ enabled: true
+ name: "945200.yaml"
+ description: "XXE Regression Test PL2"
+ tests:
+ -
+ test_title: 945200-1
+ desc: XXE test replace response values
+ stages:
+ -
+ stage:
+ input:
+ dest_addr: "127.0.0.1"
+ port: 80
+ headers:
+ Host: "localhost"
+ Accept: "*/*"
+ User-Agent: "ModSecurity CRS 3 Tests"
+ Content-Type: "text/html"
+ method: POST
+ version: HTTP/1.1
+ uri: /
+ data: " ]>&example;"
+ output:
+ log_contains: "id \"945200\""
+
diff --git a/util/regression-tests/tests/REQUEST-945-APPLICATION-ATTACK-XML/945300.yaml b/util/regression-tests/tests/REQUEST-945-APPLICATION-ATTACK-XML/945300.yaml
new file mode 100644
index 000000000..fcbc8669e
--- /dev/null
+++ b/util/regression-tests/tests/REQUEST-945-APPLICATION-ATTACK-XML/945300.yaml
@@ -0,0 +1,28 @@
+---
+ meta:
+ author: "theMiddle"
+ enabled: true
+ name: "945300.yaml"
+ description: "XXE Regression Test PL3"
+ tests:
+ -
+ test_title: 945200-1
+ desc: XXE ENTITY tag
+ stages:
+ -
+ stage:
+ input:
+ dest_addr: "127.0.0.1"
+ port: 80
+ headers:
+ Host: "localhost"
+ Accept: "*/*"
+ User-Agent: "ModSecurity CRS 3 Tests"
+ Content-Type: "text/html"
+ method: POST
+ version: HTTP/1.1
+ uri: /
+ data: " ]>"
+ output:
+ log_contains: "id \"945300\""
+