You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2026/04/21 13:49:17 UTC

(ws-neethi) 02/02: Put a limit on the number of nested policies

This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ws-neethi.git

commit 9069bcf9d401fbcfff834f26248845f8d51da4b5
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Apr 21 14:48:50 2026 +0100

    Put a limit on the number of nested policies
---
 .../java/org/apache/neethi/AbstractPolicyOperator.java   | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/main/java/org/apache/neethi/AbstractPolicyOperator.java b/src/main/java/org/apache/neethi/AbstractPolicyOperator.java
index 015c8b2..bdac65a 100644
--- a/src/main/java/org/apache/neethi/AbstractPolicyOperator.java
+++ b/src/main/java/org/apache/neethi/AbstractPolicyOperator.java
@@ -33,6 +33,15 @@ import org.apache.neethi.util.PolicyComparator;
  */
 public abstract class AbstractPolicyOperator implements PolicyOperator {
     protected List<PolicyComponent> policyComponents = new ArrayList<PolicyComponent>();
+
+    /**
+     * Maximum number of normalised alternatives (All nodes inside the outermost
+     * ExactlyOne) that policy normalization is permitted to produce.  Crafted
+     * WS-Policy documents can trigger an exponential Cartesian cross-product that
+     * exhausts the JVM heap; this cap converts that unbounded allocation into a
+     * fast, predictable RuntimeException.
+     */
+    private static final int MAX_ALTERNATIVES = 10_000;
     
     public AbstractPolicyOperator() {
         
@@ -233,6 +242,13 @@ public abstract class AbstractPolicyOperator implements PolicyOperator {
                 crossProductAll.addPolicyComponents(currentAll1.getPolicyComponents());
                 crossProductAll.addPolicyComponents(currentAll2.getPolicyComponents());
                 crossProduct.addPolicyComponent(crossProductAll);
+
+                if (crossProduct.getPolicyComponents().size() > MAX_ALTERNATIVES) {
+                    throw new RuntimeException(
+                        "Policy normalization exceeded the maximum number of alternatives ("
+                        + MAX_ALTERNATIVES + "). The policy may be crafted to cause "
+                        + "Algorithmic Complexity DoS via exponential cross-product expansion.");
+                }
             }
         }