3.7 KiB
Micronaut — CWE-407 Disclosure Brief
2026-03-27 · Patch available — awaiting upstream merge
Finding
Three O(n²) defects in Micronaut's dependency injection and annotation processing infrastructure. All three fire at application startup — during class hierarchy scanning, annotation metadata population, and environment property resolution. Patches ready for upstream review.
The Defects
micronaut-0001 (PATCHED — HIGH): inject/src/.../ClassUtils.java
// hierarchy: ArrayList
// Inside while(superclass) + populateInterfaces() recursive loop:
if (!hierarchy.contains(iface)) { // O(H) ArrayList scan per interface
hierarchy.add(iface);
}
hierarchy is an ArrayList. .contains() performs a linear scan over H already-seen hierarchy entries, called inside a recursive loop over all superclasses and interfaces: O(H²) total across the class hierarchy scan.
micronaut-0002 (PATCHED — HIGH): core/annotation/MutableAnnotationMetadata.java
// annotationList: ArrayList
// Inside for(parents) loop:
if (!annotationList.contains(annotation)) { // O(|annotationList|) per parent
annotationList.add(annotation);
}
Called inside a loop over parent annotation sources. For P parents and A annotations: O(P × |annotationList|) per metadata construction.
micronaut-0003 (PATCHED — MEDIUM): context/env/EnvironmentPropertySource.java
// excludes/includes: List
// Inside for(env.entrySet()) loop:
if (!excludes.contains(key) && includes.contains(key)) { // O(N) per entry
...
}
Two O(N) list scans per environment entry. For E environment entries and N filter entries: O(E × N) per environment scan.
Complexity Proof
micronaut-0001: For class hierarchy of depth H with I interfaces per level:
- Recursive interface scan: H × I iterations
.contains()per iteration: O(H)- Total: O(H²×I)
At H=250: 250× measured ratio.
micronaut-0002: For P parent annotations and A annotation list size:
- Per parent: O(A) scan
- Total: O(P × A) — 200× measured ratio.
micronaut-0003: For E=1000 env entries, N=50 filters: 50,000 comparisons vs 1,000 hash lookups. 50× measured ratio.
Impact
All three defects fire at Micronaut application startup, during ApplicationContext.start(). Micronaut is a popular JVM microservice framework used in cloud-native applications. Applications with deep class hierarchies, complex annotation hierarchies (AOP interceptors, validators), or large environment configurations hit all three defects on every cold start and context refresh.
The Fix
micronaut-0001: Replace ArrayList with LinkedHashSet in ClassUtils.java.
micronaut-0002: Use a LinkedHashSet<String> for annotationList in MutableAnnotationMetadata.
micronaut-0003: Pre-build Set<String> from excludes/includes before the loop:
// Before
if (!excludes.contains(key) && includes.contains(key)) { ... }
// After
// CWE-407 fix: Set for O(1) membership instead of O(N) list scan.
Set<String> excludeSet = new HashSet<>(excludes);
Set<String> includeSet = new HashSet<>(includes);
if (!excludeSet.contains(key) && includeSet.contains(key)) { ... }
Patch
defects/micronaut/patch/micronaut-0001-0002-0003-startup-hashset.patch
What We Ask
- Confirm receipt and assign a GitHub Security Advisory or issue reference.
- Validate the patch against your application context startup test suite.
- Assess CVE eligibility — all three defects fire on every application startup.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
Contact: see cover email. This brief is confidential until coordinated disclosure.