BootUI
Try it
Setup
Features
Workshop
Properties
AI agents
Ecosystem
GitHub
Try it
Setup
Features
Workshop
Properties
AI agents
Ecosystem
GitHub
  • Get started

    • Try the sample app
    • Setup
    • Spring WebFlux
    • Quarkus
    • Java agent
    • Activation and safety
    • Non-standard runtimes
    • Troubleshooting
  • Workshop

    • Workshop overview
    • 00 - Runtime understanding
    • 01 - Setup and tooling
    • 02 - Configuration and wiring
    • 03 - Runtime journal
    • 04 - Runtime Insights
    • 05 - Java instrumentation
    • 06 - Assessment and impact
    • 07 - Agent change loop
    • 08 - Going further
    • Participant worksheet
    • A - Prompts
    • B - Troubleshooting
    • C - Frameworks
    • D - Extensions
  • Features

    • All features
    • Scorecard
    • Live Activity
    • Runtime Insights
    • Advisors
    • Runtime
    • Configuration
    • Database
    • Security
    • Services
    • Diagnostics
    • Java Agent
    • Developer tools
  • Reference

    • Properties
    • Framework support
    • AI agents
    • Command line
    • BootUI family
    • Known limitations
  • Diagnostic checks

    • Architecture
    • REST API
    • Spring
    • Hibernate
    • Database
    • Security
    • Vulnerabilities
    • Memory
    • Pentesting
    • GraalVM readiness
    • CRaC readiness
    • Quarkus
    • Quarkus security
  • Contributing

    • Repository
    • Specification
    • Implementation plan
    • v2 plan
    • Try 2.0 early
    • v2 validation report
    • Releasing 2.0
    • Quarkus design notes
    • WebFlux design notes
  • Privacy

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 GET with Accept: text/html
  • one OPTIONS preflight with Origin: https://evil.example and Access-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.

EvidenceBound
GET body retained for inspection8 KiB
Header names per response64
Header values per response128, and 16 KiB of header text
Single header name / value256 / 4096 characters
Spring MVC handler-mapping beans / endpoint patterns64 / 4096
OAuth discovery property sources / names / issuer / implicit-grant entries128 / 4096 / 64 / 64
Configuration-list property sources, and items per indexed or collection value128 / 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's defaultProperties contribution, 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 /bootui itself — 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 custom OPTIONS handlers may still execute and can have the application's normal per-request effects. A Spring application that scopes its CorsConfigurationSource (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's quarkus.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 via SecurityFilterChain/ CorsConfigurationSource beans. 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 categoryChecksNotes
A01 Broken Access Control1One servlet CSRF posture review prompt; route authorization is left to manual review. It renders NOT_APPLICABLE (not PASS) on WebFlux and Quarkus.
A02 Security Misconfiguration61Missing 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 Failures0Handed off to the Vulnerabilities panel for explicit OSV dependency scanning; broader provenance and CI/CD controls need manual review.
A04 Cryptographic Failures4Informational 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 Injection0Skipped by design — use a dedicated DAST and manual review.
A06 Insecure Design0Skipped by design — threat modeling and business-logic abuse cases require manual review.
A07 Authentication Failures7Spring 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 Failures0Skipped by design until BootUI has safe static checks for deserialization, update integrity, or trusted artifact boundaries.
A09 Security Logging and Alerting Failures0Skipped by design — audit coverage, alerting, and log integrity require operational review.
A10 Mishandling of Exceptional Conditions4Verbose error responses and Spring Boot spring.web.error.include-* disclosure settings; ordinary request-path metadata is not a finding.
Total77

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:

SeverityMeaningExamples
CRITICALImmediate severe impact if exposed.An unprotected heap dump or shutdown actuator endpoint
HIGHPotentially serious impact, needs review.Credentialed CORS to a permissive origin, sensitive actuator exposure
MEDIUMLeaks internals or weakens defenses, but typically needs chaining.Actuator value exposure, verbose errors, missing session cookie hardening
LOWA defense-in-depth gap.Missing security headers, broad CORS without credentials
INFOAn 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.

  1. PT-A01-001INFOAll Spring Security filter chains have CSRF disabled
  2. PT-A02-001INFOCookie is missing HttpOnly
  3. PT-A02-002INFOCookie is missing Secure
  4. PT-A02-003MEDIUMCookie uses SameSite=None without Secure
  5. PT-A02-004LOWSession cookie Secure flag is explicitly disabled
  6. PT-A02-005MEDIUMSession cookie HttpOnly flag is explicitly disabled
  7. PT-A02-006MEDIUMSession cookie SameSite=None is paired with Secure=false
  8. PT-A05-064INFOSession cookie is missing a __Host-/__Secure- name prefix
  9. PT-A05-001INFOSynthetic GET evidence is incomplete
  10. PT-A05-069INFOSynthetic OPTIONS evidence is incomplete
  11. PT-A05-002LOWMissing X-Content-Type-Options nosniff header
  12. PT-A05-003LOWMissing clickjacking protection header
  13. PT-A05-046LOWX-Frame-Options uses an unsupported value
  14. PT-A05-004INFOMissing Referrer-Policy header
  15. PT-A05-047LOWReferrer-Policy leaks full URLs cross-origin
  16. PT-A05-005LOWCookie is missing SameSite
  17. PT-A05-006MEDIUMError response appears to expose implementation details
  18. PT-A05-007INFOCORS allows credentialed cross-origin requests
  19. PT-A05-008LOWCORS allows a broad cross-origin request
  20. PT-A05-065LOWCORS allows the literal 'null' origin
  21. PT-A05-010LOWMissing Content-Security-Policy header
  22. PT-A05-060INFOContent-Security-Policy is present but weakened
  23. PT-A05-061LOWUnsafe X-XSS-Protection header is enabled
  24. PT-A05-066MEDIUMContent-Security-Policy frame-ancestors is overly permissive
  25. PT-A05-067LOWContent-Security-Policy is missing object-src or base-uri
  26. PT-A05-011INFOResponse discloses server technology
  27. PT-A05-048INFOLocal HTTP response advertises disabled HSTS
  28. PT-A05-063INFOLocal HTTP response advertises weak HSTS
  29. PT-A05-013INFOMissing Permissions-Policy header
  30. PT-A05-014MEDIUMError responses are configured to expose details
  31. PT-A05-015MEDIUMActuator shutdown endpoint is enabled
  32. PT-A05-016MEDIUMActuator mappings are present without Spring Security
  33. PT-A05-032CRITICALActuator /heapdump endpoint is exposed
  34. PT-A05-033HIGHActuator /httpexchanges (or /httptrace) endpoint is exposed
  35. PT-A05-034HIGHActuator /sessions endpoint is exposed
  36. PT-A05-035MEDIUMActuator /loggers endpoint is exposed
  37. PT-A05-036MEDIUMActuator /threaddump endpoint is exposed
  38. PT-A05-037MEDIUMActuator /gateway/routes endpoint is exposed
  39. PT-A05-038MEDIUMActuator /logfile endpoint is exposed
  40. PT-A05-039LOWActuator /caches endpoint is exposed
  41. PT-A05-040INFOActuator /prometheus endpoint is exposed
  42. PT-A05-052HIGHActuator /env endpoint is web-exposed
  43. PT-A05-053HIGHActuator /configprops endpoint is web-exposed
  44. PT-A05-054MEDIUMActuator /mappings endpoint is web-exposed
  45. PT-A05-055MEDIUMReconnaissance actuator endpoints are web-exposed
  46. PT-A05-056CRITICALActuator /shutdown endpoint is web-mapped
  47. PT-A05-017INFOH2 database console is enabled
  48. PT-A05-018MEDIUMActuator endpoints are configured to reveal values
  49. PT-A05-049MEDIUMActuator web exposure includes every endpoint
  50. PT-A05-050LOWActuator health details are always exposed
  51. PT-A05-019MEDIUMActuator CORS allows any origin
  52. PT-A05-020INFOSpring Boot DevTools is on the classpath
  53. PT-A05-062INFOSpring Boot DevTools remote support is configured
  54. PT-A05-021INFOMissing Cross-Origin-Opener-Policy header
  55. PT-A05-022INFOMissing Cross-Origin-Resource-Policy header
  56. PT-A05-068INFOMissing Cross-Origin-Embedder-Policy header
  57. PT-A05-023LOWCORS preflight allows any method or header for a permissive origin
  58. PT-A05-024LOWTRACE or TRACK method advertised
  59. PT-A05-025MEDIUMspring.web.error.include-exception is enabled
  60. PT-A05-026MEDIUMspring.web.error.include-binding-errors reveals validation details
  61. PT-A05-027INFOJolokia JMX-over-HTTP bridge is configured or present
  62. PT-A05-028INFOActuator env POST support is configured
  63. PT-A05-029MEDIUMActuator CORS allowed-origin-patterns is a wildcard
  64. PT-A05-030INFOspring.jpa.show-sql is enabled
  65. PT-A05-031INFOVerbose logging level configured for framework packages
  66. PT-A05-051INFORequest detail logging is enabled
  67. PT-A05-041INFOAPI documentation or developer console is exposed
  68. PT-A05-042MEDIUMA Spring Security DefaultHttpFirewall bean is present
  69. PT-A05-043INFOManagement interface potentially externally reachable
  70. PT-A05-044INFOserver.forward-headers-strategy trusts X-Forwarded-* headers
  71. PT-A07-001INFOSpring Security is not on the classpath
  72. PT-A07-002INFONo Spring Security filter chain is configured
  73. PT-A07-003INFOSpring Security user password is set in configuration
  74. PT-A07-004MEDIUMServlet session tracking modes include URL
  75. PT-A07-005MEDIUMSpring Boot auto-generated security password is in use
  76. PT-A07-006HIGHOAuth2/OIDC issuer URI uses plaintext HTTP
  77. PT-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-assurance PASS, 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 SecurityFilterChain beans)
  • Inspects: every registered SecurityFilterChain for the presence of CsrfFilter.
  • 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 coverage INDETERMINATE.
  • 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-Cookie on the GET response)
  • Fires when: a complete, separately retained Set-Cookie field lacks the HttpOnly presence flag. HttpOnly=false still sets that flag. Unknown-purpose cookies, including conventional script-readable XSRF-TOKEN and CSRF-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 covers JSESSIONID, SESSION, and quarkus-credential case-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-Cookie on the GET response)
  • Fires when: a complete Set-Cookie field lacks the Secure presence flag (Secure=false still sets it). A clipped field cannot establish a missing flag.
  • Why INFO: the probe is local HTTP, so Secure is often genuinely absent in development. Use this as a reminder to confirm the HTTPS deployment sets Secure; 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-Cookie on the GET response)
  • Fires when: a complete cookie's effective, last accepted SameSite attribute is None and it lacks the Secure presence flag. Modern browser processing rejects this combination; the finding is not demonstrated plaintext leakage. Set Secure when 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 false in 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 true for 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 false in 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=none explicitly configured with secure=false. Inactive WebFlux servlet settings do not fire. A missing secure value does not fire because HTTPS deployments and reverse proxies may still set the Secure attribute correctly.
  • Recommendation: remove secure=false or set it to true whenever 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-Cookie on the GET response)
  • Fires when: a Set-Cookie header is named JSESSIONID or SESSION (case-insensitively), has a standalone Secure attribute, and its name does not start with __Host- or __Secure- (case-sensitive). Generic HttpOnly cookies are not assumed to be session identifiers; lookalike attributes such as Securely do not count. Cookies that are not yet Secure are 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 GET request 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 OPTIONS preflight 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 GET response's first X-Content-Type-Options field value is absent or is not the trimmed, case-insensitive token nosniff. This includes relevant API responses, not just HTML. A comma-joined sniff, nosniff value 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 GET response is missing both X-Frame-Options and a CSP frame-ancestors directive 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 CSP frame-ancestors directive, and its distinct comma-separated tokens include values other than DENY or SAMEORIGIN (case-insensitive). Supported repeated or comma-separated tokens are not reported; conflicts may fail closed. Obsolete ALLOW-FROM remains a configuration review. An enforced frame-ancestors directive takes precedence even when it is *; malformed XFO text alone is not proof of a browser bypass.
  • Recommendation: use DENY, SAMEORIGIN, or an enforced CSP frame-ancestors directive. [S06]

PT-A05-004 - Missing Referrer-Policy header

  • Severity / confidence: INFO / Medium
  • Source: synthetic HTTP (GET)
  • Fires when: a browser-document GET response did not include Referrer-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-Policy token is unsafe-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, or strict-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-Cookie has 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=Lax or SameSite=Strict unless cross-site delivery is intentional, in which case review None with Secure. [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-sensitive Access-Control-Allow-Credentials: true, or advertises the literal wildcard with that credentials token. Duplicated/invalid origins, failed statuses, and TRUE do not establish credentialed permission. The reflected-origin branch is a conditional credentialed-sharing review; literal * is rejected by Fetch for credentials mode include.
  • 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 token true. 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 sent Origin: 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 GET response did not include a Content-Security-Policy header (distinct from a CSP that only contributes frame-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 plain data:, http:, or https: 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 overridden default-src must not be presented as permissive. If any enforced policy has sandbox without allow-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 plain http: or https: scheme source allows script from any host (CSP3 scheme matching lets http: match HTTPS URLs too). * never matches data:. 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 a default-src fallback — for example a clickjacking-only frame-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-attr alone does not restrict script elements; report-only policies still count as a missing CSP under PT-A05-010.
  • Recommendation: restrict scripts with script-src (or default-src), avoid 'unsafe-inline' and 'unsafe-eval', avoid bare * and plain data:, http:, or https: 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 GET response uses the recognized legacy auditor token 1 (for example 1 or 1; mode=block), not an arbitrary value beginning with that digit such as 10.
  • Recommendation: set X-XSS-Protection: 0 or 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 additional frame-ancestors policy prevents one wildcard policy from proving unrestricted effective framing. An empty frame-ancestors; blocks framing, and XFO cannot override an enforcing frame-ancestors *. Exact tokens and first-duplicate semantics apply.
  • Recommendation: restrict frame-ancestors to '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 omit object-src with no default-src fallback. Coverage supplied by another enforcing policy counts; exact directive names, ASCII whitespace, and first-duplicate semantics apply. object-src inherits default-src; base-uri does not.
  • Recommendation: add explicit object-src 'none' (when default-src does not already cover it) and base-uri 'none'; use base-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 Server token or any X-Powered-By header, INFO for an unversioned Server product 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 as h2o are 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 no Server header by default, so a finding usually reflects a custom server.server-header or an intermediary.
  • Recommendation: suppress or genericize Server and X-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=0 during 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-Security field has a positive max-age (avoiding PT-A05-048's max-age=0 case) and either lacks includeSubDomains or sets max-age below 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 includeSubDomains only 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 always or on-param.

PT-A05-015 - Actuator shutdown endpoint is enabled

  • Severity / confidence: MEDIUM / Medium
  • Source: Spring metadata (effective management.endpoint.shutdown.access and 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=none or 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:

  1. Access — management.endpoint.<id>.access=none|read-only|unrestricted, the default access setting, and management.endpoints.access.max-permitted. none removes endpoint access; read-only permits read operations; unrestricted permits the available operations subject to caps, not unrestricted anonymous network access.
  2. Web exposure — management.endpoints.web.exposure.include and .exclude, available endpoint dependencies, and actual web mappings. include=* does not override exclusions or access caps.
  3. 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.
  4. 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 no FilterChainProxy or SecurityFilterChain bean 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}/heapdump is registered. A heap dump can contain credentials, session tokens, and PII pulled straight out of process memory.
  • Recommendation: set management.endpoint.heapdump.access=none or 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 /httpexchanges endpoint or recognizes the historical /httptrace path. The latter is a retained marker, not Spring Boot 2/3 compatibility guidance.
  • Limits: Boot 4.1 recording excludes Authorization, Cookie, and Set-Cookie by 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=none or 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 /sessions is 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 prefer read-only access 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 /loggers is 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. loggers is 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 use read-only when 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 /threaddump is 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/routes is 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=none and 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 /logfile is 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=none or 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 /caches is 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; prefer read-only when 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 /prometheus is 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=always is set.
  • Source: Spring metadata (Spring MVC mappings, Spring Security beans, management.endpoint.env.show-values)
  • Fires when: a mapping for /{management-base-path}/env is registered. The endpoint exposes the resolved Spring Environment; show-values=always permits unsanitized values unless custom sanitization applies. Actual returned values and authorization are not inspected. env is 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=none or remove unnecessary web exposure; when needed, authorize reads and keep management.endpoint.env.show-values at never or carefully configured when-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=always is set.
  • Source: Spring metadata (Spring MVC mappings, Spring Security beans, management.endpoint.configprops.show-values)
  • Fires when: a mapping for /{management-base-path}/configprops is registered. The endpoint dumps @ConfigurationProperties metadata; show-values=always permits unsanitized values unless custom sanitization applies. Actual returned values and authorization are not inspected. configprops is 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=none or remove unnecessary web exposure; when needed, authorize reads and keep management.endpoint.configprops.show-values at never or carefully configured when-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}/mappings is registered. The endpoint lists every request mapping, which hands an attacker a full route map for reconnaissance. mappings is 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 /mappings outside 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). /info is intentionally not included: Spring's own guidance treats /health and /info as the two endpoints commonly exposed publicly, so flagging it here would be noisy rather than actionable. beans, conditions, scheduledtasks, startup, and metrics are among BootUI's own actuator-exposure defaults (auditevents, sbom, flyway, and liquibase are 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 maps auditevents, sbom, flyway, or liquibase, 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}/shutdown is 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=none or remove /shutdown from 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.enabled outside local development, and never set spring.h2.console.settings.web-allow-others=true without 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 default show-details=always is ignored so the check only reports host configuration.
  • Recommendation: use when-authorized or never outside 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 mode include.
  • 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.secret and 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 literal false activation 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=false unless 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. Consider same-origin for 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. Consider same-origin or same-site when 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. Consider require-corp or credentialless for UIs that need cross-origin isolation (for example, SharedArrayBuffer usage), 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 * or https://evil.example as the allowed origin and advertises Access-Control-Allow-Methods: * or Access-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, and Authorization requires 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 remains PARTIAL; 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 Allow header or the Access-Control-Allow-Methods header lists TRACE or TRACK. Checking Access-Control-Allow-Methods in addition to Allow catches CORS configurations that advertise TRACE/TRACK as an allowed cross-origin method without necessarily surfacing it in Allow. 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. Complete Allow evidence 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 always or on-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 /jolokia is web-mapped; INFO without a mapping.
  • Source: Spring metadata (management.endpoint.jolokia.enabled, /jolokia mappings, and/or org.jolokia.http.AgentServlet on the classpath)
  • Fires when: /jolokia is web-mapped, the Jolokia servlet class is on the classpath, or the legacy management.endpoint.jolokia.enabled property 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-springboot has 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.enabled configuration. [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 /env endpoint 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 DEBUG or TRACE. 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 stale spring.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 /graphql is 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 HttpFirewall bean type)
  • Fires when: a resolved bean type is DefaultHttpFirewall. Bean presence does not prove it is the active firewall. Unlike StrictHttpFirewall, 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 StrictHttpFirewall where 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.address narrows 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.port configures a separate connector with a wildcard address (0.0.0.0, ::, [::]) or no explicit address. -1 disables 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 ManagementWebServerFactoryCustomizer sets the management connector's address from management.server.address only; it never inherits server.address. An application deliberately bound to 127.0.0.1 with management.server.port=9090 and no management address therefore exposes Actuator on every interface while the application stays loopback-only (MEDIUM). When server.address is 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.address to 127.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 framework or native. Processing/trust depends on the server and configured trusted proxies; native does 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's server.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 HANDOFF to the Security panel (QS-AUTH-*, QS-OIDC-*, and QS-TLS-004 for 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-web is 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 FilterChainProxy or SecurityFilterChain bean 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.password defined)
  • 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 URL in 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 autoConfiguredDefaultUserPresent and an explicitly true defaultUserPasswordGenerated are required; a missing/unknown generated state is not treated as true. Merely having a spring.security.user.password property does not suppress verified generated-password evidence. A custom bean named inMemoryUserDetailsManager is 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-uri and spring.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 the spring.security.oauth2.client.provider.<name>.issuer-uri pattern, 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 that SecretMasker recognizes 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-url branch was removed: QS-TLS-004 reviews it for every active tenant, honoring tenant-enabled=false and 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 is always, not never; 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 effective quarkus.http.insecure-requests at LOW, while this check rated the same configuration MEDIUM and assumed enabled even when quarkus.http.ssl.client-auth=required makes Quarkus default to disabled. [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.

IDDispositionAudit resultSources
PT-A01-001UPDATECSRF follows ambient browser credentials, including cookie/Basic JSON APIs, not a blanket stateless exemption.S01, S05
PT-A02-001UPDATEComplete cookies, presence flags, and purpose-aware HttpOnly severity.S03, S07, S08
PT-A02-002UPDATEINFO local-HTTP Secure reminder; incomplete fields cannot prove a missing flag.S07, S08, S10
PT-A02-003UPDATEEffective last SameSite and modern rejection semantics, not demonstrated leakage.S08
PT-A02-004UPDATEActive servlet Secure setting only; false permits HTTP rather than forcing it.S07, S13
PT-A02-005UPDATEActive servlet HttpOnly setting only; preserve explicit false trigger.S07, S13
PT-A02-006UPDATEActive servlet pairing and accurate None-without-Secure rejection guidance.S08, S13
PT-A07-001UPDATEMissing dependency is INFO, not proof of absent custom/proxy authentication.S01, S14
PT-A07-002UPDATEMissing Spring chain is conditional wiring review, not proof routes are unprotected.S14
PT-A07-003UPDATESecurely injected configuration is not evidence of a source-controlled credential.S14
PT-A07-004UPDATEExplicit URL tracking remains MEDIUM only in the active servlet runtime.S08, S13
PT-A07-005UPDATERequire default-user provenance and generated-password state, not a bean name alone.S14
PT-A07-006UPDATEPlaintext discovery integrity risk differs from observed token transport; preserve masking.S23
PT-A07-007RETAINImplicit-grant metadata and authorization-code/PKCE recommendation remain supported.S23
PT-A05-001UPDATEIncomplete GET diagnostic; missing fields never manufacture absence findings.S01, S02
PT-A05-002UPDATENosniff applies to relevant APIs too; exact protocol token semantics.S02, S03, S04
PT-A05-003UPDATEExact CSP directives and complete document evidence, not substring matching.S02, S06
PT-A05-004RETAINOptional Referrer-Policy INFO reminder; absence does not prove unsafe browser defaults.S02, S09
PT-A05-005UPDATEValid explicit SameSite versus browser defaults, duplicates, and completeness.S08
PT-A05-006UPDATEActual error/stack structure rather than framework words; HTTP status alone is insufficient.S12
PT-A05-007UPDATEExact Fetch preflight/header semantics and conditional credentialed-read claims.S04, S05
PT-A05-008UPDATEExact origin/status semantics; broad public API policy may be intentional.S03, S04, S05
PT-A05-010RETAINLOW missing enforced CSP prompt for documents; report-only does not enforce.S02, S06
PT-A05-011RETAINLOW technology disclosure heuristic with bounded evidence, not exploitability proof.S02
PT-A05-013RETAINOptional Permissions-Policy INFO rather than a universal requirement.S02
PT-A05-014RETAINExplicit always/on-param error-detail settings remain meaningful.S12, S13
PT-A05-015UPDATECurrent endpoint access/caps; configured availability differs from web mapping.S15
PT-A05-016UPDATEMissing Spring chain does not prove anonymous access; preserve BootUI-default exclusion.S14, S15
PT-A05-017UPDATEH2 property-only INFO; active registration MEDIUM or HIGH with remote permission, not DB-authentication bypass.S19
PT-A05-018RETAINExplicit show-values=always review; custom sanitization/auth remain untested.S15
PT-A05-019UPDATEEffective scalar/indexed origin lists and conditional exposure wording.S04, S15
PT-A05-020RETAINDevTools classpath INFO remains development-scoping advice.S24
PT-A05-021RETAINOptional COOP isolation guidance must account for popup/OAuth workflows.S02, S03
PT-A05-022RETAINCORP INFO is conditional embedding advice, not universal safety proof.S02, S03
PT-A05-023UPDATEWildcards depend on credentials mode and do not imply Authorization permission.S04
PT-A05-024UPDATETRACE is standardized diagnostics and Fetch-forbidden; advertisement is not execution.S11
PT-A05-025RETAINExplicit exception-class disclosure remains MEDIUM/High.S12, S13
PT-A05-026UPDATEReview internal/rejected-value disclosure, not normal API validation contracts.S12, S13
PT-A05-027UPDATEClasspath/stale property is not active Jolokia exposure or current historical-RCE evidence.S15
PT-A05-028UPDATEOnly observed Actuator env write mappings rate MEDIUM; configuration/Cloud support alone remain INFO.S16
PT-A05-029UPDATEScalar/indexed patterns and reflected origins differ from wire wildcard responses.S04, S15
PT-A05-030UPDATESQL statement output does not establish bound-parameter logging; retain INFO.S25
PT-A05-031RETAINFour explicit verbose logging settings remain conditional INFO, not an A09 audit.S01, S25
PT-A05-032UPDATERetain CRITICAL mapped impact; current access/exposure advice, not a fictitious non-web port.S15
PT-A05-033UPDATECredential headers are excluded by default; repository capacity/content are not guaranteed.S17
PT-A05-034UPDATERetain HIGH; session lookup/DELETE depend on available operations, access, and authorization.S15
PT-A05-035UPDATERetain MEDIUM; POST writes and authorization are not proved by a path alone.S15
PT-A05-036UPDATERetain MEDIUM; thread frames do not inherently contain argument values.S15
PT-A05-037UPDATECurrent Gateway access/topology review, not proof of a historical vulnerability.S15
PT-A05-038UPDATERetain MEDIUM; log contents/auth remain uninspected; current endpoint access guidance.S15
PT-A05-039UPDATERetain LOW; eviction is conditional on writable operations, access, and authorization.S15
PT-A05-040RETAININFO for intentionally published metrics, not an automatic vulnerability claim.S15
PT-A05-041UPDATEOrdinary /graphql is not tooling; developer-surface mappings do not prove anonymous access.S26
PT-A05-042UPDATEA bean may not be active; DefaultHttpFirewall rejects encoded slashes by default.S18
PT-A05-043UPDATENumeric/random-port semantics; wildcard binding does not prove Internet reachability.S15, S20
PT-A05-044UPDATENative forwarding has server-dependent proxy trust; retain INFO.S20
PT-A05-045REMOVEOrdinary caller-known error-path metadata; Boot 4.1 default is always. Never reuse this ID.S12, S13
PT-A05-046UPDATEEffective framing parsing and exact CSP precedence, not assumed browser bypass.S06
PT-A05-047UPDATELast recognized policy wins; unknown trailing tokens do not erase unsafe-url.S09
PT-A05-048UPDATEStrict HSTS grammar; retain INFO with HTTPS edge unassessed.S10
PT-A05-049UPDATEinclude=* remains subject to exclusions, access caps, and endpoint capabilities.S15
PT-A05-050RETAINHost-only health details/components review; preserve BootUI-default suppression.S15
PT-A05-051UPDATEBoot 4.1 codec key and applicable-component/custom-codec limitations.S13
PT-A05-052UPDATERetain HIGH; actual env identity, sanitization/auth caveats, current endpoint access model.S15
PT-A05-053UPDATERetain HIGH; actual configprops identity, sanitization/auth caveats, current access model.S15
PT-A05-054RETAINMEDIUM route metadata review; authorization remains unverified.S15
PT-A05-055RETAINBounded reconnaissance summary with authorization caveat, not a dependency vulnerability finding.S01, S15
PT-A05-056UPDATERetain CRITICAL mapped impact; current access model and successful POST remain untested.S15
PT-A05-060UPDATEIndependent policies, effective fallbacks, duplicates, nonce/hash, strict-dynamic, and sandbox script restrictions.S06
PT-A05-061UPDATERecognized legacy auditor token, not any value beginning with 1; retain LOW/Low.S02
PT-A05-062UPDATERemote-secret configuration alone is INFO; observed active remote server support rates HIGH.S24
PT-A05-063UPDATEStrict HSTS parsing; ASVS level/subdomain-readiness distinctions.S03, S10
PT-A05-064RETAINOptional Secure session-like prefix suggestion stays INFO, not mandatory renaming.S03, S08
PT-A05-065UPDATENull ACAO does not match the sent origin; conditional observation, not verified opaque-origin access.S04, S05
PT-A05-066UPDATEIndependent enforced CSP policies intersect; one wildcard does not prove unrestricted framing.S06
PT-A05-067UPDATEExact CSP composition; object-src has default fallback, base-uri does not.S06
PT-A05-068RETAINOptional COEP isolation guidance must account for intentional cross-origin dependencies.S02
PT-A05-069UPDATEUnavailable OPTIONS evidence differs from an inspected policy-rejected preflight.S04, S11
PT-A05-070UPDATEQuarkus reflects wildcard matches; effective activation/list/credentials determine conditional risk.S21
PT-A05-072UPDATEOnly 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.

IDDispositionAudit resultSources
PT-A05-070REMOVEDuplicated QS-CORS-001/002, which always run on Quarkus; delivered CORS stays covered by the synthetic preflight.S21
PT-A05-072REMOVEDuplicated QS-TLS-001 at a conflicting severity and ignored the client-auth=required default.S22
PT-A07-006UPDATESpring-only; QS-TLS-004 owns the Quarkus OIDC auth-server URL with tenant and extension gating. Quarkus A07 is a HANDOFF.S23
PT-A05-060UPDATEAdds plain data:/http:/https: script scheme sources (MEDIUM) and a script-unrestricted CSP (LOW).S06, S27
PT-A05-043UPDATEMEDIUM only when the management listener is broader than a narrowed server.address; otherwise LOW.S15, S29
PT-A05-011UPDATEUnversioned 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/Expires on a session-id cookie) and session cookie Domain attribute: the anonymous missing-resource probe almost never issues a session cookie, deletion cookies (Max-Age=0, past Expires) would be false positives, and __Host- guidance in PT-A05-064 already forbids Domain.
  • 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 no Origin.

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-path defaults to always); codecs use spring.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 enabled and global enabled-by-default: each is mutually exclusive with its corresponding access setting, explicit endpoint settings override the global default, and max-permitted caps 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.include entry. 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 match data:; 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 Server values 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

  1. Add a final class to PentestingChecks.java extending AbstractPentestingCheck. Pass a PentestingDefinition with a unique stable ID (PT-<category>-NNN), title, OWASP 2025 category, severity, confidence, source (SPRING_METADATA or HTTP_SYNTHETIC), target, recommendation, and learn-more URL.
  2. Implement evaluate(PentestingContext) so it returns List.of() when the check is silent and one or more PentestingFindingDtos otherwise. Reuse existing PentestingContext accessors — do not introduce new HTTP traffic.
  3. Register the class in PentestingCheckRegistry.ACTIVE_CHECKS. If the new check changes what an OWASP category covers, update the matching CoverageDefinition.scannedDescription. A SPRING_METADATA check needs a matching PentestingConfigSnapshot/PentestingSecurityStatus/PentestingEndpointInventory field populated by SpringPentestingObservationCollector. 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 into PARTIAL/INDETERMINATE status.
  4. 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.
  5. Append the new check to this page in the matching OWASP section so the published catalogue stays in sync.
Prev
Memory
Next
GraalVM readiness

© 2026 Julien Dubois