This is a master-key flaw hidden behind the admin office door
Available public clues point to alf.io extension-script sandbox escape leading to authenticated RCE. The extension system lets an Administrator upload JavaScript that runs inside the app when events fire; public project docs say extensions can only be added or modified by the Administrator, and a later upstream pull request replaced the Rhino-based engine and removed custom sandbox code. A secondary source ties CVE-2026-35482 to versions before 2.0-M5-2606; I could not confirm a first-party advisory page for the exact CVE, so treat that version range as medium-confidence rather than fully authoritative.
The vendor's HIGH / 8.0 baseline is technically defensible if you score the end state in a vacuum: successful exploitation appears to cross from app-level admin into server-side code execution. In the real world, though, this is a post-compromise / post-admin bug with high attack complexity, no public in-the-wild signal, and a relatively narrow deployment population. For most enterprise patch queues, that pushes it down to MEDIUM unless you routinely delegate alf.io admin rights to semi-trusted event staff or expose the admin surface broadly to the internet.
3 steps from start to impact.
Get an alf.io administrator session
- Reachability to the alf.io admin interface
- Valid alf.io Administrator privileges
- Extensions feature available to that admin account
- Requires authenticated remote access with high privileges
- If admin auth is behind SSO, MFA, or VPN, the attacker is already several steps into the kill chain
- Many orgs have very few alf.io admins, reducing targetable population
Upload or edit a malicious extension script
- Administrator can access extension management
- Target instance actually permits custom extensions
- Vulnerable Rhino/custom-sandbox implementation present
- Not all deployments use extensions operationally
- Exploit development is AC:H: attacker must understand the exposed host bindings and sandbox escape path
- Custom builds and backports may already have removed Rhino even if the version string is ambiguous
Trigger script execution and escape to host context
- A supported event must fire or be triggerable
- Sandbox escape primitives must succeed on that exact build
- Server process permissions must allow useful post-exploit actions
- Host blast radius is bounded by the alf.io service account's OS permissions
- Containerized deployments with tight filesystem/network policies can materially limit payoff
- EDR on the host may stop child-process or suspicious outbound behavior even after the escape
The supporting signals.
| In-the-wild status | No public exploitation evidence found in accessible sources reviewed; not KEV-listed. |
|---|---|
| Proof-of-concept availability | No dedicated public PoC located. However, the attack concept is materially informed by the public extension model and the upstream Rhino-to-QuickJS sandbox rework in PR #1512. |
| EPSS | No CVE-specific EPSS record located in accessible public sources at review time, so I am not using EPSS as an amplifier here. |
| KEV status | Not listed in CISA's Known Exploited Vulnerabilities Catalog. User-provided intel says KEV: No; public review agrees. |
| CVSS vector readout | CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:H/I:H/A:H means network-reachable but high-complexity and high-privilege. The decisive suppressor is PR:H: this is not an outsider bug. |
| Affected versions | Medium-confidence: secondary source indicates alf.io < 2.0-M5-2606. I could not verify the exact first-party advisory page for this CVE. |
| Fixed version | Medium-confidence: secondary source indicates 2.0-M5-2606. Upstream code history also shows a major sandbox hardening change on 2026-04-14 in PR #1512. |
| Exposure / scanning data | No reliable product-specific GreyNoise/Shodan/Censys campaign signal located for this CVE or for a distinctive alf.io internet fingerprint. Treat internet-facing admin UIs as a local exposure problem, not a mass-exploitation trend. |
| Disclosure date | 2026-06-02 per the intel block and corroborating secondary indexing. |
| Researcher / reporting org | Not determined from accessible authoritative sources. |
noisgate verdict.
The decisive factor is existing alf.io Administrator access. This bug may end in real host-level code execution, but it is still a post-admin escape inside a niche extension subsystem, which sharply narrows the reachable population compared with a true perimeter RCE.
Why this verdict
- Downgrade for attacker position: the CVSS already says
PR:H, and the public extension docs say scripts can be added or modified only by the Administrator. That means the attacker is already in a privileged application role before the CVE even starts to matter. - Downgrade for exposure population: alf.io is a niche self-hosted event platform, not a ubiquitous enterprise edge service. The affected population is much smaller than Exchange, PAN-OS, Confluence, or Citrix-class backlog killers.
- Downgrade for operational friction: exploitation appears to require the extension subsystem plus a working sandbox escape against the Rhino/custom-wrapper implementation. That is materially more brittle than one-request unauth RCE.
- Keep it at MEDIUM, not LOW: if the escape works, the impact likely crosses from app admin into server execution context (
S:C, high CIA). That is a real boundary jump, not harmless feature abuse. - No threat-intel amplifier: no KEV listing, no public campaign evidence, and no public PoC I could validate. Without those accelerants, this does not earn a 'drop-everything' slot.
Why not higher?
Because this is not a perimeter bug. It assumes authenticated remote access, high privileges, and use of a specific extension feature, which compounds downward pressure at every stage of the kill chain. In a 10,000-host patch program, that profile does not compete with remotely reachable low-friction CVEs that attackers can hit before they own an account.
Why not lower?
Because the end state still matters: a successful sandbox escape appears to transform an application admin foothold into code execution on the alf.io host. That can expose database credentials, payment integrations, secrets, and downstream infrastructure access, so writing it off as mere backlog lint would be too casual.
What to do — in priority order.
- Lock down alf.io admin reachability — Put the admin UI behind VPN, IP allowlists, or SSO access policy so the already-required
PR:Hprerequisite gets even harder to satisfy. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but this is worth doing immediately if your admin surface is internet-exposed. - Restrict extension management to a tiny trusted set — Reconfirm that only the smallest possible set of operators holds the Administrator role and can touch extensions. There is no mitigation SLA — go straight to the 365-day remediation window; this control matters most where event staff or contractors have elevated app roles.
- Disable or remove custom extensions if unused — If your deployment does not need custom JS extensions, remove them or disable the workflow so the exploit path disappears entirely. There is no mitigation SLA — go straight to the 365-day remediation window, but this is the cleanest temporary risk reduction.
- Constrain the service account — Run alf.io with a non-privileged OS account, minimal filesystem access, and tightly scoped outbound network rules so a successful escape has less post-exploit payoff. There is no mitigation SLA — go straight to the 365-day remediation window; use this to shrink blast radius where patch lead times are slow.
- Alert on extension changes and Java child processes — Monitor admin actions that create or edit extensions and pair them with EDR rules for the Java service spawning shells, script interpreters, or network tools. There is no mitigation SLA — go straight to the 365-day remediation window; this is detective coverage, not a substitute for the fix.
- A generic WAF is not a dependable answer; the exploit path is authenticated, application-specific, and likely rides legitimate admin workflows rather than a clean malicious request pattern.
- External vuln scanning alone will not prove safety; this is a feature-and-role-dependent sandbox issue, not something banner grabs reliably validate.
- Network segmentation by itself does not solve it if admins legitimately reach the UI from segmented networks; the trust problem is the admin role plus extension execution.
Crowdsourced verification payload.
Run this on the alf.io application host as a user that can read the WAR/JAR file and, if you want auto-discovery, inspect Java process command lines. Example: sudo bash verify-cve-2026-35482.sh /opt/alfio/alfio-2.0-M5-2509-1-boot.war. It needs only local read access; root is helpful but not strictly required.
#!/usr/bin/env bash
# verify-cve-2026-35482.sh
# Checks whether a local alf.io deployment appears vulnerable to CVE-2026-35482
# Logic:
# - If version is detectable and < 2.0-M5-2606 => VULNERABLE
# - If version is detectable and >= 2.0-M5-2606 => PATCHED
# - If version is unclear, fall back to artifact inspection:
# * Rhino present and QuickJS absent => VULNERABLE
# * QuickJS present and Rhino absent => PATCHED
# * otherwise => UNKNOWN
# Exit codes:
# 0 PATCHED
# 1 VULNERABLE
# 2 UNKNOWN
set -u
FIX_MILESTONE=2606
TARGET="${1:-}"
FOUND=""
find_candidate() {
if [[ -n "$TARGET" && -e "$TARGET" ]]; then
echo "$TARGET"
return 0
fi
# Common install locations / filenames
for p in \
/opt/alfio/*.war /opt/alfio/*.jar \
/srv/alfio/*.war /srv/alfio/*.jar \
/var/lib/alfio/*.war /var/lib/alfio/*.jar \
./alfio*.war ./alfio*.jar; do
for f in $p; do
[[ -e "$f" ]] && { echo "$f"; return 0; }
done
done
# Try to discover from running Java process
local cmd
cmd=$(ps -eo args 2>/dev/null | grep -E 'alfio|boot\.war|spring-boot' | grep -v grep | head -n1 || true)
if [[ -n "$cmd" ]]; then
for token in $cmd; do
if [[ "$token" == *.war || "$token" == *.jar ]]; then
[[ -e "$token" ]] && { echo "$token"; return 0; }
fi
done
fi
return 1
}
extract_version() {
local f="$1"
local base ver manifest
base=$(basename "$f")
# Try filename first
if [[ "$base" =~ ([0-9]+\.[0-9]+-M[0-9]+-[0-9]+(-[0-9]+)?) ]]; then
echo "${BASH_REMATCH[1]}"
return 0
fi
# Then try manifest / pom properties inside jar/war
if command -v unzip >/dev/null 2>&1; then
manifest=$(unzip -p "$f" META-INF/MANIFEST.MF 2>/dev/null | grep -Ei '^(Implementation-Version|Bundle-Version|Specification-Version):' | head -n1 | cut -d: -f2- | xargs || true)
if [[ "$manifest" =~ ^[0-9]+\.[0-9]+-M[0-9]+-[0-9]+(-[0-9]+)?$ ]]; then
echo "$manifest"
return 0
fi
manifest=$(unzip -p "$f" BOOT-INF/classes/application.properties 2>/dev/null | grep -E '^alfio.version=' | head -n1 | cut -d= -f2- | xargs || true)
if [[ "$manifest" =~ ^[0-9]+\.[0-9]+-M[0-9]+-[0-9]+(-[0-9]+)?$ ]]; then
echo "$manifest"
return 0
fi
fi
return 1
}
# Compare only the milestone/build family we care about.
# Returns 0 if version >= fixed version, 1 if < fixed version, 2 if unknown.
version_is_patched() {
local ver="$1"
local main major minor milestone build
# Expected examples: 2.0-M4-2407, 2.0-M5-2509-1, 2.0-M5-2606
if [[ ! "$ver" =~ ^([0-9]+)\.([0-9]+)-M([0-9]+)-([0-9]+)(-[0-9]+)?$ ]]; then
return 2
fi
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
milestone="${BASH_REMATCH[3]}"
build="${BASH_REMATCH[4]}"
# Any M4 or earlier is vulnerable based on public clues.
if (( milestone < 5 )); then
return 1
fi
if (( milestone > 5 )); then
return 0
fi
# M5: compare build family against 2606
if (( build >= FIX_MILESTONE )); then
return 0
else
return 1
fi
}
inspect_runtime_engine() {
local f="$1"
local listing rhino quickjs
if ! command -v unzip >/dev/null 2>&1; then
return 2
fi
listing=$(unzip -l "$f" 2>/dev/null || true)
echo "$listing" | grep -Eiq 'org/mozilla/javascript|rhino' && rhino=1 || rhino=0
echo "$listing" | grep -Eiq 'quickjs|quickjs4j|chicory' && quickjs=1 || quickjs=0
if [[ $rhino -eq 1 && $quickjs -eq 0 ]]; then
return 1
fi
if [[ $quickjs -eq 1 && $rhino -eq 0 ]]; then
return 0
fi
return 2
}
main() {
local artifact version
artifact=$(find_candidate) || {
echo "UNKNOWN - Could not locate an alf.io WAR/JAR. Provide the artifact path explicitly."
exit 2
}
FOUND="$artifact"
version=$(extract_version "$artifact" || true)
if [[ -n "$version" ]]; then
version_is_patched "$version"
case $? in
0)
echo "PATCHED - Detected alf.io artifact '$FOUND' with version '$version' (>= 2.0-M5-2606)."
exit 0
;;
1)
echo "VULNERABLE - Detected alf.io artifact '$FOUND' with version '$version' (< 2.0-M5-2606)."
exit 1
;;
esac
fi
inspect_runtime_engine "$artifact"
case $? in
0)
echo "PATCHED - Version unclear, but artifact '$FOUND' appears to contain QuickJS and not Rhino."
exit 0
;;
1)
echo "VULNERABLE - Version unclear, but artifact '$FOUND' appears to contain Rhino and not QuickJS."
exit 1
;;
*)
echo "UNKNOWN - Found artifact '$FOUND' but could not confidently determine version/runtime engine."
exit 2
;;
esac
}
main "$@"
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.