Pentesting checks
The Pentesting panel runs a fixed, local-only set of OWASP Top 10:2025-aligned hygiene checks against the host application. This page lists every check that ships with BootUI today, what it inspects, when it fires, and what to do about it.
Each check is a small class registered in PentestingCheckRegistry and implemented in PentestingChecks.java. Both live in the framework-neutral bootui-engine module shared by the adapters. Adding a check means adding one focused class plus a registry entry, never ad-hoc HTTP traffic.
What BootUI does
The scanner combines two bounded evidence sources.
Framework metadata. Spring Environment properties, classpath presence, Spring Security beans, the Spring MVC mapping inventory when MVC is the active runtime, and reflection over registered SecurityFilterChain beans. Quarkus CORS, OIDC, management, and HTTP/TLS configuration is reviewed by the Quarkus Security advisor (QS-*), so on Quarkus this scan relies on the synthetic responses instead of duplicating those static rules. No check ever flags a value that exists only because BootUI injected it; see BootUI's own actuator defaults.
Synthetic HTTP requests. At most two requests per scan, sent directly to the literal loopback address 127.0.0.1 at /<context-path>/__bootui_pentesting__/missing-resource, never at /bootui:
- one
GETwithAccept: text/html - one
OPTIONSpreflight withOrigin: https://evil.exampleandAccess-Control-Request-Method: GET
The application's own response headers reveal its CORS, security-header, and cookie posture. Each request times out after two seconds, does not follow redirects, and bypasses configured proxies. Bodies are inspected only for fixed verbose-error markers and never appear in the report. If the port or context path fails validation, neither request is sent.
Bounds on target and evidence
The server port must be an integer from 1 through 65535. Context paths are limited to 256 characters and reject encoded (%), ambiguous (//, backslash, query, fragment), control-character, and dot-segment forms.
| Evidence | Bound |
|---|---|
GET body retained for inspection | 8 KiB |
| Header names per response | 64 |
| Header values per response | 128, and 16 KiB of header text |
| Single header name / value | 256 / 4096 characters |
| Spring MVC handler-mapping beans / endpoint patterns | 64 / 4096 |
| OAuth discovery property sources / names / issuer / implicit-grant entries | 128 / 4096 / 64 / 64 |
| Configuration-list property sources, and items per indexed or collection value | 128 / 64 |
Oversized header names are dropped, and oversized values are dropped with their fields marked incomplete. Partial cookies and policies are not parsed as complete fields, and an incomplete header inventory cannot prove a header absent, though complete independent fields and retained error markers can still support findings.
Any failed request, incomplete metadata read, or exceeded limit makes the scan PARTIAL rather than silently accepting an incomplete list. Findings from retained evidence stay valid, while affected no-finding coverage becomes INDETERMINATE. Unavailable, failed, and truncated probe evidence limits coverage without discarding known findings. The INFO probe-failure notices PT-A05-001 and PT-A05-069 cannot establish a score on their own, though genuine INFO findings can. See the shared score eligibility policy.
What the evidence does and does not prove
Document-specific checks need a response that can represent a rendered document: an HTML or XHTML Content-Type, or bounded HTML evidence when no explicit media type says otherwise. A body beginning with <html> does not override an explicit JSON or other non-HTML type. Redirects, bodyless responses, and unknown rendering roles cannot support missing document-policy findings. The request's own Accept: text/html proves neither rendering nor an exception path. X-Content-Type-Options: nosniff applies to API responses too, so it is not a document-only control.
checksRun counts registered check evaluations attempted, not checks that had applicable evidence. A scan attempts 77 checks without claiming all 77 could inspect the host. No observed cookie issuance does not mean login cookies are hardened, and a successful preflight does not prove the authenticated response is readable.
Findings are heuristic review prompts, not proof of exploitability. This is a developer hygiene tool, not a replacement for a penetration test or a DAST suite.
Parsing and severity follow the relevant standards and framework behavior: the Fetch CORS protocol for credentialed wildcard responses, RFC 7034 for X-Frame-Options, RFC 6265 for Set-Cookie attributes, RFC 9700 for OAuth security, and CSP3 with Google's CSP Evaluator checks for Content-Security-Policy weaknesses.
Check IDs are stable API-facing identifiers that keep their original PT-* prefixes, so a check ID's number may not match the OWASP Top 10 2025 category shown in the panel.
Dismissing findings
Use Dismiss on a finding to accept that check for your local project, or list its exact PT-* ID under dismissedRules in .bootui/boot-ui.yml. For example:
dismissedRules:
- PT-A07-006
- PT-A05-040
- PT-A05-044
The shared dismissal store follows bootui.overrides-file when it is relocated, and dismissals apply on all three stacks. A dismissal covers every retained finding from that check, including findings against multiple targets, but does not dismiss another advisor's rule about a similar observation. PT-A07-006 and SEC-OAUTH-004, for example, stay independent decisions.
REST, MCP, and CLI reports retain every finding with an explicit dismissed boolean, and only active findings contribute to findingsFound, scan.findingsFound, severityCounts, and the scores. The panel keeps accepted findings in a collapsed Dismissed rules list with Restore controls. Dismissing and restoring read the cached report; neither reruns checks or sends another probe. Both controls are disabled when the panel is read-only.
Dismissal changes penalties, not what the scan observed. Check counts, scan time and status, category coverage, and evidence are unchanged. Dismissing every finding does not prove the application safe or make incomplete evidence complete, and dismissing INFO probe-failure notices does not establish score eligibility.
BootUI's own actuator defaults are never flagged
How BootUI distinguishes defaults from host configuration
BootUiActuatorDefaultsEnvironmentPostProcessor contributes management.endpoints.web.exposure.include=health,info, beans,conditions,configprops,env,loggers,mappings,metrics,startup,scheduledtasks as a lowest-priority library default whenever BootUI is active and the host has not configured that property itself. Because bootui-spring-boot-starter transitively pulls in spring-boot-starter-actuator, this default alone is enough to make those endpoints live Spring MVC mappings — and SpringPentestingObservationCollector reads the live mapping inventory (not the raw property), so without special handling it could not tell "exposed because of BootUI's own convenience default" apart from "exposed because the host configured it". endpointInventory() resolves this: it excludes the actuator mappings whose endpoint id is one of BootUI's own defaulted ids (and the bare discovery/links mapping) from the set the exposure-based checks see (PT-A05-016, PT-A05-035, PT-A05-052–PT-A05-055), but only when the live, resolved value of management.endpoints.web.exposure.include is confirmed to be BootUI's own default with no value from any other property source — i.e. the host genuinely has not configured exposure at all. Concretely:
- A fresh application that only adds the BootUI starter (no host-set exposure list, no Spring Security) reports no actuator-exposure findings — BootUI's own convenience default is not host misconfiguration.
- If the host explicitly sets
management.endpoints.web.exposure.include— even to the exact same list BootUI would have defaulted to — the value resolves from a higher-precedence source than BootUI'sdefaultPropertiescontribution, so the exclusion does not apply and the usual findings fire normally. - If the host sets a different exposure list, the same applies: whatever the host chose is flagged normally.
/health and /info are included in the exclusion set for completeness (so the discovery link and health/info mappings don't keep PT-A05-016's "at least one actuator mapping" check non-empty on a fresh app), even though no check keys on those two ids specifically (see PT-A05-055's rationale below). This behavior is Spring-only: the Quarkus adapter has no equivalent environment-default-injecting post-processor, so QuarkusPentestingObservationCollector never needs this exclusion.
Platform-specific metadata coverage
Evidence and availability by stack
A01 (Broken Access Control) is backed by servlet Spring Security metadata today (PT-A01-001), so it renders NOT_APPLICABLE on WebFlux and Quarkus. A07 (Authentication Failures) is Spring metadata: Security wiring, default-user, session-tracking, issuer, and implicit-grant checks. On Quarkus, A07 renders HANDOFF to the Security panel, whose QS-AUTH-*, QS-OIDC-*, and QS-TLS-004 rules review authentication and identity-provider transport for every active OIDC tenant; it is not a green assertion that anything was checked here.
Spring MVC is the complete reference collector. On WebFlux, Spring configuration and OAuth metadata still run, but MVC request mappings and servlet filter-chain evidence are explicitly marked unavailable rather than represented by an empty, apparently clean inventory. Use the reactive Security advisor for SecurityWebFilterChain and route-policy coverage. The active application context determines the runtime even when both MVC and WebFlux classes are present. WebFlux uses spring.webflux.base-path and does not treat inactive servlet session properties as effective settings.
QuarkusPentestingObservationCollector deliberately supplies a neutral PentestingSecurityStatus (securityClassPresent=false, chainsWithCsrf=-1) because Quarkus has no Spring Security equivalent to inspect. Its endpoint inventory is explicitly unavailable, not "empty and checked," and every Spring configuration field stays neutral. It supplies only the live port and quarkus.http.root-path. Quarkus CORS is a single global Vert.x filter, so the synthetic preflight directly exercises it; static CORS, TLS, OIDC, and management configuration belongs to the Security panel (QS-CORS-*, QS-TLS-*, QS-OIDC-*, QS-MGMT-*).
PentestingObservation separately records Spring-metadata availability, endpoint-inventory availability/truncation, and authMetadataTruncated (Spring OAuth2 client-registration enumeration). OAuth2 truncation only affects A07 Authentication Failures, never A02 Security Misconfiguration or A04 Cryptographic Failures. When a category depends entirely on unavailable metadata, an empty finding set renders as NOT_APPLICABLE instead of a no-finding status, mirroring the existing QuarkusPanelAvailability.NOT_APPLICABLE precedent used for the GraalVM/CRaC/Conditions/Startup-Timeline panels: "no meaningful equivalent today", not "checked and clean".
Additional explicit unknowns preserve the same evidence boundary: failed/incomplete default-user inspection makes the scan PARTIAL and dependent A07 no-finding coverage INDETERMINATE; failed/incomplete firewall inspection does the same for A02. Independently supported findings keep their category in REVIEW, with the incomplete-evidence limitation retained rather than hidden.
The engine-only PentestingObservation.configurationMetadataTruncated field also records incomplete configuration collection without changing the public report DTO shape. Unknown/truncated Actuator CORS or exposure lists affect A02 no-finding coverage only; unknown/truncated servlet session-tracking configuration affects A07. These bounded configuration reads make the scan PARTIAL without marking unrelated categories indeterminate.
Mixed categories — A02 (Security Misconfiguration), A04 (Cryptographic Failures), and A10 (Mishandling of Exceptional Conditions) — are backed by a mix of SPRING_METADATA and HTTP_SYNTHETIC checks. The HTTP_SYNTHETIC checks in those categories (missing/unsafe security headers, cookie flags, CORS, TRACE, weakened CSP, verbose error bodies, HSTS, …) run identically against the two synthetic loopback probes on every adapter. A no-finding result is still INFO, not a pass, because two responses cannot prove application-wide posture.
CORS checks keep their stable primary mapping to A02 Security Misconfiguration, with meaningful overlap into A01 Broken Access Control when cross-origin access changes who can read a resource. Plaintext OAuth/OIDC issuer configuration keeps its primary mapping to A07 Authentication Failures, with transport overlap into A04 Cryptographic Failures.
Coverage status means:
REVIEW— at least one non-diagnostic finding mapped to the category.INFO— no finding was produced from the bounded evidence that was evaluated; this is not a pass.INDETERMINATE— a required request or bounded metadata inventory failed or was truncated.NOT_APPLICABLE— the adapter does not provide the category's required evidence model.HANDOFF/SKIPPED— another BootUI panel owns the signal (A03 always; A07 on Quarkus), or active probing is deliberately out of scope.
A category with known findings stays REVIEW while its description preserves applicable incomplete-evidence limitations; REVIEW is not a claim that every dependent check completed. Neither unobserved cookie issuance nor untested authenticated CORS responses become a clean result.
What BootUI does not do
- It does not crawl or sweep application endpoints, fuzz inputs, or send SQL/XSS/command-injection payloads.
- It does not run against
/bootuiitself — BootUI's own controllers are always excluded. - It does not follow redirects, consult configured HTTP proxies, resolve a hostname, or contact an external host.
- It does not perform dependency vulnerability scanning; that lives in the Vulnerabilities panel (OSV.dev, user-initiated).
- Reports do not contain raw response bodies, cookie values, credentials, or full OAuth/OIDC issuer paths, queries, fragments, or user-info. Issuer evidence is reduced to a masked value or scheme/host/port plus
/.... - The two synthetic probes target one fixed, deliberately unlikely path (
/<context-path>/__bootui_pentesting__/missing-resource), so route-scoped security configuration may be invisible to them. The path is not guaranteed to be unmapped: catch-all routes, filters, sessions, metrics, and customOPTIONShandlers may still execute and can have the application's normal per-request effects. A Spring application that scopes itsCorsConfigurationSource(or security headers) to a specific route prefix (e.g./api/**) rather than applying it globally will not have that configuration reflected in the probe response, even though the configuration is real. This is a structural asymmetry between the two adapters: Quarkus'squarkus.http.cors(and its security-header equivalents) is wired as a single global Vert.x filter that runs for every request, so the same fixed-path, 2-probe design is inherently more representative for Quarkus than for Spring, where CORS/security-header configuration is more commonly scoped per-route viaSecurityFilterChain/CorsConfigurationSourcebeans. Treat a no-finding synthetic-probe result as "nothing matched on the evaluated default/global response," not as proof that every route shares that posture.
Coverage by OWASP Top 10 (2025)
| OWASP category | Checks | Notes |
|---|---|---|
| A01 Broken Access Control | 1 | One servlet CSRF posture review prompt; route authorization is left to manual review. It renders NOT_APPLICABLE (not PASS) on WebFlux and Quarkus. |
| A02 Security Misconfiguration | 61 | Missing or unsafe security headers, cookie flags and name prefixes, observed CORS preflight responses (wildcard, credentialed, null-origin), actuator exposure, dev-only switches, HttpFirewall, public management binding, exposed dev consoles, request-detail logging, SQL logging, verbose framework log levels, recon actuator endpoints, CSP hardening, and an OPTIONS-preflight-probe-failure indicator. CORS has A01 overlap. |
| A03 Software Supply Chain Failures | 0 | Handed off to the Vulnerabilities panel for explicit OSV dependency scanning; broader provenance and CI/CD controls need manual review. |
| A04 Cryptographic Failures | 4 | Informational HSTS-over-HTTP observations and Secure-cookie reminders; deep cryptographic code review is not performed. Quarkus listener TLS configuration is reviewed by the Security panel (QS-TLS-*). Plaintext OAuth/OIDC is mapped primarily to A07 with A04 overlap. |
| A05 Injection | 0 | Skipped by design — use a dedicated DAST and manual review. |
| A06 Insecure Design | 0 | Skipped by design — threat modeling and business-logic abuse cases require manual review. |
| A07 Authentication Failures | 7 | Spring Security wiring, in-config credentials, auto-generated default user, servlet session tracking, plaintext Spring OAuth2/OIDC issuer URLs, and Spring OAuth implicit grants. On Quarkus this category is a HANDOFF to the Security panel (QS-AUTH-*, QS-OIDC-*, QS-TLS-004). |
| A08 Software or Data Integrity Failures | 0 | Skipped by design until BootUI has safe static checks for deserialization, update integrity, or trusted artifact boundaries. |
| A09 Security Logging and Alerting Failures | 0 | Skipped by design — audit coverage, alerting, and log integrity require operational review. |
| A10 Mishandling of Exceptional Conditions | 4 | Verbose error responses and Spring Boot spring.web.error.include-* disclosure settings; ordinary request-path metadata is not a finding. |
| Total | 77 |
The zero-check categories are scoped that way on purpose. BootUI flags bounded local signals that are commonly forgotten or risky, and never produces a value judgement on application code, architecture, operations, or payload behavior that requires manual review.
Severity scale
Severity reflects the worst plausible impact if the finding is real, not how likely it is:
| Severity | Meaning | Examples |
|---|---|---|
| CRITICAL | Immediate severe impact if exposed. | An unprotected heap dump or shutdown actuator endpoint |
| HIGH | Potentially serious impact, needs review. | Credentialed CORS to a permissive origin, sensitive actuator exposure |
| MEDIUM | Leaks internals or weakens defenses, but typically needs chaining. | Actuator value exposure, verbose errors, missing session cookie hardening |
| LOW | A defense-in-depth gap. | Missing security headers, broad CORS without credentials |
| INFO | An informational hygiene prompt. | Missing optional headers, dev-only switches expected locally |
Missing Spring Security wiring alone is INFO, not proof that routes lack protection.
Some checks assign severity from the available evidence, such as INFO versus MEDIUM for cookie purpose, or LOW versus HIGH for credentialed CORS. Configuration alone never justifies an active-exposure claim. A mapped sensitive endpoint keeps its worst-plausible-impact rating, but a mapping is not proof of anonymous reachability, authorization failure, or writable access, and property-only signals are narrower configuration reviews.
The panel shows severity alongside a confidence rating of Low, Medium, or High, reflecting how reliably the underlying signal indicates the finding.
Filter the list, then jump to a check — the detail below narrows to match.
PT-A01-001INFOAll Spring Security filter chains have CSRF disabledPT-A02-001INFOCookie is missing HttpOnlyPT-A02-002INFOCookie is missing SecurePT-A02-003MEDIUMCookie uses SameSite=None without SecurePT-A02-004LOWSession cookie Secure flag is explicitly disabledPT-A02-005MEDIUMSession cookie HttpOnly flag is explicitly disabledPT-A02-006MEDIUMSession cookie SameSite=None is paired with Secure=falsePT-A05-064INFOSession cookie is missing a __Host-/__Secure- name prefixPT-A05-001INFOSynthetic GET evidence is incompletePT-A05-069INFOSynthetic OPTIONS evidence is incompletePT-A05-002LOWMissing X-Content-Type-Options nosniff headerPT-A05-003LOWMissing clickjacking protection headerPT-A05-046LOWX-Frame-Options uses an unsupported valuePT-A05-004INFOMissing Referrer-Policy headerPT-A05-047LOWReferrer-Policy leaks full URLs cross-originPT-A05-005LOWCookie is missing SameSitePT-A05-006MEDIUMError response appears to expose implementation detailsPT-A05-007INFOCORS allows credentialed cross-origin requestsPT-A05-008LOWCORS allows a broad cross-origin requestPT-A05-065LOWCORS allows the literal 'null' originPT-A05-010LOWMissing Content-Security-Policy headerPT-A05-060INFOContent-Security-Policy is present but weakenedPT-A05-061LOWUnsafe X-XSS-Protection header is enabledPT-A05-066MEDIUMContent-Security-Policy frame-ancestors is overly permissivePT-A05-067LOWContent-Security-Policy is missing object-src or base-uriPT-A05-011INFOResponse discloses server technologyPT-A05-048INFOLocal HTTP response advertises disabled HSTSPT-A05-063INFOLocal HTTP response advertises weak HSTSPT-A05-013INFOMissing Permissions-Policy headerPT-A05-014MEDIUMError responses are configured to expose detailsPT-A05-015MEDIUMActuator shutdown endpoint is enabledPT-A05-016MEDIUMActuator mappings are present without Spring SecurityPT-A05-032CRITICALActuator /heapdump endpoint is exposedPT-A05-033HIGHActuator /httpexchanges (or /httptrace) endpoint is exposedPT-A05-034HIGHActuator /sessions endpoint is exposedPT-A05-035MEDIUMActuator /loggers endpoint is exposedPT-A05-036MEDIUMActuator /threaddump endpoint is exposedPT-A05-037MEDIUMActuator /gateway/routes endpoint is exposedPT-A05-038MEDIUMActuator /logfile endpoint is exposedPT-A05-039LOWActuator /caches endpoint is exposedPT-A05-040INFOActuator /prometheus endpoint is exposedPT-A05-052HIGHActuator /env endpoint is web-exposedPT-A05-053HIGHActuator /configprops endpoint is web-exposedPT-A05-054MEDIUMActuator /mappings endpoint is web-exposedPT-A05-055MEDIUMReconnaissance actuator endpoints are web-exposedPT-A05-056CRITICALActuator /shutdown endpoint is web-mappedPT-A05-017INFOH2 database console is enabledPT-A05-018MEDIUMActuator endpoints are configured to reveal valuesPT-A05-049MEDIUMActuator web exposure includes every endpointPT-A05-050LOWActuator health details are always exposedPT-A05-019MEDIUMActuator CORS allows any originPT-A05-020INFOSpring Boot DevTools is on the classpathPT-A05-062INFOSpring Boot DevTools remote support is configuredPT-A05-021INFOMissing Cross-Origin-Opener-Policy headerPT-A05-022INFOMissing Cross-Origin-Resource-Policy headerPT-A05-068INFOMissing Cross-Origin-Embedder-Policy headerPT-A05-023LOWCORS preflight allows any method or header for a permissive originPT-A05-024LOWTRACE or TRACK method advertisedPT-A05-025MEDIUMspring.web.error.include-exception is enabledPT-A05-026MEDIUMspring.web.error.include-binding-errors reveals validation detailsPT-A05-027INFOJolokia JMX-over-HTTP bridge is configured or presentPT-A05-028INFOActuator env POST support is configuredPT-A05-029MEDIUMActuator CORS allowed-origin-patterns is a wildcardPT-A05-030INFOspring.jpa.show-sql is enabledPT-A05-031INFOVerbose logging level configured for framework packagesPT-A05-051INFORequest detail logging is enabledPT-A05-041INFOAPI documentation or developer console is exposedPT-A05-042MEDIUMA Spring Security DefaultHttpFirewall bean is presentPT-A05-043INFOManagement interface potentially externally reachablePT-A05-044INFOserver.forward-headers-strategy trusts X-Forwarded-* headersPT-A07-001INFOSpring Security is not on the classpathPT-A07-002INFONo Spring Security filter chain is configuredPT-A07-003INFOSpring Security user password is set in configurationPT-A07-004MEDIUMServlet session tracking modes include URLPT-A07-005MEDIUMSpring Boot auto-generated security password is in usePT-A07-006HIGHOAuth2/OIDC issuer URI uses plaintext HTTPPT-A07-007HIGHOAuth2 client uses the implicit grant
A01:2025 - Broken Access Control
This category is backed by one servlet Spring Security check. On WebFlux and Quarkus it renders
NOT_APPLICABLE, not a false-assurancePASS, when no finding fires — see "Platform-specific metadata coverage" above.
PT-A01-001 - All Spring Security filter chains have CSRF disabled
- Severity / confidence: INFO / Low
- Source: Spring metadata (reflection over
SecurityFilterChainbeans) - Inspects: every registered
SecurityFilterChainfor the presence ofCsrfFilter. - Fires when: at least one filter chain is registered, and none of them include
CsrfFilter. The check fails safe to silent if Spring Security is absent; an inspection error makes the dependent coverageINDETERMINATE. - Why it matters: CSRF follows browser-ambient credentials, not response format or server-side session state. JSON APIs using cookies or browser-supplied Basic authentication can still need CSRF protection. This inspection does not establish which authentication mechanisms or route protections apply.
- Recommendation: retain CSRF protection wherever browsers automatically attach credentials. A bearer-token-only API may justify disabling it if tokens are explicitly attached and no ambient authentication path remains. [S01, S05]
A02/A04:2025 - Cookie and transport hygiene
These stable PT-A02-* checks now display either A02 Security Misconfiguration or A04 Cryptographic Failures, depending on whether the signal is cookie hardening or transport encryption.
PT-A02-001 - Cookie is missing HttpOnly
- Severity / confidence: dynamic / Medium — MEDIUM for known session/authentication-like names, INFO otherwise.
- Source: synthetic HTTP (
Set-Cookieon theGETresponse) - Fires when: a complete, separately retained
Set-Cookiefield lacks theHttpOnlypresence flag.HttpOnly=falsestill sets that flag. Unknown-purpose cookies, including conventional script-readableXSRF-TOKENandCSRF-TOKEN, are INFO rather than assumed to hold credentials. Evidence includes only a sanitized, 80-character cookie-name label, never its value. Known-name recognition currently coversJSESSIONID,SESSION, andquarkus-credentialcase-insensitively. - Recommendation: mark session and sensitive cookies
HttpOnly; keep intentional script-readable cookies free of authentication material. Name-based purpose recognition remains a heuristic. [S03, S07, S08]
PT-A02-002 - Cookie is missing Secure
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
Set-Cookieon theGETresponse) - Fires when: a complete
Set-Cookiefield lacks theSecurepresence flag (Secure=falsestill sets it). A clipped field cannot establish a missing flag. - Why INFO: the probe is local HTTP, so
Secureis often genuinely absent in development. Use this as a reminder to confirm the HTTPS deployment setsSecure; this probe does not inspect the TLS or reverse-proxy edge. [S07, S08, S10]
PT-A02-003 - Cookie uses SameSite=None without Secure
- Severity / confidence: MEDIUM / Medium
- Source: synthetic HTTP (
Set-Cookieon theGETresponse) - Fires when: a complete cookie's effective, last accepted SameSite attribute is
Noneand it lacks theSecurepresence flag. Modern browser processing rejects this combination; the finding is not demonstrated plaintext leakage. SetSecurewhen cross-site delivery is intentional, or choose an appropriate Lax/Strict policy. [S08]
PT-A02-004 - Session cookie Secure flag is explicitly disabled
- Severity / confidence: LOW / Medium
- Source: Spring metadata (
server.servlet.session.cookie.secure) - Fires when: the property is explicitly set to
falsein an active servlet runtime. A missing value or an inactive WebFlux servlet setting does not fire. False permits HTTP transmission; it does not force it. - Recommendation: remove the override or set it to
truefor HTTPS deployments, considering TLS termination and trusted forwarding configuration. [S07, S13]
PT-A02-005 - Session cookie HttpOnly flag is explicitly disabled
- Severity / confidence: MEDIUM / High
- Source: Spring metadata (
server.servlet.session.cookie.http-only) - Fires when: the property is explicitly set to
falsein an active servlet runtime. A missing value or an inactive WebFlux servlet setting does not fire. - Recommendation: remove the override so the session identifier is not readable from JavaScript. [S07, S13]
PT-A02-006 - Session cookie SameSite=None is paired with Secure=false
- Severity / confidence: MEDIUM / High
- Source: Spring metadata (
server.servlet.session.cookie.same-site,server.servlet.session.cookie.secure) - Fires when: the active servlet runtime has
same-site=noneexplicitly configured withsecure=false. Inactive WebFlux servlet settings do not fire. A missingsecurevalue does not fire because HTTPS deployments and reverse proxies may still set the Secure attribute correctly. - Recommendation: remove
secure=falseor set it totruewhenever the session cookie is intentionally cross-site. Modern browser processing rejects None without Secure; this configuration does not prove leakage. [S08, S13]
PT-A05-064 - Session cookie is missing a __Host-/__Secure- name prefix
- Severity / confidence: INFO / Medium
- Source: synthetic HTTP (
Set-Cookieon theGETresponse) - Fires when: a
Set-Cookieheader is namedJSESSIONIDorSESSION(case-insensitively), has a standaloneSecureattribute, and its name does not start with__Host-or__Secure-(case-sensitive). GenericHttpOnlycookies are not assumed to be session identifiers; lookalike attributes such asSecurelydo not count. Cookies that are not yetSecureare left to PT-A02-002 so this check does not pile on duplicate noise. - Recommendation: rename session-identifier cookies to use the
__Host-prefix (or at least__Secure-) so browsers enforce the cookie's security attributes regardless of application configuration. See the OWASP Session Management Cheat Sheet's Cookie Prefixes section.
A02/A04/A10:2025 - Misconfiguration, transport, and error-handling checks
These stable PT-A05-* checks now display A02 Security Misconfiguration for most configuration hygiene prompts, A04 Cryptographic Failures for HSTS/Secure-cookie reminders, and A10 Mishandling of Exceptional Conditions for verbose error disclosure.
PT-A05-001 - Synthetic GET evidence is incomplete
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
GET) - Fires when: the synthetic
GETrequest failed (connection refused, timeout, rejected target, etc.) or its retained headers/body were truncated. This makes dependent no-finding results explicitly incomplete. Complete independent fields and genuine retained error markers remain usable; incomplete fields never manufacture absence findings. A catch-all success response is not described as a tested exception path. [S01, S02]
PT-A05-069 - Synthetic OPTIONS evidence is incomplete
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
OPTIONS) - Fires when: the synthetic
OPTIONSpreflight request failed or its retained headers were truncated. This is the OPTIONS-probe twin of PT-A05-001: without it, a failed preflight silently produced zero CORS findings, which is indistinguishable from "the preflight ran and CORS is fine". The finding's evidence explicitly names the probe-dependent checks (PT-A05-007, PT-A05-008, PT-A05-023, PT-A05-024, PT-A05-065) so their absence from a report is read as indeterminate rather than a clean CORS posture. An inspected policy rejection (such as HTTP 403) is not itself a transport failure or missing evidence. [S04, S11]
PT-A05-002 - Missing X-Content-Type-Options nosniff header
- Severity / confidence: LOW / Medium
- Source: synthetic HTTP (
GET) - Fires when: an applicable
GETresponse's firstX-Content-Type-Optionsfield value is absent or is not the trimmed, case-insensitive tokennosniff. This includes relevant API responses, not just HTML. A comma-joinedsniff, nosniffvalue does not pass; incomplete headers cannot establish absence. [S02, S03, S04]
PT-A05-003 - Missing clickjacking protection header
- Severity / confidence: LOW / Medium
- Source: synthetic HTTP (
GET) - Fires when: a browser-document
GETresponse is missing bothX-Frame-Optionsand a CSPframe-ancestorsdirective in complete enforced policy evidence. Exact directive names matter; a lookalike substring or report-only policy does not supply framing protection. Missing framing controls on a non-rendered JSON API are not reported. [S02, S06]
PT-A05-046 - X-Frame-Options uses an unsupported value
- Severity / confidence: LOW / Medium
- Source: synthetic HTTP (
GET) - Fires when: a browser-document response has
X-Frame-Options, no CSPframe-ancestorsdirective, and its distinct comma-separated tokens include values other thanDENYorSAMEORIGIN(case-insensitive). Supported repeated or comma-separated tokens are not reported; conflicts may fail closed. ObsoleteALLOW-FROMremains a configuration review. An enforcedframe-ancestorsdirective takes precedence even when it is*; malformed XFO text alone is not proof of a browser bypass. - Recommendation: use
DENY,SAMEORIGIN, or an enforced CSPframe-ancestorsdirective. [S06]
PT-A05-004 - Missing Referrer-Policy header
- Severity / confidence: INFO / Medium
- Source: synthetic HTTP (
GET) - Fires when: a browser-document
GETresponse did not includeReferrer-Policy. - Limits: this optional explicit-policy reminder does not mean browser defaults are unsafe. [S02, S09]
PT-A05-047 - Referrer-Policy leaks full URLs cross-origin
- Severity / confidence: LOW / High
- Source: synthetic HTTP (
GET) - Fires when: a browser-document response's last recognized
Referrer-Policytoken isunsafe-url. Unknown trailing tokens do not cancel it. This can send the origin, path, and query cross-origin (not fragments or URL user-info). - Recommendation: prefer
no-referrer,strict-origin, orstrict-origin-when-cross-origin. [S09]
PT-A05-005 - Cookie is missing SameSite
- Severity / confidence: LOW / Medium
- Source: synthetic HTTP (
Set-Cookie) - Fires when: a complete
Set-Cookiehas no effective valid explicit SameSite policy after duplicate-attribute processing. Absent or invalid SameSite invokes browser-default processing, commonly Lax-like behavior; it does not prove unrestricted cross-site delivery. - Recommendation: choose
SameSite=LaxorSameSite=Strictunless cross-site delivery is intentional, in which case reviewNonewithSecure. [S08]
PT-A05-006 - Error response appears to expose implementation details
- Severity / confidence: MEDIUM / Low
- Source: synthetic HTTP (response body of the
GET) - Fires when: the retained body has actual verbose-error or stack-trace structure, including recognizable Java stack frames, exception structure, or structured trace fields. Ordinary framework/package words in a successful documentation page are insufficient. Genuine error structure can still fire with a nonstandard HTTP 200 status. Inspection remains limited to 8 KiB; reports contain fixed marker labels, never body contents. [S12]
PT-A05-007 - CORS allows credentialed cross-origin requests
- Severity / confidence: dynamic / Medium — HIGH for successful reflected-origin evidence; LOW for a literal wildcard.
- Source: synthetic HTTP (
OPTIONS) - Fires when: a successful preflight response has one valid allowed-origin value matching the exact serialized probe origin
https://evil.example, with byte-case-sensitiveAccess-Control-Allow-Credentials: true, or advertises the literal wildcard with that credentials token. Duplicated/invalid origins, failed statuses, andTRUEdo not establish credentialed permission. The reflected-origin branch is a conditional credentialed-sharing review; literal*is rejected by Fetch for credentials modeinclude. - Limits: no authenticated actual response is requested. Cookie policy, actual-response CORS headers, route authorization, and sensitive data availability remain untested. Neither branch proves credential theft or application-wide cross-origin readability. [S04, S05]
PT-A05-008 - CORS allows a broad cross-origin request
- Severity / confidence: LOW / Low
- Source: synthetic HTTP (
OPTIONS) - Fires when: a successful preflight has a valid
*or exact probe-origin allowance without the exact credentials tokentrue. Invalid/multiple origins and unsuccessful statuses do not establish permission. - Recommendation: verify that broad noncredentialed sharing is intentional; a public API may legitimately use it. The actual response and any sensitive content are not inspected. [S03, S04, S05]
PT-A05-065 - CORS allows the literal 'null' origin
- Severity / confidence: LOW / Low
- Source: synthetic HTTP (
OPTIONS) - Fires when: an inspected OPTIONS response advertises the single literal origin
null. It does not match the sentOrigin: https://evil.example; BootUI does not send a null-origin follow-up. This is conditional policy evidence, not verified preflight acceptance or access from opaque origins, even when credentials are advertised. - Recommendation: review whether trusting opaque origins is intentional; sandboxed documents and other unrelated contexts can serialize their origin as
null. Prefer explicit trusted origins. [S04, S05]
PT-A05-010 - Missing Content-Security-Policy header
- Severity / confidence: LOW / Medium
- Source: synthetic HTTP (
GET) - Fires when: a browser-document
GETresponse did not include aContent-Security-Policyheader (distinct from a CSP that only contributesframe-ancestors). A report-only policy does not supply enforcement. [S02, S06]
PT-A05-060 - Content-Security-Policy is present but weakened
- Severity / confidence: dynamic / Low — MEDIUM for an effective unsafe script source, LOW when no enforcing policy restricts scripts at all.
- Source: synthetic HTTP (
GET) - Fires when: complete enforced CSP evidence supports an effective script weakness:
'unsafe-eval', a bare*script source, a plaindata:,http:, orhttps:scheme source, or unrestricted inline scripts. Separate fields and comma-separated policies enforce independently; the first duplicate directive within each policy wins. Script element/attribute/eval fallbacks, valid nonce/hash tokens, and'strict-dynamic'are considered before reporting a weakness. A restrictive additional policy or overriddendefault-srcmust not be presented as permissive. If any enforced policy hassandboxwithoutallow-scripts, script execution is restricted and script-weakness findings are suppressed. - Scheme sources:
data:lets injected markup load script from a data URL, and a plainhttp:orhttps:scheme source allows script from any host (CSP3 scheme matching letshttp:match HTTPS URLs too).*never matchesdata:. A nonce or hash does not neutralize a scheme source; only'strict-dynamic'in the same effective source list makes browsers ignore host and scheme sources. Independent enforcing policies intersect, so a second policy limited to'self'removes the weakness. - No script restriction (LOW): a present, enforced CSP in which no policy declares
script-src,script-src-elem, or adefault-srcfallback — for example a clickjacking-onlyframe-ancestors 'self'policy — gives no script-injection mitigation. It previously passed both this check and PT-A05-010, and now carries PT-A05-010's LOW severity.script-src-attralone does not restrict script elements; report-only policies still count as a missing CSP under PT-A05-010. - Recommendation: restrict scripts with
script-src(ordefault-src), avoid'unsafe-inline'and'unsafe-eval', avoid bare*and plaindata:,http:, orhttps:sources, and prefer nonces or hashes combined with'strict-dynamic'. This bounded interpretation is not a complete CSP validator or a browser compatibility test; report-only policies do not enforce protection. [S06, S27]
PT-A05-061 - Unsafe X-XSS-Protection header is enabled
- Severity / confidence: LOW / Low
- Source: synthetic HTTP (
GET) - Fires when: a browser-document
GETresponse uses the recognized legacy auditor token1(for example1or1; mode=block), not an arbitrary value beginning with that digit such as10. - Recommendation: set
X-XSS-Protection: 0or omit the header, and rely on a strong Content-Security-Policy instead. [S02]
PT-A05-066 - Content-Security-Policy frame-ancestors is overly permissive
- Severity / confidence: MEDIUM / Medium
- Source: synthetic HTTP (
GET) - Fires when: complete enforced CSP policies leave an effective broad
frame-ancestors *allowance. Independent enforcing policies intersect: a restrictive additionalframe-ancestorspolicy prevents one wildcard policy from proving unrestricted effective framing. An emptyframe-ancestors;blocks framing, and XFO cannot override an enforcingframe-ancestors *. Exact tokens and first-duplicate semantics apply. - Recommendation: restrict
frame-ancestorsto'self'or explicit trusted origins. Report-only policies do not restrict framing. [S06]
PT-A05-067 - Content-Security-Policy is missing object-src or base-uri
- Severity / confidence: LOW / Low
- Source: synthetic HTTP (
GET) - Fires when: complete enforced CSP policies omit
base-uri, or omitobject-srcwith nodefault-srcfallback. Coverage supplied by another enforcing policy counts; exact directive names, ASCII whitespace, and first-duplicate semantics apply.object-srcinheritsdefault-src;base-uridoes not. - Recommendation: add explicit
object-src 'none'(whendefault-srcdoes not already cover it) andbase-uri 'none'; usebase-uri 'self'only when the application intentionally uses a same-origin<base>element. These limit plugin loading and injected<base>elements, respectively. [S06]
PT-A05-011 - Response discloses server technology
- Severity / confidence: dynamic / Low — LOW for a version-shaped
Servertoken or anyX-Powered-Byheader, INFO for an unversionedServerproduct name. - Source: synthetic HTTP (
GET) - Fires when: the response includes
Server,X-Powered-By, or both. Evidence is bounded and notes whether either value appears to include a version. A version is a dotted number (12.0), a number after a slash (Apache/2), or a parenthesized number (Jetty(12.0.5)); digits inside a product name such ash2oare not a version. This mirrors OWASP ZAP passive rules 10036 (Server version leak LOW, unversioned informational) and 10037 (X-Powered-By LOW). Embedded Tomcat, Reactor Netty, and Vert.x send noServerheader by default, so a finding usually reflects a customserver.server-headeror an intermediary. - Recommendation: suppress or genericize
ServerandX-Powered-By. Neither header proves vulnerable software. [S02, S28]
PT-A05-048 - Local HTTP response advertises disabled HSTS
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
GET) - Fires when: a complete, grammatically valid HSTS field advertises
max-age=0, rather than a numeric prefix or substring that resembles it. Duplicate or malformed directives do not establish this policy. Browsers ignore HSTS received over HTTP, so this is a low-confidence deployment-edge review hint, not proof that HTTPS disables HSTS. - Recommendation: only send
max-age=0during a deliberate HSTS removal window; otherwise configure a positive max-age on HTTPS responses. IP-literal loopback is not an HSTS host, and this scan never tests the HTTPS edge. [S10]
PT-A05-063 - Local HTTP response advertises weak HSTS
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
GET) - Fires when: a complete, grammatically valid
Strict-Transport-Securityfield has a positivemax-age(avoiding PT-A05-048'smax-age=0case) and either lacksincludeSubDomainsor setsmax-agebelow the OWASP ASVS one-year recommendation (31536000 seconds). Because the probe is HTTP, this is an informational reminder to verify the deployed HTTPS edge. - Recommendation: review ASVS 5.0 V3.4.1's one-year duration and its L2+ subdomain requirement at the HTTPS edge. Enable
includeSubDomainsonly after all affected subdomains are HTTPS-ready and under appropriate control; it covers subdomains, not a broader collection of unrelated origins. This local observation cannot verify deployment compliance or justify preload enrollment. [S03, S10]
PT-A05-013 - Missing Permissions-Policy header
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
GET) - Fires when: a browser-document response did not include
Permissions-Policy. An explicit policy is optional defense in depth, not a universal application requirement. [S02]
PT-A05-014 - Error responses are configured to expose details
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (
spring.web.error.include-stacktrace,spring.web.error.include-message) - Fires when: either property is set to
alwaysoron-param.
PT-A05-015 - Actuator shutdown endpoint is enabled
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (effective
management.endpoint.shutdown.accessand global access limits) - Fires when: effective endpoint access permits the shutdown operation. This is not proof of a web mapping or successful shutdown; PT-A05-056 separately reports a mapped endpoint.
- Recommendation: use
management.endpoint.shutdown.access=noneor remove unnecessary web exposure. Endpoint access, exposure, and authorization are separate controls. [S15]
Spring Boot 4.1 endpoint controls and evidence limits
For every endpoint finding below, distinguish:
- Access —
management.endpoint.<id>.access=none|read-only|unrestricted, the default access setting, andmanagement.endpoints.access.max-permitted.noneremoves endpoint access;read-onlypermits read operations;unrestrictedpermits the available operations subject to caps, not unrestricted anonymous network access. - Web exposure —
management.endpoints.web.exposure.includeand.exclude, available endpoint dependencies, and actual web mappings.include=*does not override exclusions or access caps. - Authorization — caller authentication and operation-specific authorization. A Spring filter chain's presence neither proves that a particular mapping is protected nor automatically lowers the mapped endpoint's impact.
- Content and writes — sanitization, installed extensions, operation methods, and allowed keys. A mapped GET does not establish a writable POST/DELETE, and no administrative endpoint is invoked by this scan.
Prefer the Boot 4.1 .access keys for new configuration. Boot 4.1.1 still honors the deprecated management.endpoint.<id>.enabled and management.endpoints.enabled-by-default properties; they are not ignored. The endpoint-level access/enabled pair is mutually exclusive, as is the global access.default/enabled-by-default pair. An explicit endpoint setting overrides the global default, and management.endpoints.access.max-permitted caps the result. BootUI delegates this resolution to Boot's own optional PropertiesEndpointAccessResolver, guarded for classpath absence, rather than implementing a compatibility shim.
Actual Actuator identity is preferred over an application route that merely resembles /actuator/<id>. The inventory is bounded to the inspected context and does not claim complete coverage of a separate management application. A separate management HTTP port remains an HTTP port, not a "non-web" endpoint. [S15, S16]
PT-A05-016 - Actuator mappings are present without Spring Security
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (Spring MVC mappings + Spring Security beans)
- Fires when: at least one
/actuator/*mapping exists, and noFilterChainProxyorSecurityFilterChainbean is registered. The evidence string highlights high-risk endpoints (/heapdump,/env,/httpexchanges//httptrace,/sessions,/threaddump,/loggers,/jolokia,/shutdown,/gateway/routes) before the generic mapping list so the worst exposures jump out. Mappings that exist only because of BootUI's own actuator-exposure default are excluded first — see "BootUI's own actuator defaults are never flagged" above — so this stays silent on a fresh app that only adds the BootUI starter. The missing Spring chain is a wiring observation, not proved anonymous access: proxy, custom, and other authentication layers are uninspected. [S14, S15]
PT-A05-032 - Actuator /heapdump endpoint is exposed
- Severity / confidence: CRITICAL / High. Severity does not drop when a Spring Security filter chain is present — presence only proves Spring Security is wired, not that this specific mapping is authorized. The evidence instead notes whether a filter chain was detected, phrased as "authorization not verified" rather than "protected".
- Source: Spring metadata (Spring MVC mappings and Spring Security beans)
- Fires when: a mapping for
/{management-base-path}/heapdumpis registered. A heap dump can contain credentials, session tokens, and PII pulled straight out of process memory. - Recommendation: set
management.endpoint.heapdump.access=noneor remove web exposure. If operationally required, restrict the HTTP listener and enforce endpoint-specific authorization. No heap dump or anonymous access is tested. [S15]
PT-A05-033 - Actuator /httpexchanges (or /httptrace) endpoint is exposed
- Severity / confidence: HIGH / High
- Source: Spring metadata (Spring MVC mappings)
- Fires when: the inventory identifies a mapped
/httpexchangesendpoint or recognizes the historical/httptracepath. The latter is a retained marker, not Spring Boot 2/3 compatibility guidance. - Limits: Boot 4.1 recording excludes
Authorization,Cookie, andSet-Cookieby default. Custom recording options or repositories may differ. The default in-memory repository keeps 100 exchanges; neither that capacity nor the precise recorded content is guaranteed for other repositories. URLs and permitted headers can still be sensitive. - Recommendation: use
management.endpoint.httpexchanges.access=noneor remove web exposure when unnecessary; otherwise review recording options and require authorization. The report does not retrieve exchanges. [S15, S17]
PT-A05-034 - Actuator /sessions endpoint is exposed
- Severity / confidence: HIGH / High
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping for
/sessionsis registered. Available operations may support session lookup and deletion; a mapping alone does not prove that DELETE is available or authorized. Session repository support also matters. - Recommendation: remove web exposure or set
management.endpoint.sessions.access=none; when needed, restrict callers and preferread-onlyaccess if deletion is unnecessary. No sessions are queried or deleted. [S15]
PT-A05-035 - Actuator /loggers endpoint is exposed
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping for
/loggersis registered. With writable access and authorization, POST can change log levels; more verbose logging may expose sensitive data depending on the application. A path alone proves neither writable access nor successful mutation.loggersis one of BootUI's own actuator-exposure defaults, so this stays silent when that default is the only reason it's mapped (see "BootUI's own actuator defaults are never flagged"). - Recommendation: remove web exposure, set
management.endpoint.loggers.access=none, or useread-onlywhen writes are unnecessary; authorize the remaining operations. [S15]
PT-A05-036 - Actuator /threaddump endpoint is exposed
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping for
/threaddumpis registered. Thread and stack-frame metadata can reveal implementation details; a thread dump does not inherently reveal in-flight argument values. - Recommendation: remove unnecessary web exposure or set
management.endpoint.threaddump.access=none; authorize access when needed. The scan does not retrieve a dump. [S15]
PT-A05-037 - Actuator /gateway/routes endpoint is exposed
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping for
/gateway/routesis registered (Spring Cloud Gateway). The endpoint lists internal route definitions when reads are available and authorized. Route mutation requires applicable writable operations, endpoint access, and authorization; mapping alone does not prove a write or historical Gateway vulnerability. - Recommendation: review the installed Gateway version's access model, prefer read-only operational access, or set
management.endpoint.gateway.access=noneand remove web exposure. Keep remaining access authorized. [S15]
PT-A05-038 - Actuator /logfile endpoint is exposed
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping for
/logfileis registered. It can serve configured log content, which may contain sensitive material; actual contents and caller authorization are not inspected. - Recommendation: set
management.endpoint.logfile.access=noneor remove unnecessary web exposure; restrict network access and authorize callers when needed. [S15]
PT-A05-039 - Actuator /caches endpoint is exposed
- Severity / confidence: LOW / Low
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping for
/cachesis registered. Cache eviction requires an available DELETE operation, writable endpoint access, and authorization; none is proved by a mapped path or exercised by this scan. - Recommendation: remove web exposure or use
management.endpoint.caches.access=none; preferread-onlywhen operators need inspection without eviction and authorize all remaining access. [S15]
PT-A05-040 - Actuator /prometheus endpoint is exposed
- Severity / confidence: INFO / Low
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping for
/prometheusis registered. Metrics scraping is normally fine, but unauthenticated metrics still leak business-volume data (e.g. request counts, queue depths). - Recommendation: scrape the endpoint over a private network or behind authentication.
PT-A05-052 - Actuator /env endpoint is web-exposed
- Severity / confidence: HIGH / Medium. Severity does not drop when a Spring Security filter chain is present — presence only proves Spring Security is wired, not that this specific mapping is authorized (see the rationale under PT-A05-032 above). The evidence instead notes whether a filter chain was detected and whether
show-values=alwaysis set. - Source: Spring metadata (Spring MVC mappings, Spring Security beans,
management.endpoint.env.show-values) - Fires when: a mapping for
/{management-base-path}/envis registered. The endpoint exposes the resolved SpringEnvironment;show-values=alwayspermits unsanitized values unless custom sanitization applies. Actual returned values and authorization are not inspected.envis one of BootUI's own actuator-exposure defaults, so this stays silent when that default is the only reason it's mapped (see "BootUI's own actuator defaults are never flagged"). - Recommendation: set
management.endpoint.env.access=noneor remove unnecessary web exposure; when needed, authorize reads and keepmanagement.endpoint.env.show-valuesatneveror carefully configuredwhen-authorized. [S15]
PT-A05-053 - Actuator /configprops endpoint is web-exposed
- Severity / confidence: HIGH / Medium. Severity does not drop when a Spring Security filter chain is present — see the rationale under PT-A05-032 above. The evidence instead notes whether a filter chain was detected and whether
show-values=alwaysis set. - Source: Spring metadata (Spring MVC mappings, Spring Security beans,
management.endpoint.configprops.show-values) - Fires when: a mapping for
/{management-base-path}/configpropsis registered. The endpoint dumps@ConfigurationPropertiesmetadata;show-values=alwayspermits unsanitized values unless custom sanitization applies. Actual returned values and authorization are not inspected.configpropsis one of BootUI's own actuator-exposure defaults, so this stays silent when that default is the only reason it's mapped (see "BootUI's own actuator defaults are never flagged"). - Recommendation: set
management.endpoint.configprops.access=noneor remove unnecessary web exposure; when needed, authorize reads and keepmanagement.endpoint.configprops.show-valuesatneveror carefully configuredwhen-authorized. [S15]
PT-A05-054 - Actuator /mappings endpoint is web-exposed
- Severity / confidence: MEDIUM / Medium. Severity does not drop when a Spring Security filter chain is present — see the rationale under PT-A05-032 above. The evidence instead notes whether a filter chain was detected.
- Source: Spring metadata (Spring MVC mappings and Spring Security beans)
- Fires when: a mapping for
/{management-base-path}/mappingsis registered. The endpoint lists every request mapping, which hands an attacker a full route map for reconnaissance.mappingsis one of BootUI's own actuator-exposure defaults, so this stays silent when that default is the only reason it's mapped (see "BootUI's own actuator defaults are never flagged"). - Recommendation: restrict or disable
/mappingsoutside development.
PT-A05-055 - Reconnaissance actuator endpoints are web-exposed
- Severity / confidence: MEDIUM / Medium. Severity does not drop when a Spring Security filter chain is present — see the rationale under PT-A05-032 above. The evidence instead notes whether a filter chain was detected.
- Source: Spring metadata (Spring MVC mappings and Spring Security beans)
- Fires when: any mapping is registered for
/{management-base-path}/beans,/conditions,/scheduledtasks,/startup,/metrics,/auditevents,/sbom,/flyway, or/liquibase. Together they expose the bean graph, auto-configuration report, schedules, runtime metrics, the exact dependency versions in the software bill of materials, and database migration history — all useful for reconnaissance (the SBOM in particular hands an attacker exact dependency versions to cross-reference against known CVEs)./infois intentionally not included: Spring's own guidance treats/healthand/infoas the two endpoints commonly exposed publicly, so flagging it here would be noisy rather than actionable.beans,conditions,scheduledtasks,startup, andmetricsare among BootUI's own actuator-exposure defaults (auditevents,sbom,flyway, andliquibaseare not), so this stays silent for those five when BootUI's default is the only reason they're mapped (see "BootUI's own actuator defaults are never flagged") — it still fires normally if the host mapsauditevents,sbom,flyway, orliquibase, or explicitly configures exposure themselves. With several endpoints mapped at once, the evidence lists as many as fit within the shared evidence-length limit and collapses the rest into a trailing(+N more)count, so the Spring Security posture note at the end is never silently dropped. - Recommendation: restrict or disable these low-risk-but-revealing actuator endpoints outside development.
PT-A05-056 - Actuator /shutdown endpoint is web-mapped
- Severity / confidence: CRITICAL / High. Severity does not drop when a Spring Security filter chain is present — see the rationale under PT-A05-032 above. The evidence instead notes whether a filter chain was detected.
- Source: Spring metadata (Spring MVC mappings and Spring Security beans)
- Fires when: a mapping for
/{management-base-path}/shutdownis registered. The check never invokes shutdown; it reports potential impact if the shutdown operation is available to an authorized caller. A mapped path does not establish anonymous access or a successful POST. - Recommendation: set
management.endpoint.shutdown.access=noneor remove/shutdownfrom web exposure; restrict and authorize any deliberately retained administrative operation. [S15]
PT-A05-017 - H2 database console is enabled
- Severity / confidence: dynamic / Medium — INFO for configuration alone, MEDIUM for an active console registration, HIGH for an active registration with
web-allow-others=true. - Source: Spring metadata (
spring.h2.console.enabled,spring.h2.console.settings.web-allow-others, and active console registration) - Fires when: the enabled property is true or an active console registration is observed. Configuration alone remains INFO even with
web-allow-others=true; an active registration supplies the stronger evidence for MEDIUM/HIGH. Remote-console permission does not bypass database authentication. Actual network reachability, console access, and database credentials are not tested. - Recommendation: disable
spring.h2.console.enabledoutside local development, and never setspring.h2.console.settings.web-allow-others=truewithout reviewing network restrictions and database credentials. [S19]
PT-A05-018 - Actuator endpoints are configured to reveal values
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (
management.endpoint.env.show-values,management.endpoint.configprops.show-values) - Fires when: either is set to
always. This permits raw values through the applicable endpoint unless custom sanitization applies; effective exposure, authorization, and actual response contents are not inspected. [S15]
PT-A05-049 - Actuator web exposure includes every endpoint
- Severity / confidence: MEDIUM / High
- Source: Spring metadata (
management.endpoints.web.exposure.include) - Fires when: the host application explicitly includes
*, including indexed YAML/list forms. BootUI's own actuator defaults do not include*. Effective exposure remains subject to exclusions, endpoint availability, and access caps; the wildcard does not prove every endpoint is available or anonymously reachable. - Recommendation: expose only the actuator endpoints operators need and keep sensitive endpoints disabled or authorized using the Boot 4.1 access and web-exposure controls described above. [S15]
PT-A05-050 - Actuator health details are always exposed
- Severity / confidence: LOW / Medium
- Source: Spring metadata (
management.endpoint.health.show-details,management.endpoint.health.show-components) - Fires when: the host application configures health details or components as
always. BootUI's local defaultshow-details=alwaysis ignored so the check only reports host configuration. - Recommendation: use
when-authorizedorneveroutside local development unless the health endpoint is strongly authenticated.
PT-A05-019 - Actuator CORS allows any origin
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (
management.endpoints.web.cors.allowed-origins) - Fires when: the effective scalar or indexed origin list contains
*. This is configuration review, not an actual-response or authorization test. Literal wildcard responses do not permit Fetch credentials modeinclude. - Recommendation: restrict origins for private management data and verify effective exposure and CORS behavior. [S04, S15]
PT-A05-020 - Spring Boot DevTools is on the classpath
- Severity / confidence: INFO / Low
- Source: Spring metadata (classpath presence of
org.springframework.boot.devtools.RemoteSpringApplication) - Fires when: DevTools is on the classpath. Expected locally; the prompt exists to confirm the dependency is development-scoped and never ships to production.
PT-A05-062 - Spring Boot DevTools remote support is configured
- Severity / confidence: dynamic / Medium — INFO for configuration alone, HIGH for observed active remote DevTools server support.
- Source: Spring metadata (
spring.devtools.remote.secretand active remote server support) - Fires when: the remote-secret property is configured with a value other than
false, or active remote DevTools server support is observed. The secret value is read only to honor the literalfalseactivation condition; it is neither retained in the observation nor reported. Property presence alone remains INFO; observed active server support is HIGH even without property-presence evidence. Secret possession, network reachability, class updates, and restart operations are not tested. - Recommendation: never configure this property outside a trusted local machine; remove it before any non-local deployment. If remote development access is genuinely required, tunnel it over SSH rather than exposing it directly, and set
spring.devtools.remote.restart.enabled=falseunless the restart channel is also needed. [S24]
PT-A05-021 - Missing Cross-Origin-Opener-Policy header
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
GET) - Fires when: a browser-document response did not include
Cross-Origin-Opener-Policy. Considersame-originfor sensitive UIs needing browsing-context isolation, after reviewing intentional popup/OAuth workflows. [S02, S03]
PT-A05-022 - Missing Cross-Origin-Resource-Policy header
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
GET) - Fires when: a browser-document response did not include
Cross-Origin-Resource-Policy. Considersame-originorsame-sitewhen those restrictions fit intended embedding; this is optional guidance, not universal safety proof. [S02, S03]
PT-A05-068 - Missing Cross-Origin-Embedder-Policy header
- Severity / confidence: INFO / Low
- Source: synthetic HTTP (
GET) - Fires when: a browser-document response did not include
Cross-Origin-Embedder-Policy. Mirrors the existing Cross-Origin-Opener-Policy/Cross-Origin-Resource-Policy checks. Considerrequire-corporcredentiallessfor UIs that need cross-origin isolation (for example,SharedArrayBufferusage), accounting for intentionally cross-origin dependencies before applying a restrictive policy. See the OWASP Secure Headers Project.
PT-A05-023 - CORS preflight allows any method or header for a permissive origin
- Severity / confidence: LOW / Medium
- Source: synthetic HTTP (
OPTIONS) - Fires when: the preflight echoes
*orhttps://evil.exampleas the allowed origin and advertisesAccess-Control-Allow-Methods: *orAccess-Control-Allow-Headers: *on a successful response with valid origin syntax. Trusted origins do not trigger this check. Wildcards have credentials-mode-dependent semantics; they do not mean arbitrary credentialed methods/headers, andAuthorizationrequires explicit allowance. The probe only asks for GET and sends no requested-header list; other methods and actual-response sharing are not tested. A complete wildcard methods field can support a finding when the allowed-headers field was clipped, and vice versa, provided the required origin/preflight evidence is complete. The scan remainsPARTIAL; unrelated incomplete fields do not discard an independently supported observation. [S04]
PT-A05-024 - TRACE or TRACK method advertised
- Severity / confidence: LOW / Low
- Source: synthetic HTTP (
OPTIONS) - Fires when: either the
Allowheader or theAccess-Control-Allow-Methodsheader listsTRACEorTRACK. CheckingAccess-Control-Allow-Methodsin addition toAllowcatches CORS configurations that advertise TRACE/TRACK as an allowed cross-origin method without necessarily surfacing it inAllow. TRACE is a standardized diagnostic method, and Fetch forbids TRACE/TRACK from script requests. Confidence is Low because advertisement proves neither execution nor a cross-site tracing exploit; BootUI sends neither method. Review unnecessary server diagnostics rather than treating this as a demonstrated browser exploit. CompleteAllowevidence remains usable when an unrelated CORS field was clipped; each advertisement field is evaluated independently in a partial scan. [S11]
PT-A05-025 - spring.web.error.include-exception is enabled
- Severity / confidence: MEDIUM / High
- Source: Spring metadata (
spring.web.error.include-exception) - Fires when: explicitly
true. Exposes the underlying exception class in error responses.
PT-A05-026 - spring.web.error.include-binding-errors reveals validation details
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (
spring.web.error.include-binding-errors) - Fires when: set to
alwaysoron-param. Framework binding detail can reveal rejected values, internal object names, or implementation metadata depending on the error contract. - Recommendation: review internal/rejected-value disclosure without suppressing useful, intentionally designed API validation errors. This property does not prove that sensitive values appeared in an observed response. [S12, S13]
PT-A05-027 - Jolokia JMX-over-HTTP bridge is configured or present
- Severity / confidence: dynamic / Low — MEDIUM when
/jolokiais web-mapped; INFO without a mapping. - Source: Spring metadata (
management.endpoint.jolokia.enabled,/jolokiamappings, and/ororg.jolokia.http.AgentServleton the classpath) - Fires when:
/jolokiais web-mapped, the Jolokia servlet class is on the classpath, or the legacymanagement.endpoint.jolokia.enabledproperty is set. - Spring Boot 4 note: built-in Jolokia integration is no longer supplied by Boot. A third-party add-on such as
jolokia-support-springboothas its own activation requirements and still needs appropriate endpoint access/exposure controls. Neither a legacy property nor classpath presence, even together, proves a web mapping. A mapped bridge merits review, but its authorization and permitted JMX operations remain untested; this is not evidence of a historical RCE in the current runtime. - Recommendation: if Jolokia is intentional, confirm it is not web-exposed and is locked down behind authentication; otherwise remove the dependency and any unused legacy
management.endpoint.jolokia.enabledconfiguration. [S15]
PT-A05-028 - Actuator env POST support is configured
- Severity / confidence: dynamic / Medium — INFO for configuration or active Cloud write support without an observed web write mapping, MEDIUM for a write-capable Actuator env mapping.
- Source: Spring metadata (
management.endpoint.env.post.enabled, active Cloud write support, and Actuator write-mapping inventory) - Fires when: the property is explicitly true, active Cloud env write support is observed, or the Actuator write-mapping inventory contains the actual management-base-path
/envendpoint or a child path. Only the last condition supplies the stronger MEDIUM evidence. Base Boot's env endpoint is read-only; a property, active Cloud write bean without a web write mapping, or env GET mapping alone does not establish a writable HTTP endpoint. Permitted keys, authorization, and successful mutation are not tested. - Recommendation: remove unused configuration; for an installed write extension, restrict allowed keys, endpoint access, exposure, and authorized callers according to that extension's version. No POST is sent. [S16]
PT-A05-029 - Actuator CORS allowed-origin-patterns is a wildcard
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (
management.endpoints.web.cors.allowed-origin-patterns) - Fires when: any effective scalar/indexed origin-pattern token equals
*. Spring origin-pattern matching can reflect a matching origin rather than emit a literal wire wildcard; credentialed sharing is conditional on effective credentials, exposure, and actual-response policy. - Recommendation: use explicit trusted origins/patterns for private management data and verify authorization; the configuration observation does not test cross-origin reads. [S04, S15]
PT-A05-030 - spring.jpa.show-sql is enabled
- Severity / confidence: INFO / Low
- Source: Spring metadata (
spring.jpa.show-sql) - Fires when: explicitly
true. Hibernate statement output can reveal SQL/schema information, but this setting alone does not establish bound-parameter logging or sensitive-value capture. - Recommendation: keep statement output scoped to deliberate diagnostics and review bind-value logging separately. [S25]
PT-A05-031 - Verbose logging level configured for framework packages
- Severity / confidence: INFO / Low
- Source: Spring metadata (
logging.level.root,logging.level.org.springframework,logging.level.org.springframework.web,logging.level.org.springframework.security) - Fires when: any of those four logger levels is set to
DEBUGorTRACE. Verbose framework logging can leak request bodies, headers, and authentication detail.
PT-A05-051 - Request detail logging is enabled
- Severity / confidence: INFO / High
- Source: Spring metadata (
spring.mvc.log-request-details,spring.http.codecs.log-request-details) - Fires when: an applicable component's property is explicitly
true. Servlet MVC configuration is not treated as active in WebFlux; the codec setting is collected for the reactive runtime. Codec configuration applies to Boot-configured codecs, not necessarily custom codecs; matching logging levels and code paths also determine which request details appear. - Recommendation: keep request-detail logging disabled outside short local diagnostics. The Boot 4.1 codec key is
spring.http.codecs.log-request-details, not the stalespring.codec.log-request-details. [S13]
PT-A05-041 - API documentation or developer console is exposed
- Severity / confidence: INFO / Medium
- Source: Spring metadata (Spring MVC mappings)
- Fires when: a mapping prefix matches a well-known developer surface:
/v3/api-docs,/v2/api-docs,/swagger-ui, or/graphiql. Ordinary/graphqlis an application API, not automatically developer tooling. Mapping does not prove anonymous reachability. H2 console configuration is reported separately by PT-A05-017. - Recommendation: review intentional public documentation and restrict development-only tools by profile or authorization rather than disabling the application GraphQL API. [S26]
PT-A05-042 - A Spring Security DefaultHttpFirewall bean is present
- Severity / confidence: MEDIUM / High
- Source: Spring metadata (registered
HttpFirewallbean type) - Fires when: a resolved bean type is
DefaultHttpFirewall. Bean presence does not prove it is the active firewall. UnlikeStrictHttpFirewall, it allows some request normalization, but it rejects encoded slashes by default. This is not proof of path traversal, request smuggling, or an active bypass. - Recommendation: verify the firewall actually wired into Spring Security; prefer narrowly customizing
StrictHttpFirewallwhere an exception is necessary. Failed inspection is unknown, not a safe default. [S18]
PT-A05-043 - Management interface potentially externally reachable
- Severity / confidence: dynamic / Medium — MEDIUM when
server.addressnarrows the application listener but the management listener binds every interface; LOW when the application listener is not narrower. - Source: Spring metadata (
management.server.port,management.server.address,server.address,server.port) - Fires when: a valid numeric
management.server.portconfigures a separate connector with a wildcard address (0.0.0.0,::,[::]) or no explicit address.-1disables management HTTP; equal positive management/application ports share a connector (the application default is 8080). Zero requests a random port and is not treated as an equal fixed port. Invalid/out-of-range settings do not prove binding. A specific management address, including a private non-loopback interface, is not reported. - Why the severity differs: Spring Boot's
ManagementWebServerFactoryCustomizersets the management connector's address frommanagement.server.addressonly; it never inheritsserver.address. An application deliberately bound to127.0.0.1withmanagement.server.port=9090and no management address therefore exposes Actuator on every interface while the application stays loopback-only (MEDIUM). Whenserver.addressis unset or also a wildcard, the separate listener is no more exposed than the application itself (LOW). The Security panel's SEC-ACT-006 separately suggests a dedicated management port; a separate port is not isolation by itself, which is why this check reviews its bind address. - Recommendation: set
management.server.addressto127.0.0.1/::1, a private interface, or a dedicated network segment. Combine with authorization on sensitive Actuator operations. Wildcard/default binding does not establish Internet reachability; routing, firewalls, containers, and deployment controls are not inspected. [S15, S20, S29]
PT-A05-044 - server.forward-headers-strategy trusts X-Forwarded-* headers
- Severity / confidence: INFO / Low. Lowered from LOW: this setting is often legitimately required behind a trusted reverse proxy, so its mere presence isn't itself a misconfiguration — it's a signal to verify, not a finding to remediate by disabling it.
- Source: Spring metadata (
server.forward-headers-strategy) - Fires when: set to
frameworkornative. Processing/trust depends on the server and configured trusted proxies;nativedoes not universally trust every caller. The setting alone establishes neither spoofability nor secure end-user TLS. - Recommendation: confirm the proxy strips or overwrites client-supplied
X-Forwarded-*headers before they reach the application (e.g. via an allow-listed ingress/load balancer, or Tomcat'sserver.tomcat.remoteip.internal-proxies), and that no untrusted client can bypass that proxy to reach the application directly. Verify the actual server-specific trust boundary rather than disabling a legitimate proxy integration based on this INFO observation. [S20]
A07:2025 - Authentication Failures
Spring MVC supplies evidence for all seven checks below. WebFlux supplies the Spring configuration/OAuth subset but marks MVC mapping and servlet filter-chain evidence unavailable. On Quarkus, A07 renders
HANDOFFto the Security panel (QS-AUTH-*,QS-OIDC-*, andQS-TLS-004for plaintext identity-provider URLs). See "Platform-specific metadata coverage" above.
PT-A07-001 - Spring Security is not on the classpath
- Severity / confidence: INFO / Low
- Source: Spring metadata (classpath + Spring MVC mappings)
- Fires when: at least one application mapping exists and
spring-security-webis absent. Custom/proxy authentication and intentionally public routes are not inspected; absence is not proof of unprotected routes. - Recommendation: verify the intended authentication/authorization boundary, adding Spring Security only when appropriate to the application. [S01, S14]
PT-A07-002 - No Spring Security filter chain is configured
- Severity / confidence: INFO / Low
- Source: Spring metadata (Spring Security beans + Spring MVC mappings)
- Fires when: Spring Security is on the classpath, application mappings exist, but no
FilterChainProxyorSecurityFilterChainbean is registered. This is conditional Spring wiring review, not proof that no other authentication/authorization layer exists. - Recommendation: confirm the intended boundary and configure a Spring chain if Spring Security is meant to own it. Servlet evidence remains unavailable on WebFlux and Quarkus. [S14]
PT-A07-003 - Spring Security user password is set in configuration
- Severity / confidence: INFO / Medium
- Source: Spring metadata (
spring.security.user.passworddefined) - Fires when: the property is defined. The value itself is never read — the check only inspects whether the property is configured. It may be securely injected; this is not evidence of hardcoding or source-control storage.
- Recommendation: review credential sourcing, rotation, and whether a single configured user suits the deployment; use an appropriate authentication provider where needed. [S14]
PT-A07-004 - Servlet session tracking modes include URL
- Severity / confidence: MEDIUM / High
- Source: Spring metadata (
server.servlet.session.tracking-modes) - Fires when: the effective tracking-mode list includes
URLin an active servlet runtime, not an inactive WebFlux servlet setting. URL session tracking can put identifiers into links, logs, and referrer data. - Recommendation: prefer cookie-only session tracking where possible; the scan does not create or follow a rewritten session URL. [S08, S13]
PT-A07-005 - Spring Boot auto-generated security password is in use
- Severity / confidence: MEDIUM / Medium
- Source: Spring metadata (default-user auto-configuration provenance and effective generated-password state)
- Fires when: verified Boot default-user provenance and generated-password state support the development fallback. With Spring Security present, both
autoConfiguredDefaultUserPresentand an explicitly truedefaultUserPasswordGeneratedare required; a missing/unknown generated state is not treated as true. Merely having aspring.security.user.passwordproperty does not suppress verified generated-password evidence. A custom bean namedinMemoryUserDetailsManageris insufficient. Inspection neither reads passwords nor instantiates lazy application beans; failed/unknown inspection makes dependent no-finding coverage indeterminate, not safe. - Why it matters: the generated development account is not an intentional production identity model. Startup logs may contain its credential, so log access and credential lifetime require review rather than claims of permanent access.
- Recommendation: configure a real
UserDetailsService(or another authentication source) before exposing the application off the developer's machine. If you must keep a static account, set it explicitly via configuration so the generated password is replaced, and review secure sourcing/rotation separately. [S14]
PT-A07-006 - OAuth2/OIDC issuer URI uses plaintext HTTP
- Severity / confidence: HIGH / Medium
- Source: Spring metadata (
spring.security.oauth2.resourceserver.jwt.issuer-uriandspring.security.oauth2.client.provider.*.issuer-uri) - Fires when: any configured Spring OAuth2/OIDC issuer URL starts with
http://(case-insensitive). The resource-server property is read directly; client-provider issuer URIs are discovered by enumerating property sources for thespring.security.oauth2.client.provider.<name>.issuer-uripattern, since provider names are host-chosen and cannot be read from a fixed key. All offending entries are combined into a single finding. Report evidence never includes URI user-info, query, or fragment; path detail is replaced with/..., and any value thatSecretMaskerrecognizes as credential-bearing is shown only as******. - Why it matters: RFC 9700 (the OAuth 2.0 Security Best Current Practice) requires TLS for sensitive OAuth endpoints. Plaintext issuer/discovery configuration can undermine metadata and key-discovery integrity; it does not prove tokens or authorization codes were transmitted over that exact URL. No discovery or token endpoint is contacted by this check.
- Overlap: SEC-OAUTH-004 reviews the resource-server issuer and JWK URIs only when the Security panel is available; this check also covers client-provider issuer URIs. The Quarkus
quarkus.oidc.auth-server-urlbranch was removed: QS-TLS-004 reviews it for every active tenant, honoringtenant-enabled=falseand an absent OIDC extension. - Recommendation: use an
https://issuer URL for every OAuth2 resource-server and client provider, even in local development where practical, so misconfiguration doesn't silently survive into a real deployment. Spring discovery covers bounded enumerable configuration, not all programmatic registrations. [S23]
PT-A07-007 - OAuth2 client uses the implicit grant
- Severity / confidence: HIGH / High
- Source: Spring metadata (
spring.security.oauth2.client.registration.*.authorization-grant-type) - Fires when: an enumerable Spring property source contains a registration whose trimmed grant type is
implicit(case-insensitive). Evidence records only the matching property name and fixed grant label; no client secret or arbitrary property value is collected. - Why it matters: RFC 9700 section 2.1.2 says clients should not use the implicit grant because access tokens are exposed in authorization responses and are vulnerable to leakage and replay.
- Recommendation: use the authorization-code grant with PKCE.
Retired IDs
Stable IDs are never reused. The catalog retains these retired identifiers:
PT-A05-012— "Strict-Transport-Security not observed." An HTTP loopback response cannot establish whether the HTTPS deployment edge sets HSTS, so absence was permanently noisy. The two observed-HSTS checks remain informational deployment-review hints.PT-A05-071— "Quarkus CORS is enabled without configured origins." Quarkus remains same-origin-only in that state, so the check described an inert configuration rather than a security finding.PT-A05-045— "spring.web.error.include-path exposes request paths in error responses." Retired by the advisor accuracy audit (#961): caller-known request paths are ordinary error-contract metadata, not a useful independent disclosure finding. Boot 4.1's default isalways, notnever; applications need not remove normal path metadata merely to clear an advisor warning. [S12, S13]PT-A05-070— "Quarkus CORS origin configuration is overly broad." Retired by the Pentesting advisor audit: it duplicated the Security panel's always-available QS-CORS-001/QS-CORS-002, which handle more universal-origin forms. Pentesting's own synthetic preflight still observes the delivered Quarkus CORS behavior through PT-A05-007, PT-A05-008, PT-A05-023, and PT-A05-065. [S21]PT-A05-072— "Quarkus TLS endpoint also accepts plaintext HTTP." Retired by the same audit: QS-TLS-001 reviews effectivequarkus.http.insecure-requestsat LOW, while this check rated the same configuration MEDIUM and assumedenabledeven whenquarkus.http.ssl.client-auth=requiredmakes Quarkus default todisabled. [S22]
Accuracy audit dispositions
The #961 audit reviewed all 80 previously active stable IDs against Spring Boot 4.1.1, Quarkus 3.33.3.1, and the primary references below: 61 UPDATE, 18 RETAIN, 1 REMOVE, leaving 79 active checks. UPDATE includes corrected claims, recommendations, severity, or applicability without necessarily changing detection. RETAIN preserves the primary trigger/purpose/rating; shared field-completeness and parsing fixes still apply. REMOVE permanently retires the ID. No disposition adds requests, endpoints, payloads, or new IDs.
| ID | Disposition | Audit result | Sources |
|---|---|---|---|
| PT-A01-001 | UPDATE | CSRF follows ambient browser credentials, including cookie/Basic JSON APIs, not a blanket stateless exemption. | S01, S05 |
| PT-A02-001 | UPDATE | Complete cookies, presence flags, and purpose-aware HttpOnly severity. | S03, S07, S08 |
| PT-A02-002 | UPDATE | INFO local-HTTP Secure reminder; incomplete fields cannot prove a missing flag. | S07, S08, S10 |
| PT-A02-003 | UPDATE | Effective last SameSite and modern rejection semantics, not demonstrated leakage. | S08 |
| PT-A02-004 | UPDATE | Active servlet Secure setting only; false permits HTTP rather than forcing it. | S07, S13 |
| PT-A02-005 | UPDATE | Active servlet HttpOnly setting only; preserve explicit false trigger. | S07, S13 |
| PT-A02-006 | UPDATE | Active servlet pairing and accurate None-without-Secure rejection guidance. | S08, S13 |
| PT-A07-001 | UPDATE | Missing dependency is INFO, not proof of absent custom/proxy authentication. | S01, S14 |
| PT-A07-002 | UPDATE | Missing Spring chain is conditional wiring review, not proof routes are unprotected. | S14 |
| PT-A07-003 | UPDATE | Securely injected configuration is not evidence of a source-controlled credential. | S14 |
| PT-A07-004 | UPDATE | Explicit URL tracking remains MEDIUM only in the active servlet runtime. | S08, S13 |
| PT-A07-005 | UPDATE | Require default-user provenance and generated-password state, not a bean name alone. | S14 |
| PT-A07-006 | UPDATE | Plaintext discovery integrity risk differs from observed token transport; preserve masking. | S23 |
| PT-A07-007 | RETAIN | Implicit-grant metadata and authorization-code/PKCE recommendation remain supported. | S23 |
| PT-A05-001 | UPDATE | Incomplete GET diagnostic; missing fields never manufacture absence findings. | S01, S02 |
| PT-A05-002 | UPDATE | Nosniff applies to relevant APIs too; exact protocol token semantics. | S02, S03, S04 |
| PT-A05-003 | UPDATE | Exact CSP directives and complete document evidence, not substring matching. | S02, S06 |
| PT-A05-004 | RETAIN | Optional Referrer-Policy INFO reminder; absence does not prove unsafe browser defaults. | S02, S09 |
| PT-A05-005 | UPDATE | Valid explicit SameSite versus browser defaults, duplicates, and completeness. | S08 |
| PT-A05-006 | UPDATE | Actual error/stack structure rather than framework words; HTTP status alone is insufficient. | S12 |
| PT-A05-007 | UPDATE | Exact Fetch preflight/header semantics and conditional credentialed-read claims. | S04, S05 |
| PT-A05-008 | UPDATE | Exact origin/status semantics; broad public API policy may be intentional. | S03, S04, S05 |
| PT-A05-010 | RETAIN | LOW missing enforced CSP prompt for documents; report-only does not enforce. | S02, S06 |
| PT-A05-011 | RETAIN | LOW technology disclosure heuristic with bounded evidence, not exploitability proof. | S02 |
| PT-A05-013 | RETAIN | Optional Permissions-Policy INFO rather than a universal requirement. | S02 |
| PT-A05-014 | RETAIN | Explicit always/on-param error-detail settings remain meaningful. | S12, S13 |
| PT-A05-015 | UPDATE | Current endpoint access/caps; configured availability differs from web mapping. | S15 |
| PT-A05-016 | UPDATE | Missing Spring chain does not prove anonymous access; preserve BootUI-default exclusion. | S14, S15 |
| PT-A05-017 | UPDATE | H2 property-only INFO; active registration MEDIUM or HIGH with remote permission, not DB-authentication bypass. | S19 |
| PT-A05-018 | RETAIN | Explicit show-values=always review; custom sanitization/auth remain untested. | S15 |
| PT-A05-019 | UPDATE | Effective scalar/indexed origin lists and conditional exposure wording. | S04, S15 |
| PT-A05-020 | RETAIN | DevTools classpath INFO remains development-scoping advice. | S24 |
| PT-A05-021 | RETAIN | Optional COOP isolation guidance must account for popup/OAuth workflows. | S02, S03 |
| PT-A05-022 | RETAIN | CORP INFO is conditional embedding advice, not universal safety proof. | S02, S03 |
| PT-A05-023 | UPDATE | Wildcards depend on credentials mode and do not imply Authorization permission. | S04 |
| PT-A05-024 | UPDATE | TRACE is standardized diagnostics and Fetch-forbidden; advertisement is not execution. | S11 |
| PT-A05-025 | RETAIN | Explicit exception-class disclosure remains MEDIUM/High. | S12, S13 |
| PT-A05-026 | UPDATE | Review internal/rejected-value disclosure, not normal API validation contracts. | S12, S13 |
| PT-A05-027 | UPDATE | Classpath/stale property is not active Jolokia exposure or current historical-RCE evidence. | S15 |
| PT-A05-028 | UPDATE | Only observed Actuator env write mappings rate MEDIUM; configuration/Cloud support alone remain INFO. | S16 |
| PT-A05-029 | UPDATE | Scalar/indexed patterns and reflected origins differ from wire wildcard responses. | S04, S15 |
| PT-A05-030 | UPDATE | SQL statement output does not establish bound-parameter logging; retain INFO. | S25 |
| PT-A05-031 | RETAIN | Four explicit verbose logging settings remain conditional INFO, not an A09 audit. | S01, S25 |
| PT-A05-032 | UPDATE | Retain CRITICAL mapped impact; current access/exposure advice, not a fictitious non-web port. | S15 |
| PT-A05-033 | UPDATE | Credential headers are excluded by default; repository capacity/content are not guaranteed. | S17 |
| PT-A05-034 | UPDATE | Retain HIGH; session lookup/DELETE depend on available operations, access, and authorization. | S15 |
| PT-A05-035 | UPDATE | Retain MEDIUM; POST writes and authorization are not proved by a path alone. | S15 |
| PT-A05-036 | UPDATE | Retain MEDIUM; thread frames do not inherently contain argument values. | S15 |
| PT-A05-037 | UPDATE | Current Gateway access/topology review, not proof of a historical vulnerability. | S15 |
| PT-A05-038 | UPDATE | Retain MEDIUM; log contents/auth remain uninspected; current endpoint access guidance. | S15 |
| PT-A05-039 | UPDATE | Retain LOW; eviction is conditional on writable operations, access, and authorization. | S15 |
| PT-A05-040 | RETAIN | INFO for intentionally published metrics, not an automatic vulnerability claim. | S15 |
| PT-A05-041 | UPDATE | Ordinary /graphql is not tooling; developer-surface mappings do not prove anonymous access. | S26 |
| PT-A05-042 | UPDATE | A bean may not be active; DefaultHttpFirewall rejects encoded slashes by default. | S18 |
| PT-A05-043 | UPDATE | Numeric/random-port semantics; wildcard binding does not prove Internet reachability. | S15, S20 |
| PT-A05-044 | UPDATE | Native forwarding has server-dependent proxy trust; retain INFO. | S20 |
| PT-A05-045 | REMOVE | Ordinary caller-known error-path metadata; Boot 4.1 default is always. Never reuse this ID. | S12, S13 |
| PT-A05-046 | UPDATE | Effective framing parsing and exact CSP precedence, not assumed browser bypass. | S06 |
| PT-A05-047 | UPDATE | Last recognized policy wins; unknown trailing tokens do not erase unsafe-url. | S09 |
| PT-A05-048 | UPDATE | Strict HSTS grammar; retain INFO with HTTPS edge unassessed. | S10 |
| PT-A05-049 | UPDATE | include=* remains subject to exclusions, access caps, and endpoint capabilities. | S15 |
| PT-A05-050 | RETAIN | Host-only health details/components review; preserve BootUI-default suppression. | S15 |
| PT-A05-051 | UPDATE | Boot 4.1 codec key and applicable-component/custom-codec limitations. | S13 |
| PT-A05-052 | UPDATE | Retain HIGH; actual env identity, sanitization/auth caveats, current endpoint access model. | S15 |
| PT-A05-053 | UPDATE | Retain HIGH; actual configprops identity, sanitization/auth caveats, current access model. | S15 |
| PT-A05-054 | RETAIN | MEDIUM route metadata review; authorization remains unverified. | S15 |
| PT-A05-055 | RETAIN | Bounded reconnaissance summary with authorization caveat, not a dependency vulnerability finding. | S01, S15 |
| PT-A05-056 | UPDATE | Retain CRITICAL mapped impact; current access model and successful POST remain untested. | S15 |
| PT-A05-060 | UPDATE | Independent policies, effective fallbacks, duplicates, nonce/hash, strict-dynamic, and sandbox script restrictions. | S06 |
| PT-A05-061 | UPDATE | Recognized legacy auditor token, not any value beginning with 1; retain LOW/Low. | S02 |
| PT-A05-062 | UPDATE | Remote-secret configuration alone is INFO; observed active remote server support rates HIGH. | S24 |
| PT-A05-063 | UPDATE | Strict HSTS parsing; ASVS level/subdomain-readiness distinctions. | S03, S10 |
| PT-A05-064 | RETAIN | Optional Secure session-like prefix suggestion stays INFO, not mandatory renaming. | S03, S08 |
| PT-A05-065 | UPDATE | Null ACAO does not match the sent origin; conditional observation, not verified opaque-origin access. | S04, S05 |
| PT-A05-066 | UPDATE | Independent enforced CSP policies intersect; one wildcard does not prove unrestricted framing. | S06 |
| PT-A05-067 | UPDATE | Exact CSP composition; object-src has default fallback, base-uri does not. | S06 |
| PT-A05-068 | RETAIN | Optional COEP isolation guidance must account for intentional cross-origin dependencies. | S02 |
| PT-A05-069 | UPDATE | Unavailable OPTIONS evidence differs from an inspected policy-rejected preflight. | S04, S11 |
| PT-A05-070 | UPDATE | Quarkus reflects wildcard matches; effective activation/list/credentials determine conditional risk. | S21 |
| PT-A05-072 | UPDATE | Only selected/default/direct HTTP TLS material counts, not unrelated client keys. | S22 |
Pentesting advisor audit (2026)
A second audit re-checked all 79 active IDs against Spring Boot 4.1.1, Quarkus 3.33, CSP3, OWASP ZAP passive rules, and the sibling Security advisors, leaving 77 active checks: 2 REMOVE, 4 UPDATE, 73 RETAIN, and no new IDs. Every change was reviewed by three independent model critiques before implementation. No change adds requests, endpoints, payloads, or probe traffic.
| ID | Disposition | Audit result | Sources |
|---|---|---|---|
| PT-A05-070 | REMOVE | Duplicated QS-CORS-001/002, which always run on Quarkus; delivered CORS stays covered by the synthetic preflight. | S21 |
| PT-A05-072 | REMOVE | Duplicated QS-TLS-001 at a conflicting severity and ignored the client-auth=required default. | S22 |
| PT-A07-006 | UPDATE | Spring-only; QS-TLS-004 owns the Quarkus OIDC auth-server URL with tenant and extension gating. Quarkus A07 is a HANDOFF. | S23 |
| PT-A05-060 | UPDATE | Adds plain data:/http:/https: script scheme sources (MEDIUM) and a script-unrestricted CSP (LOW). | S06, S27 |
| PT-A05-043 | UPDATE | MEDIUM only when the management listener is broader than a narrowed server.address; otherwise LOW. | S15, S29 |
| PT-A05-011 | UPDATE | Unversioned Server is INFO; version-shaped tokens and X-Powered-By stay LOW. | S28 |
Candidate rules that were considered and deliberately not added:
- Persistent session cookie (
Max-Age/Expireson a session-id cookie) and session cookieDomainattribute: the anonymous missing-resource probe almost never issues a session cookie, deletion cookies (Max-Age=0, pastExpires) would be false positives, and__Host-guidance in PT-A05-064 already forbidsDomain. - Reflected CORS origin without
Vary: Origin: OPTIONS responses are not shared-cacheable and the browser preflight cache is per-origin, so the preflight cannot substantiate cache poisoning; the GET sends noOrigin.
Primary-source register
Research used standards, official documentation, and public upstream sources, not scans of external applications. Normative protocol behavior takes precedence over abbreviated examples. Versioned documentation can redirect to newer content; immutable upstream sources anchor decisive implementation facts. The references establish guidance and scope, not proof that a finding is exploitable in the inspected application.
S01 — OWASP scope: Top 10:2025, A01, A02, and A10. An awareness taxonomy, not a complete penetration-testing standard.
S02 — Header applicability: OWASP HTTP Headers Cheat Sheet. Document framing/CSP/isolation differ from non-rendered APIs; legacy XSS auditors are not modern XSS protection.
S03 — Assurance levels: ASVS 5.0 V3. V3.3.4 makes HttpOnly purpose-dependent; V3.4.1 covers one-year HSTS and L2+ subdomains; V3.4.4 recommends nosniff on all responses. Assurance requirements do not automatically determine vulnerability severity.
S04 — Fetch CORS: header grammar, credentials matrix, CORS check, and preflight fetch. Exact origin/credentials tokens and successful preflight differ from actual-response disclosure.
S05 — CORS/CSRF limits: WSTG CORS, CSRF prevention, and Spring CSRF. Public API sharing may be intentional; stateless cookie/Basic authentication can remain CSRF-relevant.
S06 — CSP3: policy lists, parsing, policy intersection, fallbacks, inline algorithm, script matching, and framing/XFO, empty source lists, plus sandbox.
S07 — RFC 6265: separate fields, attribute parsing, Secure, HttpOnly, and storage. Presence flags are not Boolean-valued attributes.
S08 — Contemporary cookie processing: 6265bis-22 storage, SameSite parsing, and OWASP session management. The cited 6265bis version is an expired Internet-Draft, not a verified replacement RFC. SameSite/prefix guidance describes contemporary browser processing; it is not attributed to original RFC 6265.
S09 — Referrer Policy: W3C header parsing. The last recognized nonempty token wins.
S10 — HSTS: RFC 6797 receiving policy, insecure transport, and syntax. HTTP STS is ignored; IP literals cannot become Known HSTS Hosts.
S11 — Method advertisement: RFC 9110 OPTIONS, TRACE, Allow, and Fetch forbidden methods.
S12 — Error contracts: OWASP error handling, WSTG improper error handling, and RFC 9457 security considerations. Ordinary structured errors differ from implementation dumps; nonstandard statuses can still contain real errors.
S13 — Boot 4.1 properties: application properties and v4.1.1 HttpCodecsProperties. Error settings use
spring.web.error(include-pathdefaults toalways); codecs usespring.http.codecs.S14 — Boot authentication provenance: v4.1.1 default-user auto-configuration, SecurityProperties, and security reference. Generated-password state is separate from a bean's name.
S15 — Actuator controls: Boot 4.1 endpoints and v4.1.1 PropertiesEndpointAccessResolver. Endpoint access/caps, web exposure, authentication, and sanitization are distinct. The resolver still honors deprecated endpoint
enabledand globalenabled-by-default: each is mutually exclusive with its corresponding access setting, explicit endpoint settings override the global default, andmax-permittedcaps the result.S16 — Environment reads/writes: v4.1.1 EnvironmentEndpoint and Spring Cloud context services. Base Boot reads differ from optional Cloud writes; add-on guidance is version-dependent.
S17 — HTTP exchange defaults: Boot recording and S13's
management.httpexchanges.recording.includeentry. Credential headers are excluded by default.S18 — Firewall: Spring Security 7.1.1 DefaultHttpFirewall. Encoded-slash allowance defaults false; stronger StrictHttpFirewall rejection is not proof of an existing bypass.
S19 — H2 console: official tutorial, console settings, and remote-use warning. Remote console access differs from database authentication; these official sources are mutable, not version-pinned.
S20 — Proxies/listeners: Boot webserver guidance and Quarkus 3.33 HTTP reference. Proxy trust is server-dependent; local listener configuration does not establish end-user TLS.
S21 — Quarkus CORS: 3.33.3 CORSFilter and 3.33 CORS guide. Research verified 3.33.0/3.33.3 source behavior; the repository targeted 3.33.3.2 at the time of this audit. Sole wildcards and multi-entry regex lists take different default-credentials branches; matching origins are reflected.
S22 — Quarkus TLS selection: 3.33 all-config (
quarkus.http.tls-configuration-name) and HTTP reference. Main-listener selected/default/direct SSL differs from arbitrary named client TLS material.S23 — OAuth: RFC 9700 and implicit grant guidance. Configured issuer transport is not proof of observed token transmission.
S24 — DevTools: Boot 4.1 DevTools. Development configuration/classpath presence does not prove optional remote components activated.
S25 — Logging: Boot logging and Hibernate statement logger. Statement output differs from bind-value/request-detail capture; the Hibernate link is a maintenance branch, not an assertion of this repository's exact patch.
S26 — GraphQL: Boot GraphQL. The application API and GraphiQL developer tooling are separate surfaces.
S27 — CSP evaluation: Google CSP Evaluator security checks (
checkPlainUrlSchemes,checkMissingScriptSrcDirective) and CSP3 scheme matching.*does not matchdata:; only'strict-dynamic'makes browsers ignore host and scheme sources.S28 — Server fingerprinting: ZAP Server header rule and ZAP X-Powered-By rule. Version-bearing
Servervalues are LOW; unversioned product names are informational.S29 — Management listener: v4.1.1 ManagementWebServerFactoryCustomizer and customizing the management server address. The management connector address comes only from
management.server.address.
Adding a new check
- Add a
final classtoPentestingChecks.javaextendingAbstractPentestingCheck. Pass aPentestingDefinitionwith a unique stable ID (PT-<category>-NNN), title, OWASP 2025 category, severity, confidence, source (SPRING_METADATAorHTTP_SYNTHETIC), target, recommendation, and learn-more URL. - Implement
evaluate(PentestingContext)so it returnsList.of()when the check is silent and one or morePentestingFindingDtos otherwise. Reuse existingPentestingContextaccessors — do not introduce new HTTP traffic. - Register the class in
PentestingCheckRegistry.ACTIVE_CHECKS. If the new check changes what an OWASP category covers, update the matchingCoverageDefinition.scannedDescription. ASPRING_METADATAcheck needs a matchingPentestingConfigSnapshot/PentestingSecurityStatus/PentestingEndpointInventoryfield populated bySpringPentestingObservationCollector. Adapters must mark unavailable evidence explicitly; do not represent unsupported metadata as an empty, clean inventory. Any new enumeration must have a deterministic limit and propagate truncation intoPARTIAL/INDETERMINATEstatus. - Add a focused test in
PentestingScannerTests: extend the uniqueness assertion to include the new ID, and verify the check stays silent on safe defaults and fires on a minimal failing fixture. - Append the new check to this page in the matching OWASP section so the published catalogue stays in sync.