You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by ak...@apache.org on 2026/05/22 20:14:59 UTC
(tooling-agents) branch main updated: Adjusting severity guidance to align with https://security.apache.org/blog/severityrating/ (#43)
This is an automated email from the ASF dual-hosted git repository.
andrewmusselman pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-agents.git
The following commit(s) were added to refs/heads/main by this push:
new c254bcb Adjusting severity guidance to align with https://security.apache.org/blog/severityrating/ (#43)
c254bcb is described below
commit c254bcbf03ac921e90eb935b037dfdf11dd4c9fe
Author: Andrew Musselman <ak...@apache.org>
AuthorDate: Fri May 22 13:14:54 2026 -0700
Adjusting severity guidance to align with https://security.apache.org/blog/severityrating/ (#43)
Tested on atr and mina, looks good.
---
ASVS/agents/asvs_audit.py | 261 +++++++++++++++++++++++++++++++++++----------
ASVS/agents/asvs_bundle.py | 103 ++++++++++++++----
2 files changed, 291 insertions(+), 73 deletions(-)
diff --git a/ASVS/agents/asvs_audit.py b/ASVS/agents/asvs_audit.py
index 86ce709..9648781 100644
--- a/ASVS/agents/asvs_audit.py
+++ b/ASVS/agents/asvs_audit.py
@@ -69,11 +69,11 @@ async def run(input_dict, tools):
- `**Severity:** Medium` / `**Severity**: High`
"""
import re
- counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0}
+ counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "Info": 0}
# Primary: count Finding IDs and classify each by its severity token
finding_ids = re.findall(
- r'ASVS-\d+-(CRIT(?:ICAL)?|HIGH|MED(?:IUM)?|LOW)-\d+',
+ r'ASVS-\d+-(CRIT(?:ICAL)?|HIGH|MED(?:IUM)?|LOW|INFO(?:RMATIONAL)?)-\d+',
content, re.IGNORECASE,
)
for sev_token in finding_ids:
@@ -86,13 +86,16 @@ async def run(input_dict, tools):
counts["Medium"] += 1
elif token_upper == "LOW":
counts["Low"] += 1
+ elif token_upper.startswith("INFO"):
+ counts["Info"] += 1
if sum(counts.values()) > 0:
return counts
# Fallback 1: severity headings at any heading depth, with or without brackets
for sev_name, key in [("critical", "Critical"), ("high", "High"),
- ("medium", "Medium"), ("low", "Low")]:
+ ("medium", "Medium"), ("low", "Low"),
+ ("info", "Info"), ("informational", "Info")]:
pattern = rf'(?im)^#{{1,6}}\s*\[?\s*{sev_name}\s*\]?\s*$'
counts[key] += len(re.findall(pattern, content))
@@ -104,6 +107,7 @@ async def run(input_dict, tools):
counts["High"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*High', content, re.IGNORECASE))
counts["Medium"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*Medium', content, re.IGNORECASE))
counts["Low"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*Low', content, re.IGNORECASE))
+ counts["Info"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*Info(?:rmational)?', content, re.IGNORECASE))
return counts
async def _single_pass_consolidate(results, asvs, asvs_description, provider, model, params):
@@ -845,11 +849,25 @@ FILES:
analysis_system_prompt += f"\n## Domain Context\n{domain_context}\n"
if severity_threshold:
- severity_levels = {"CRITICAL": 4, "HIGH": 3, "MEDIUM": 2, "LOW": 1}
+ severity_levels = {"CRITICAL": 5, "HIGH": 4, "MEDIUM": 3, "LOW": 2, "INFO": 1, "INFORMATIONAL": 1}
threshold_val = severity_levels.get(severity_threshold.upper(), 0)
if threshold_val > 0:
- included = [k for k, v in severity_levels.items() if v >= threshold_val]
- analysis_system_prompt += f"\n## Severity Threshold\nReport findings at these severity levels and ONLY these: {', '.join(included)}.\nFindings at lower severities ({severity_threshold.upper()}-below) should be omitted entirely.\nDo NOT bias toward {severity_threshold.upper()} as the default — CRITICAL findings (Type B/C/D gaps per the rules below) are equally in scope and must be reported as CRITICAL when the gap-type rule applies.\n"
+ included_set = {k for k, v in severity_levels.items() if v >= threshold_val}
+ # Collapse INFO/INFORMATIONAL aliases for display
+ included_set.discard("INFORMATIONAL")
+ included = sorted(included_set, key=lambda k: -severity_levels[k])
+ analysis_system_prompt += (
+ f"\n## Severity Threshold\n"
+ f"Report findings at these severity levels and ONLY these: "
+ f"{', '.join(included)}.\n"
+ f"Findings below {severity_threshold.upper()} should be omitted entirely.\n"
+ f"Do NOT bias toward {severity_threshold.upper()} as the default. "
+ f"Every finding's severity is determined by the ASF Severity Calibration "
+ f"below — assign Critical when the calibration supports Critical, assign "
+ f"Low when the calibration supports Low. Severity follows the actual "
+ f"exploit path and impact, never the gap shape, CWE category, or ASVS "
+ f"section alone.\n"
+ )
if false_positive_guidance:
guidance_text = "\n".join(f"- {g}" for g in false_positive_guidance)
@@ -947,48 +965,143 @@ For each security control found:
- Document where it's DEFINED
- Map ALL entry points that should use it
- Verify it's actually CALLED at each entry point
-- Flag coverage gaps (control exists but not applied = CRITICAL)
-
-### Gap Type Classification — severity is DETERMINED by gap type, not your judgment
-
-For EVERY finding you produce, first classify the gap type, then assign severity
-according to the rules below. You do not have discretion to override these.
+- Flag coverage gaps where the control exists but is not applied
+
+### Severity Calibration — Apache Software Foundation criteria
+
+Severity follows the ASF Security Team's published criteria. These are the
+authoritative definitions for ASF projects and override any tendency to rate
+findings by CWE category, ASVS section, or gap shape alone.
+
+**Critical** — easily exploited by a remote unauthenticated attacker, leads
+to arbitrary code execution or full system compromise, requires no user
+interaction. A finding is NOT Critical if exploitation requires any of:
+authentication of any kind, local or physical access, an unlikely
+configuration, user interaction (clicking a link, opening a file), prior
+compromise of another component, or a specific runtime race window that is
+unlikely under normal load. Code execution only — "could lead to compromise"
+is not Critical.
+
+**High** (ASF "Important") — easily compromises confidentiality, integrity,
+or availability under realistic conditions. Includes:
+- Local or authenticated user gains additional privileges
+- Unauthenticated remote user views resources that should be
+ authentication-protected
+- Authenticated remote user achieves arbitrary code execution
+- Remote user causes denial of service
+A real attacker capability AND a real C/I/A impact must both be present.
+Control bypass or gap that does not itself compromise C/I/A is not High by
+default — see Medium.
+
+**Medium** (ASF "Moderate") — could compromise C/I/A under certain
+circumstances. Includes:
+- Findings that would be Critical or High but require more difficult
+ exploit conditions
+- Findings affecting unlikely configurations
+- Findings with limited scope of impact
+- Control bypass that requires application-layer cooperation to convert
+ into actual harm
+- Foot-guns: insecure defaults the operator can fix, documented but easy
+ to misuse, behaviors that surprise downstream consumers
+
+**Low** — security-relevant but minimal consequences or unlikely
+circumstances. Includes:
+- Defense-in-depth gaps where another layer prevents exploitation
+- Documentation deficiencies that do not themselves enable exploitation
+- Dead dependency pins (artifact pinned in dependencyManagement but not
+ on any classpath)
+- Hardening recommendations without a concrete current exploit path
+- Library-improvement suggestions that would be nice to have but are not
+ vulnerabilities
+
+**Informational** — observations with security relevance that do not
+constitute vulnerabilities. Documentation gaps governed by foundation-level
+processes (e.g., ASF Security Team handles vulnerability response for all
+ASF projects) typically rate Informational rather than Low. Also used for
+hardening suggestions and architectural observations the project may want
+to consider but is under no obligation to act on.
+
+### Severity calibration questions — answer these before assigning severity
+
+For every finding, answer these three questions explicitly. The answers
+determine severity per the ASF definitions above.
+
+1. **What attacker capability does this require?**
+ - Remote, unauthenticated, no prior access → Critical/High territory
+ - Authenticated user, any role → High/Medium
+ - Privileged user, administrator, or local/physical access → Medium/Low
+ - Specific unusual configuration the operator opted into → Medium/Low
+
+2. **What does successful exploitation achieve?**
+ - Arbitrary code execution or full system compromise → Critical/High
+ - Privilege escalation → High
+ - Unauthorized data read or modification → High/Medium depending on
+ scope and sensitivity
+ - Denial of service → High/Medium depending on conditions
+ - Information disclosure → High/Medium/Low depending on what is disclosed
+ - Control bypass with no direct C/I/A impact → Medium/Low (the bypass
+ itself is not the harm; if downstream harm requires application-layer
+ cooperation, this is Medium at most)
+
+3. **How easy is exploitation in default deployment?**
+ - Trivially exploitable in default configuration → push severity up
+ - Requires specific application-layer pattern or operator misconfiguration
+ → push severity down
+ - Requires unlikely runtime conditions or attacker preconditions
+ → push severity down
+
+If the answers do not justify Critical or High under the ASF criteria, the
+severity must be lower — even when the finding's *shape* looks like a Type
+B/C/D control-flow gap. Shape and impact are different questions.
+
+### Gap Type Classification — pattern detection, not severity assignment
+
+These patterns help recognize SHAPES of findings. They do NOT by themselves
+determine severity. After classifying the gap shape, apply the calibration
+questions above to assign severity per the ASF criteria.
**Type A — Entry point with NO control**
- Severity: HIGH (or LOW/MEDIUM if impact is minor)
- Finding ID format: `ASVS-{asvs.replace('.', '')}-HIGH-NNN`
- Example: an endpoint accepts user input and concatenates it directly into a
- shell command — no validation anywhere → Type A → HIGH.
+ Shape: input reaches a sensitive sink without going through any
+ validation, authorization, or encoding step.
+ Example: an endpoint accepts user input and concatenates it directly
+ into a shell command — no validation anywhere.
**Type B — Control EXISTS but is NOT CALLED at this entry point**
- Severity: **CRITICAL** (false confidence — operators believe protected, aren't)
- Finding ID format: `ASVS-{asvs.replace('.', '')}-CRIT-NNN`
- Example: a login endpoint validates passwords, but a `try: ... except JSONDecodeError: pass`
- block silently skips validation when the body is malformed → control exists,
- not called → **CRITICAL, not High**.
- Example: `is_authorized_pool` exists and works, but the auth check is wrapped in
- `with suppress(JSONDecodeError):` so it's bypassed on parse failure → **CRITICAL**.
+ Shape: the codebase has the control defined; some other entry points use
+ it; this entry point does not. May produce false confidence — operators
+ believe they are protected; they are not.
+ Example: a login endpoint validates passwords, but a `try: ... except
+ JSONDecodeError: pass` block silently skips validation when the body is
+ malformed.
**Type C — Control CALLED but RESULT IGNORED**
- Severity: **CRITICAL** (work performed without consequence)
- Finding ID format: `ASVS-{asvs.replace('.', '')}-CRIT-NNN`
- Example: auth backend returns "access denied" but caller treats this identically
- to "not found" and falls through to the next backend → **CRITICAL, not High**.
- Example: token revocation list is checked but the result is logged-only and
- doesn't actually reject the request → **CRITICAL**.
+ Shape: the control runs but its decision is discarded.
+ Example: authorization backend returns "access denied" but the caller
+ treats this identically to "not found" and falls through to the next
+ backend. Example: revocation list checked but the result is logged-only
+ and doesn't reject the request.
**Type D — Control CALLED but AFTER the sensitive operation**
- Severity: **CRITICAL** (control runs too late to prevent harm)
- Finding ID format: `ASVS-{asvs.replace('.', '')}-CRIT-NNN`
- Example: SQL query is executed and THEN the parameter is validated → **CRITICAL**.
- Example: file is written to disk, then path traversal check runs → **CRITICAL**.
-
-**Hard rule:** If your finding's description includes phrases like "control exists
-but not called", "control called but result ignored", "validation skipped",
-"check bypassed", "silently fails", "exception suppressed", or "Type B/C/D" —
-the Finding ID MUST use the `CRIT` token, NOT `HIGH`. There is no case where
-a Type B/C/D gap should be marked HIGH. This is the most common failure mode
-in audits and you must guard against it.
+ Shape: order of operations puts the sensitive sink before the control
+ that should have gated it.
+ Example: SQL query executed THEN the parameter validated. Example: file
+ written to disk, then path traversal check runs.
+
+**Gap shape sets a ceiling on plausibility, not a floor on severity.**
+A Type B/C/D gap can justify Critical when the calibration questions yield
+"remote, unauthenticated, default configuration, arbitrary code execution."
+A Type B/C/D gap that requires authenticated access and yields only control
+bypass without direct C/I/A impact rates Medium at most. A Type B/C/D gap
+where the bypass enables information disclosure of low-sensitivity data
+rates Low.
+
+**Hard rule:** severity follows the ASF Severity Calibration above, not
+the gap shape. Do not auto-elevate gap-shape findings to Critical without
+verifying the calibration supports it. The most common audit failure mode
+is rating control-flow gaps as Critical because the SHAPE looks severe,
+when the actual exploit path does not match ASF Critical criteria. Type
+B/C/D shape detection is useful evidence for analysis; it is not a
+severity rule.
### Related Function Analysis
When you find a vulnerability, IMMEDIATELY search for:
@@ -1015,31 +1128,69 @@ Do NOT report:
### Output Requirements
For each finding, provide:
-- Severity level (CRITICAL/HIGH/MEDIUM/LOW) — determined by the Gap Type rules above, not your discretion
-- Finding ID using ONE of these exact formats based on severity:
- - `ASVS-{asvs.replace('.', '')}-CRIT-NNN` for Critical (Type B/C/D gaps)
+- Severity level (CRITICAL/HIGH/MEDIUM/LOW/INFO) — assigned per the ASF
+ Severity Calibration above, applied to the answers from the calibration
+ questions. NOT determined by gap shape alone, CWE category, or ASVS
+ section.
+- Finding ID using ONE of these exact formats, where the token matches the
+ assigned severity:
+ - `ASVS-{asvs.replace('.', '')}-CRIT-NNN` for Critical
- `ASVS-{asvs.replace('.', '')}-HIGH-NNN` for High
- `ASVS-{asvs.replace('.', '')}-MED-NNN` for Medium
- `ASVS-{asvs.replace('.', '')}-LOW-NNN` for Low
+ - `ASVS-{asvs.replace('.', '')}-INFO-NNN` for Informational
- Exact file location and function name with line numbers
- Vulnerable code quote
- Data flow (source → sink → missing control)
-- Proof of concept (specific malicious request)
-- Impact description
+- Attacker capability required — the answer to calibration question 1
+ (e.g., "remote unauthenticated", "authenticated user", "local access",
+ "administrator with config access")
+- Impact on success — the answer to calibration question 2 (e.g., "RCE",
+ "data read", "DoS", "control bypass with no direct C/I/A impact")
+- Proof of concept (specific malicious request or trigger) — REQUIRED for
+ Critical and High findings; if you cannot construct one that matches
+ the stated attacker capability, the finding likely does not warrant
+ Critical or High under ASF criteria — downgrade
- Remediation with code example
### Final Severity Pass — DO THIS BEFORE EMITTING OUTPUT
-After you've drafted all findings, walk back through them once more:
-1. For each finding marked HIGH, re-read its own description.
-2. If the description says or implies the control exists somewhere but is not
- reached, not called, bypassed, suppressed, called-but-ignored, or called-too-late —
- that is a Type B/C/D gap. Change the severity to CRITICAL and the Finding ID
- token from HIGH to CRIT.
-3. If the description says no such control exists at all — leave it as HIGH.
-
-This pass is not optional. The most common audit failure is marking Type B/C/D
-gaps as HIGH out of caution. Your job is to apply the rule, not to be cautious.
+After drafting all findings, walk back through them once more and verify
+the calibration on each:
+
+1. For each finding marked Critical, confirm the exploit chain reaches
+ arbitrary code execution starting from a remote unauthenticated
+ attacker with no user interaction and a default configuration. If any
+ link in the chain requires authentication, local access, user
+ interaction, prior compromise, or unusual configuration, downgrade
+ the severity per the ASF criteria (most often to High or Medium).
+
+2. For each finding marked High, confirm a real attacker capability AND
+ a real C/I/A impact are BOTH present. A control bypass that requires
+ application-layer cooperation to cause actual harm is Medium, not
+ High. A finding rated High where you cannot construct a concrete PoC
+ for the claimed attacker capability is likely Medium or Low.
+
+3. For each finding marked Medium or Low, confirm the calibration
+ questions produced answers consistent with that tier. Don't be
+ cautious and rate higher than the calibration supports; don't be
+ conservative and rate lower than it supports.
+
+4. Documentation-gap findings (e.g., ASVS "documentation must define X"
+ requirements) rate Low or Informational, not Medium. If the
+ documentation gap is governed by a foundation-level process
+ (ASF Security Team for ASF projects), rate Informational.
+
+5. Dependency findings: if the vulnerable artifact is not actually on
+ any classpath at runtime (e.g., declared in dependencyManagement but
+ not pulled by any module), rate Low regardless of the CVE's CVSS
+ score. The CVE rates the vulnerable code; a dead pin doesn't run
+ the code.
+
+This pass exists because the most common audit failure is rating
+findings by their pattern (Type B/C/D shape, CWE class, ASVS section,
+CVE CVSS) rather than by their actual exploit path and impact. Apply
+the calibration; do not pattern-match.
Also provide:
- Security Controls Inventory with coverage analysis
diff --git a/ASVS/agents/asvs_bundle.py b/ASVS/agents/asvs_bundle.py
index 0665983..65cd189 100644
--- a/ASVS/agents/asvs_bundle.py
+++ b/ASVS/agents/asvs_bundle.py
@@ -96,11 +96,11 @@ async def run(input_dict, tools):
- `**Severity:** Medium` / `**Severity**: High`
"""
import re
- counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0}
+ counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "Info": 0}
# Primary: count Finding IDs and classify each by its severity token
finding_ids = re.findall(
- r'ASVS-\d+-(CRIT(?:ICAL)?|HIGH|MED(?:IUM)?|LOW)-\d+',
+ r'ASVS-\d+-(CRIT(?:ICAL)?|HIGH|MED(?:IUM)?|LOW|INFO(?:RMATIONAL)?)-\d+',
content, re.IGNORECASE,
)
for sev_token in finding_ids:
@@ -113,13 +113,16 @@ async def run(input_dict, tools):
counts["Medium"] += 1
elif token_upper == "LOW":
counts["Low"] += 1
+ elif token_upper.startswith("INFO"):
+ counts["Info"] += 1
if sum(counts.values()) > 0:
return counts
# Fallback 1: severity headings at any heading depth, with or without brackets
for sev_name, key in [("critical", "Critical"), ("high", "High"),
- ("medium", "Medium"), ("low", "Low")]:
+ ("medium", "Medium"), ("low", "Low"),
+ ("info", "Info"), ("informational", "Info")]:
pattern = rf'(?im)^#{{1,6}}\s*\[?\s*{sev_name}\s*\]?\s*$'
counts[key] += len(re.findall(pattern, content))
@@ -131,6 +134,7 @@ async def run(input_dict, tools):
counts["High"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*High', content, re.IGNORECASE))
counts["Medium"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*Medium', content, re.IGNORECASE))
counts["Low"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*Low', content, re.IGNORECASE))
+ counts["Info"] += len(re.findall(r'\*\*Severity:?\*\*:?\s*Info(?:rmational)?', content, re.IGNORECASE))
return counts
def _split_bundled_output(consolidated_analysis, asvs_sections, asvs_descriptions,
@@ -954,10 +958,12 @@ You are auditing the code below against ALL of the following requirements. For E
analysis_system_prompt += f"\n## Domain Context\n{domain_context}\n"
if severity_threshold:
- severity_levels = {"CRITICAL": 4, "HIGH": 3, "MEDIUM": 2, "LOW": 1}
+ severity_levels = {"CRITICAL": 5, "HIGH": 4, "MEDIUM": 3, "LOW": 2, "INFO": 1, "INFORMATIONAL": 1}
threshold_val = severity_levels.get(severity_threshold.upper(), 0)
if threshold_val > 0:
- included = [k for k, v in severity_levels.items() if v >= threshold_val]
+ included_set = {k for k, v in severity_levels.items() if v >= threshold_val}
+ included_set.discard("INFORMATIONAL")
+ included = sorted(included_set, key=lambda k: -severity_levels[k])
analysis_system_prompt += f"\n## Severity Threshold\nOnly report findings at these severity levels: {', '.join(included)}.\nDo not include findings below {severity_threshold.upper()} severity.\n"
if false_positive_guidance:
@@ -1066,15 +1072,75 @@ For each security control found:
- Document where it's DEFINED
- Map ALL entry points that should use it
- Verify it's actually CALLED at each entry point
-- Flag coverage gaps (control exists but not applied = CRITICAL)
-
-### Gap Type Classification
-| Gap Type | Description | Severity |
-|----------|-------------|----------|
-| Type A | Entry point with NO control | Standard vulnerability |
-| Type B | Control EXISTS but NOT CALLED | CRITICAL (false confidence) |
-| Type C | Control CALLED but RESULT IGNORED | CRITICAL |
-| Type D | Control CALLED but AFTER sensitive operation | CRITICAL |
+- Flag coverage gaps where the control exists but is not applied
+
+### Severity Calibration — Apache Software Foundation criteria
+
+Severity follows the ASF Security Team's published criteria for ASF projects.
+These override any default tendency to rate findings by CWE category, ASVS
+section, or gap shape alone.
+
+- **Critical** — easily exploited by a remote unauthenticated attacker,
+ leads to RCE or full system compromise, no user interaction. NOT
+ Critical if exploitation requires authentication, local/physical access,
+ unusual configuration, user interaction, or prior compromise.
+- **High** (ASF Important) — easily compromises C/I/A under realistic
+ conditions: local/auth user gains privileges, unauth remote user views
+ authentication-protected resources, auth remote user achieves RCE,
+ remote user causes DoS. Requires both a real attacker capability AND
+ a real C/I/A impact.
+- **Medium** (ASF Moderate) — could compromise C/I/A under certain
+ circumstances: more difficult to exploit, unlikely configuration,
+ limited scope, or control bypass that requires application-layer
+ cooperation to cause real harm. Foot-guns and easy-to-misuse defaults
+ belong here.
+- **Low** — security-relevant but minimal consequences or unlikely
+ circumstances: defense-in-depth gaps where another layer prevents
+ exploitation, documentation deficiencies that don't enable exploit,
+ dead dependency pins, hardening recommendations without a concrete
+ exploit path, nice-to-have library improvements.
+- **Informational** — observations with security relevance that do not
+ constitute vulnerabilities. Documentation gaps governed by
+ foundation-level processes (e.g., ASF Security Team for ASF projects)
+ rate Informational.
+
+### Severity calibration — apply per finding
+
+For every finding, answer three questions before assigning severity:
+1. **Attacker capability required** — remote unauth (Critical/High) /
+ authenticated (High/Medium) / privileged or local (Medium/Low) /
+ specific unusual configuration (Medium/Low).
+2. **What success achieves** — RCE (Critical/High) / priv esc (High) /
+ data access (High/Medium) / DoS (High/Medium) / info disclosure
+ (varies by sensitivity) / control bypass with no direct C/I/A impact
+ (Medium/Low).
+3. **Exploitability in default deployment** — trivially exploitable in
+ default config pushes up; requires app-layer cooperation or unusual
+ conditions pushes down.
+
+If the answers do not justify Critical or High under ASF criteria, the
+severity is lower — even when the finding's shape looks like a control-
+flow gap.
+
+### Gap Type Classification — pattern detection, not severity assignment
+
+These shapes help recognize what KIND of finding you have. They do NOT
+by themselves determine severity. After classifying the shape, apply the
+calibration questions above.
+
+| Gap Type | Description |
+|----------|-------------|
+| Type A | Entry point with NO control |
+| Type B | Control EXISTS but NOT CALLED at this entry point |
+| Type C | Control CALLED but RESULT IGNORED |
+| Type D | Control CALLED but AFTER the sensitive operation |
+
+Gap shape sets a ceiling on plausibility, not a floor on severity. A
+Type B/C/D gap rates Critical only when the calibration questions yield
+"remote unauthenticated RCE in default configuration." A Type B/C/D gap
+that requires authenticated access and yields only control bypass without
+direct C/I/A impact rates Medium at most. Do not auto-elevate gap-shape
+findings to Critical without verifying the calibration supports it.
### Related Function Analysis
When you find a vulnerability, IMMEDIATELY search for:
@@ -1133,13 +1199,14 @@ After ALL per-requirement sections, end with two cross-cutting sections:
```
For each finding within a section, provide:
-- Severity level: CRITICAL, HIGH, MEDIUM, or LOW (in a `### [SEVERITY]` header)
-- Finding ID: ASVS-{section_no_dots}-SEV-NNN (e.g. ASVS-512-CRIT-001)
+- Severity level: CRITICAL, HIGH, MEDIUM, LOW, or INFO (in a `### [SEVERITY]` header) — assigned per the ASF Severity Calibration above
+- Finding ID: ASVS-{section_no_dots}-SEV-NNN (e.g. ASVS-512-CRIT-001; SEV token is one of CRIT, HIGH, MED, LOW, INFO matching the assigned severity)
- Exact file location and function name with line numbers
- Vulnerable code quote (a fenced code block)
- Data flow: source → sink → missing control
-- Proof of concept: a specific malicious request or input
-- Impact description
+- Attacker capability required (answer to calibration question 1)
+- Impact on success (answer to calibration question 2)
+- Proof of concept: a specific malicious request or input — required for Critical and High; if you cannot construct one consistent with the stated attacker capability, downgrade
- Remediation with code example
Be thorough but precise. If something is done correctly, acknowledge it as a positive pattern — don't invent issues."""
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org