From 0c134b4119891281f1e5ec9ac14438ff1dc818b8 Mon Sep 17 00:00:00 2001 From: Tugamer89 <61603718+Tugamer89@users.noreply.github.com> Date: Mon, 15 Jun 2026 04:40:37 +0000 Subject: [PATCH] fix(security): [MEDIUM] resolve Denial of Service (DoS) vulnerability in Automaton Builders Added a hard limit of 10,000 max states in `AbstractAutomatonBuilder` during manual automaton construction. Exceeding this limit throws an `IllegalStateException` to prevent unbounded memory allocation and state explosion attacks. Existing states can still be modified without triggering the exception. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .../org/eu/autogex/core/AbstractAutomatonBuilder.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/org/eu/autogex/core/AbstractAutomatonBuilder.java b/src/main/java/org/eu/autogex/core/AbstractAutomatonBuilder.java index baa8c4d6..ea34a502 100644 --- a/src/main/java/org/eu/autogex/core/AbstractAutomatonBuilder.java +++ b/src/main/java/org/eu/autogex/core/AbstractAutomatonBuilder.java @@ -13,6 +13,9 @@ public abstract class AbstractAutomatonBuilder< B extends AbstractAutomatonBuilder, A extends Automaton> { + /** Maximum allowed states to prevent State Explosion (DoS) during manual construction */ + protected static final int MAX_STATES = 10000; + protected final Map states = new HashMap<>(); protected final Set finalStates = new HashSet<>(); protected State initialState; @@ -37,8 +40,15 @@ protected AbstractAutomatonBuilder() { * @param name The name of the state. * @param isFinal True if the state is an accepting state. * @return The current builder instance. + * @throws IllegalStateException if adding the state would exceed MAX_STATES. */ public B addState(String name, boolean isFinal) { + if (states.size() >= MAX_STATES && !states.containsKey(name)) { + throw new IllegalStateException( + "Exceeded maximum allowed states of " + + MAX_STATES + + " (Security: DoS prevention)."); + } State state = new State(name, isFinal); states.put(name, state); if (isFinal) {