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

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

    • All features
    • Overview
    • Advisors
    • Runtime
    • Configuration
    • Database
    • Security
    • Services
    • Diagnostics
    • Developer tools
  • Reference

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

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

    • Repository
    • Specification
    • Implementation plan
    • 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 Spring and Quarkus adapters), not in a per-framework adapter module. The list intentionally stays compact and reviewable; adding a new check means adding one focused class plus a registry entry, never adding 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 present, and (for one check) reflection over registered SecurityFilterChain beans; Quarkus MicroProfile Config values for CORS, OIDC, and HTTP/TLS posture. Checks are designed to never flag a value that only exists because BootUI itself injected it (see "BootUI's own actuator defaults are never flagged" below).
  • Synthetic HTTP requests — at most two direct requests per scan to the literal loopback address 127.0.0.1 against /<context-path>/__bootui_pentesting__/missing-resource in the host application (never /bootui): one GET with Accept: text/html, and one OPTIONS preflight with Origin: https://evil.example and Access-Control-Request-Method: GET. The application's own response headers reveal CORS, security-header, and cookie posture. Each request has a two-second timeout, does not follow redirects, and bypasses configured proxies. Bodies are inspected only for fixed verbose-error markers and never included in the report. If the port or context path fails validation, neither request is sent.

The target and evidence are deliberately bounded:

  • The server port must be an integer from 1 through 65535. Context paths are limited to 256 characters and reject encoded (%), ambiguous (//, backslash, query, or fragment), control-character, and dot-segment forms.
  • The GET body is retained for inspection up to 8 KiB. Each response retains at most 64 header names, 128 total header values, 16 KiB of header text, 256 characters per header name, and 4096 characters per value. Oversized names are dropped; oversized values are clipped.
  • Spring collection inspects at most 64 MVC handler-mapping beans and 4096 endpoint patterns. OAuth discovery inspects at most 128 enumerable property sources, 4096 property names total, and 64 issuer plus 64 implicit-grant entries. Quarkus's fallback TLS discovery inspects at most 4096 configuration property names.
  • Any failed request, incomplete metadata read, or exceeded retention/metadata limit makes the scan PARTIAL. Findings from retained evidence remain valid, while affected no-finding coverage becomes INDETERMINATE.

Browser-specific checks run only when the GET response identifies HTML/XHTML through Content-Type, or its retained body clearly begins with an HTML doctype or <html> element. This avoids treating a JSON/API response as a browser document merely because the probe requested HTML.

Findings are heuristic review prompts, not proof of exploitability. The panel is a developer hygiene tool, not a replacement for a real penetration test or DAST suite.

The parsing and severity choices 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 the official Quarkus CORS and HTTP/TLS guides.

Check IDs are stable API-facing identifiers and keep their original PT-* prefixes for compatibility. A check ID's number therefore might not match the OWASP Top 10 2025 category displayed in the panel.

Why BootUI's own actuator defaults are never flagged

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

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 broader: Spring contributes Security wiring, default-user, session-tracking, issuer, and implicit-grant checks; Quarkus contributes a live plaintext quarkus.oidc.auth-server-url check. A no-finding Quarkus A07 result is therefore INFO, not a green assertion that the Spring-only checks ran.

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.

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." It supplies real Quarkus CORS, OIDC, and HTTP/TLS configuration instead of pretending Spring metadata was checked.

PentestingObservation separately records Spring-metadata availability, endpoint-inventory availability/truncation, and two distinct framework metadata truncation signals — authMetadataTruncated (Spring OAuth2 client-registration enumeration) and transportMetadataTruncated (Quarkus TLS/key-store property enumeration) — kept apart so a truncated enumeration on one platform never marks an unrelated OWASP category indeterminate on the other (e.g. Spring OAuth2 truncation only affects A07 Authentication Failures, never A04 Cryptographic Failures; Quarkus TLS truncation only affects A04, never A07). Neither signal affects A02 Security Misconfiguration: no A02 check consumes OAuth2 or TLS enumeration evidence today. 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".

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, or active probing is deliberately out of scope.

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 Misconfiguration62Missing or unsafe security headers, cookie flags and name prefixes, CORS (including wildcard, credentialed, null-origin, and Quarkus configuration patterns), 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 Failures5Informational HSTS-over-HTTP observations, Secure-cookie reminders, and Quarkus plaintext HTTP alongside TLS; deep cryptographic code review is not performed. 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 OAuth2/OIDC issuer URLs on both adapters, and Spring OAuth implicit grants. Quarkus reports its narrower OIDC-only metadata coverage as INFO when no finding is produced.
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 Conditions5Verbose error responses and Spring Boot spring.web.error.include-* disclosure settings.
Total80

The zero-check categories are scoped intentionally: BootUI flags bounded local signals that are commonly forgotten or risky, but it never produces a value judgement on application code, architecture, operations, or payload behavior that requires a manual review.

Severity scale

Severity reflects the worst plausible impact if the finding is real, not the likelihood:

  • CRITICAL — immediate severe impact if exposed (e.g. remotely reachable H2 SQL console, unprotected heap dump or shutdown actuator endpoint).
  • HIGH — credible exploit path with clear impact (e.g. credentialed CORS to a permissive origin, sensitive actuator endpoint exposure, no Spring Security on application mappings).
  • MEDIUM — leaks internals or weakens defenses but typically needs chaining (e.g. actuator value exposure, verbose errors, missing session cookie hardening).
  • LOW — defense-in-depth gap (e.g. missing security headers, broad CORS without credentials).
  • INFO — informational hygiene prompt (e.g. missing optional headers, dev-only switches that are expected locally).

Some checks assign severity dynamically, so the same check can appear as MEDIUM/HIGH or escalate to CRITICAL when the inspected configuration removes important safeguards.

Severity is shown in the panel alongside a confidence rating (Low / Medium / High) that reflects 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-001MEDIUMCookie 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-065MEDIUMCORS allows the literal 'null' origin
  21. PT-A05-010LOWMissing Content-Security-Policy header
  22. PT-A05-060MEDIUMContent-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-011LOWResponse 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-017MEDIUMH2 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-062HIGHSpring 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-070MEDIUMQuarkus CORS origin configuration is overly broad
  60. PT-A05-072MEDIUMQuarkus TLS endpoint also accepts plaintext HTTP
  61. PT-A05-025MEDIUMspring.web.error.include-exception is enabled
  62. PT-A05-026MEDIUMspring.web.error.include-binding-errors reveals validation details
  63. PT-A05-027MEDIUMJolokia JMX-over-HTTP bridge is configured or present
  64. PT-A05-028MEDIUMActuator env endpoint accepts POST writes
  65. PT-A05-029MEDIUMActuator CORS allowed-origin-patterns is a wildcard
  66. PT-A05-030INFOspring.jpa.show-sql is enabled
  67. PT-A05-031INFOVerbose logging level configured for framework packages
  68. PT-A05-051INFORequest detail logging is enabled
  69. PT-A05-041INFOAPI documentation or developer console is exposed
  70. PT-A05-042MEDIUMSpring Security HttpFirewall is the permissive DefaultHttpFirewall
  71. PT-A05-043MEDIUMManagement interface potentially externally reachable
  72. PT-A05-044INFOserver.forward-headers-strategy trusts X-Forwarded-* headers
  73. PT-A05-045INFOspring.web.error.include-path exposes request paths in error responses
  74. PT-A07-001HIGHSpring Security is not on the classpath
  75. PT-A07-002MEDIUMNo Spring Security filter chain is configured
  76. PT-A07-003MEDIUMSpring Security user password is set in configuration
  77. PT-A07-004MEDIUMServlet session tracking modes include URL
  78. PT-A07-005MEDIUMSpring Boot auto-generated security password is in use
  79. PT-A07-006HIGHOAuth2/OIDC issuer URI uses plaintext HTTP
  80. 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 protection is opt-out in Spring Security; disabling it in every chain is only safe for fully stateless, token-authenticated APIs. For browser-rendered routes it removes a primary defense.
  • Recommendation: leave CSRF enabled for any chain that serves a browser; only disable on chains that exclusively serve stateless APIs authenticated with bearer tokens.

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: MEDIUM / Medium
  • Source: synthetic HTTP (Set-Cookie on the GET response)
  • Fires when: any Set-Cookie header on the synthetic response lacks HttpOnly. Conventional script-readable XSRF-TOKEN and CSRF-TOKEN cookies are downgraded to INFO because browser code commonly copies them into a request header; the prompt asks the developer to confirm they carry no session or authentication material. Evidence includes only a sanitized, 80-character cookie-name label, never the value.
  • Recommendation: mark session and sensitive cookies HttpOnly so browser scripts cannot read them.

PT-A02-002 - Cookie is missing Secure

  • Severity / confidence: INFO / Low
  • Source: synthetic HTTP (Set-Cookie on the GET response)
  • Fires when: a Set-Cookie header lacks Secure.
  • 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.

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 cookie is set with SameSite=None but no Secure attribute. Browsers reject such cookies and they can leak over plaintext.

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. A missing value does not fire.
  • Recommendation: remove the override or set it to true for HTTPS deployments.

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. A missing value does not fire.
  • Recommendation: remove the override so the session identifier is not readable from JavaScript.

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: same-site=none is explicitly configured together with secure=false. 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 allowed cross-site.

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.

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.

PT-A05-002 - Missing X-Content-Type-Options nosniff header

  • Severity / confidence: LOW / Medium
  • Source: synthetic HTTP (GET)
  • Fires when: a browser-document response's first X-Content-Type-Options field value is absent or is not the trimmed, case-insensitive token nosniff. A comma-joined sniff, nosniff value does not pass.

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.

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 trimmed values are not exactly DENY or SAMEORIGIN (case-insensitive). Repeated identical supported values are accepted; conflicting, comma-joined, and obsolete ALLOW-FROM values are unsupported.
  • Recommendation: use DENY, SAMEORIGIN, or a CSP frame-ancestors directive.

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.

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 effective (last comma-separated) Referrer-Policy value is unsafe-url, which sends full URLs to same-origin and cross-origin destinations.
  • Recommendation: prefer no-referrer, strict-origin, or strict-origin-when-cross-origin.

PT-A05-005 - Cookie is missing SameSite

  • Severity / confidence: LOW / Medium
  • Source: synthetic HTTP (Set-Cookie)
  • Fires when: a Set-Cookie lacks any SameSite attribute.
  • Recommendation: set SameSite=Lax or SameSite=Strict unless the cookie must be sent cross-site.

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 response body matches a verbose-error heuristic. The marker list is framework-neutral so this check carries real signal on both adapters: Spring markers (stacktrace, stack trace, java.lang., org.springframework, nestedservletexception), Quarkus markers (io.quarkus., org.jboss.resteasy., jakarta.ws.rs., io.vertx., caused by:), and a generic <Something>.java:<line> source-reference pattern that doesn't depend on any package prefix. Body content is matched against fixed markers and never persisted.

PT-A05-007 - CORS allows credentialed cross-origin requests

  • Severity / confidence: dynamic / High
  • Source: synthetic HTTP (OPTIONS)
  • Fires when: the preflight sets Access-Control-Allow-Credentials: true and either reflects the untrusted probe origin https://evil.example (HIGH, accepted by browsers with credentials) or sends wildcard Access-Control-Allow-Origin: * (LOW, rejected by Fetch for credentialed requests). The wildcard case is not reported as credential theft; arbitrary non-credentialed cross-origin reads remain possible.

PT-A05-008 - CORS allows a broad cross-origin request

  • Severity / confidence: LOW / Low
  • Source: synthetic HTTP (OPTIONS)
  • Fires when: the preflight allows * or the attacker origin without credentials. This is defense-in-depth rather than an immediate exploit, but signals an overly permissive CORS policy.

PT-A05-065 - CORS allows the literal 'null' origin

  • Severity / confidence: MEDIUM / Medium (escalates to HIGH when paired with Access-Control-Allow-Credentials: true)
  • Source: synthetic HTTP (OPTIONS)
  • Fires when: the preflight response's Access-Control-Allow-Origin is the literal string null (trimmed, exact match) — independent of whether the synthetic evil origin (https://evil.example) was itself echoed. Sandboxed iframes, data:/file: URLs, and some redirected requests send a literal Origin: null, so allow-listing it trusts any such context.
  • Recommendation: never allow-list Access-Control-Allow-Origin: null; enumerate explicit trusted origins instead. See PortSwigger's CORS guide, "Whitelisted null origin value".

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).

PT-A05-060 - Content-Security-Policy is present but weakened

  • Severity / confidence: MEDIUM / Low
  • Source: synthetic HTTP (GET)
  • Fires when: a browser-document GET response includes a Content-Security-Policy header that allows 'unsafe-eval', a bare * source in script-src, script-src-elem, script-src-attr, or default-src, or 'unsafe-inline' in those directives without a nonce or hash.
  • Recommendation: avoid 'unsafe-inline' and 'unsafe-eval' for scripts, avoid bare * sources, and prefer nonces or hashes combined with 'strict-dynamic'.

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 sets X-XSS-Protection to a value starting with 1 (for example 1 or 1; mode=block).
  • Recommendation: set X-XSS-Protection: 0 or omit the header, and rely on a strong Content-Security-Policy instead.

PT-A05-066 - Content-Security-Policy frame-ancestors is overly permissive

  • Severity / confidence: MEDIUM / Medium
  • Source: synthetic HTTP (GET)
  • Fires when: a browser-document response's Content-Security-Policy header includes a frame-ancestors directive whose value contains a bare * token, allowing any origin to frame the page.
  • Recommendation: restrict frame-ancestors to 'self' or an explicit list of trusted origins. See MDN's frame-ancestors reference.

PT-A05-067 - Content-Security-Policy is missing object-src or base-uri

  • Severity / confidence: LOW / Low
  • Source: synthetic HTTP (GET)
  • Fires when: a browser-document response's Content-Security-Policy header is present but omits base-uri, or omits object-src and has no default-src fallback (object-src is a fetch directive that inherits from default-src when absent; base-uri is a document directive with no such fallback, so its absence is always reported).
  • 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. This prevents a missing fallback from being used for plugin or <base> tag injection. See the OWASP Secure Headers Project.

PT-A05-011 - Response discloses server technology

  • Severity / confidence: LOW / Low
  • 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.

PT-A05-048 - Local HTTP response advertises disabled HSTS

  • Severity / confidence: INFO / Low
  • Source: synthetic HTTP (GET)
  • Fires when: the plaintext loopback response advertises Strict-Transport-Security: max-age=0. 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.

PT-A05-063 - Local HTTP response advertises weak HSTS

  • Severity / confidence: INFO / Low
  • Source: synthetic HTTP (GET)
  • Fires when: Strict-Transport-Security is present with a positive max-age (so this does not double-report PT-A05-048's max-age=0 case) and either lacks includeSubDomains or sets max-age below the OWASP ASVS one-year minimum (31536000 seconds). Because the probe is HTTP, the result is an informational reminder to verify the deployed HTTPS edge.
  • Recommendation: set a max-age of at least one year and include includeSubDomains so the whole origin is protected, not just the exact host. See OWASP ASVS 5.0 V3.4.1 and the OWASP HSTS Cheat Sheet.

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.

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 (management.endpoint.shutdown.enabled)
  • Fires when: explicitly set to true. If /shutdown is also web-mapped, PT-A05-056 also fires because the endpoint is reachable over HTTP.

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.

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 (CVE-2022-22947 is a real-world case of a filter chain present while a mapped endpoint stayed unprotected). 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: disable management.endpoint.heapdump.enabled or restrict the actuator base path to a non-web management port.

PT-A05-033 - Actuator /httpexchanges (or /httptrace) endpoint is exposed

  • Severity / confidence: HIGH / High
  • Source: Spring metadata (Spring MVC mappings)
  • Fires when: a mapping for /httpexchanges (Spring Boot 3.x+) or the legacy /httptrace (Spring Boot ≤ 2.x) is registered. Both replay recent HTTP requests/responses, including Authorization, Cookie, and other sensitive headers.
  • Recommendation: keep it disabled in production. Where it is needed locally, require authentication and access controls.

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. The endpoint lists session IDs and supports deletion by ID.
  • Recommendation: do not expose sessions. If required, restrict to authenticated administrators only.

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. The endpoint supports POST writes that change log levels at runtime; flipping a noisy package to DEBUG can leak request payloads and credentials into logs. 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: keep loggers behind authentication or disable web exposure.

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. The dump reveals internal stack frames, library versions, and sometimes parameter values that aid reconnaissance.
  • Recommendation: do not expose threaddump unauthenticated.

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 and supports route mutation when actuator writes are enabled.
  • Recommendation: keep gateway actuator endpoints behind authentication and only expose what operators need.

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. Streams the contents of the configured log file, which routinely captures stack traces, request data, and occasional secrets.
  • Recommendation: do not expose logfile over HTTP outside of trusted networks.

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. Supports DELETE requests that evict cache entries and can be abused as a denial-of-service primitive.
  • Recommendation: leave the endpoint disabled unless administrators need it; require authentication when enabled.

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; with show-values=always it returns unmasked property values instead of masking them. 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: restrict or disable /env outside development, and keep management.endpoint.env.show-values at never or when-authorized.

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 beans; with show-values=always it returns unmasked values instead of masking them. 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: restrict or disable /configprops outside development, and keep management.endpoint.configprops.show-values at never or when-authorized.

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 only reports that a POST to the mapped endpoint would stop the application.
  • Recommendation: disable management.endpoint.shutdown.enabled or remove /shutdown from the web exposure list.

PT-A05-017 - H2 database console is enabled

  • Severity / confidence: MEDIUM / High; escalates to CRITICAL when spring.h2.console.settings.web-allow-others=true.
  • Source: Spring metadata (spring.h2.console.enabled, spring.h2.console.settings.web-allow-others)
  • Fires when: spring.h2.console.enabled=true. The finding is CRITICAL when web-allow-others=true is also set, which exposes the SQL console to remote callers.
  • Recommendation: disable spring.h2.console.enabled outside local development, and never set spring.h2.console.settings.web-allow-others=true.

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. That reveals raw property values (potentially secrets) through /env or /configprops.

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 *.
  • Recommendation: expose only the actuator endpoints operators need and keep sensitive endpoints disabled or authenticated.

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 comma-separated list contains *.

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: HIGH / High
  • Source: Spring metadata (spring.devtools.remote.secret)
  • Fires when: the property is set to anything other than false, mirroring the exact @ConditionalOnProperty("spring.devtools.remote.secret") condition that activates RemoteDevToolsAutoConfiguration. Setting the secret alone is sufficient to wire the remote DispatcherFilter that accepts class updates over HTTP, and RemoteRestartConfiguration defaults remote restart to enabled (spring.devtools.remote.restart.enabled defaults to true) once the secret is present — so this single property both opens a remote class-transfer channel and turns on remote restart unless explicitly disabled.
  • 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.

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.

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.

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). 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: *. Trusted origins do not trigger this check.

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. Neither method has a legitimate web-application use and both can aid cross-site tracing attacks. Confidence is Low because an OPTIONS advertisement does not prove a subsequent TRACE request would execute; BootUI deliberately does not send TRACE.

PT-A05-070 - Quarkus CORS origin configuration is overly broad

  • Severity / confidence: MEDIUM / High
  • Source: Quarkus metadata (quarkus.http.cors.enabled/legacy quarkus.http.cors, quarkus.http.cors.origins, and quarkus.http.cors.access-control-allow-credentials)
  • Fires when: Quarkus CORS is enabled and any comma-separated origin token is * or /.*/. If credentials are explicitly enabled, evidence states that browsers reject credentialed wildcard responses rather than overstating credential theft; arbitrary non-credentialed cross-origin reads remain allowed.
  • Recommendation: configure exact trusted origins.

PT-A05-072 - Quarkus TLS endpoint also accepts plaintext HTTP

  • Severity / confidence: MEDIUM / High
  • Source: Quarkus metadata (TLS key-store/certificate presence and quarkus.http.insecure-requests)
  • Fires when: TLS is configured and insecure requests resolve to enabled (including Quarkus's default).
  • Recommendation: set quarkus.http.insecure-requests=redirect or disabled.

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. Surfaces field-level validation errors to API callers.

PT-A05-027 - Jolokia JMX-over-HTTP bridge is configured or present

  • Severity / confidence: MEDIUM / Low when /jolokia is web-mapped or the Jolokia classes are present alongside the legacy enabled property; INFO / Low when only the legacy property is set with no classpath or mapping evidence.
  • 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: Spring Boot's own built-in Jolokia integration was deprecated in 3.3 and removed by 3.5/4.x — management.endpoint.jolokia.enabled alone (no classpath, no mapping) is now almost certainly stale, no-op configuration, so that combination is downgraded to INFO. The current, supported way to run Jolokia on Spring Boot 4 is the third-party jolokia-support-springboot add-on, gated by management.endpoints.web.exposure.include=jolokia rather than the old enabled flag; the classpath-presence and mapped-endpoint signals stay valid evidence either way.
  • Recommendation: if Jolokia is intentional, confirm it is not web-exposed and is locked down behind authentication; otherwise remove the dependency and any leftover management.endpoint.jolokia.enabled configuration.

PT-A05-028 - Actuator env endpoint accepts POST writes

  • Severity / confidence: MEDIUM / High
  • Source: Spring metadata (management.endpoint.env.post.enabled)
  • Fires when: explicitly true. Allows POST /actuator/env to mutate Spring properties at runtime.

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 token in the comma-separated list equals *. Combined with credentials this can expose actuator endpoints to any origin.

PT-A05-030 - spring.jpa.show-sql is enabled

  • Severity / confidence: INFO / Low
  • Source: Spring metadata (spring.jpa.show-sql)
  • Fires when: explicitly true. Logs full SQL statements; can leak schema and parameter values to log sinks.

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.codec.log-request-details)
  • Fires when: either property is explicitly true. These switches can expose request parameters, headers, and payload metadata when matching debug logging is enabled.
  • Recommendation: keep request detail logging disabled outside short local debugging sessions.

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, /graphiql, or /graphql. These are typically helpful locally but should not ship to production unauthenticated. H2 console exposure is reported separately by PT-A05-017.
  • Recommendation: gate them behind a Spring profile (dev, local) or Spring Security rules.

PT-A05-042 - Spring Security HttpFirewall is the permissive DefaultHttpFirewall

  • Severity / confidence: MEDIUM / High
  • Source: Spring metadata (reflection over the registered HttpFirewall bean)
  • Fires when: the resolved bean type is DefaultHttpFirewall. The Spring Security default is StrictHttpFirewall, which rejects URL-encoded path traversal, semicolons, and other request-smuggling vectors. Switching to DefaultHttpFirewall opens those classes back up.
  • Recommendation: remove the DefaultHttpFirewall override and rely on StrictHttpFirewall. If a specific request shape must be allowed, customize StrictHttpFirewall instead of replacing it.

PT-A05-043 - Management interface potentially externally reachable

  • Severity / confidence: MEDIUM / Medium
  • Source: Spring metadata (management.server.port, management.server.address, server.port)
  • Fires when: management.server.port configures a separate connector (not -1, not the main server port, and not the embedded default 8080 when server.port is unset) and either management.server.address is explicitly 0.0.0.0, ::, or [::], or the address is blank so the embedded server default bind address is used. Renamed from "Management server bound to 0.0.0.0": the check also fires when the address is merely unset (not just explicitly 0.0.0.0), so the title now reflects that broader "potentially reachable" condition; the evidence always states the exact triggering management.server.address/management.server.port tuple.
  • Recommendation: bind the management port to 127.0.0.1/::1, a private interface, or a dedicated network segment. Combine with authentication on every sensitive actuator.

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. Forwarded headers (X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto) are trusted from the immediate caller, which can be spoofed if the application is reachable directly rather than only through a trusted reverse proxy.
  • 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.

PT-A05-045 - spring.web.error.include-path exposes request paths in error responses

  • Severity / confidence: INFO / Low
  • Source: Spring metadata (spring.web.error.include-path)
  • Fires when: explicitly set to always or on-param. The default Spring Boot setting is never; switching it on echoes the request URI back in the error JSON, which can aid attacker reconnaissance when probing routes.
  • Recommendation: leave spring.web.error.include-path at its default (never) outside of local debugging.

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. Quarkus runs the plaintext OIDC auth-server check and reports no-finding A07 coverage as INFO, without claiming the Spring Security, servlet-session, default-user, or implicit-grant metadata was inspected. See "Platform-specific metadata coverage" above.

PT-A07-001 - Spring Security is not on the classpath

  • Severity / confidence: HIGH / High
  • Source: Spring metadata (classpath + Spring MVC mappings)
  • Fires when: at least one application mapping exists and spring-security-web is absent. Application routes are served with no authentication or authorization layer.

PT-A07-002 - No Spring Security filter chain is configured

  • Severity / confidence: MEDIUM / Medium
  • 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.

PT-A07-003 - Spring Security user password is set in configuration

  • Severity / confidence: MEDIUM / 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. This signals an in-config credential that should be replaced with a real user store.

PT-A07-004 - Servlet session tracking modes include URL

  • Severity / confidence: MEDIUM / High
  • Source: Spring metadata (server.servlet.session.tracking-modes)
  • Fires when: the comma-separated list includes URL. URL session tracking leaks session identifiers in links, logs, and Referer headers.

PT-A07-005 - Spring Boot auto-generated security password is in use

  • Severity / confidence: MEDIUM / Medium
  • Source: Spring metadata (Spring Security bean inventory + spring.security.user.password presence)
  • Fires when: Spring Security is on the classpath, spring.security.user.password is not configured, and the context contains a bean named inMemoryUserDetailsManager — the canonical artefact of Spring Boot's UserDetailsServiceAutoConfiguration. That combination means the application is still running with the auto-generated user account and a random password printed once at startup.
  • Why it matters: anyone who tails the startup log captures the password forever, and the credential rotates only on restart. It also commonly survives into staging or demo deployments by accident.
  • 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 auto-configured fallback is replaced.

PT-A07-006 - OAuth2/OIDC issuer URI uses plaintext HTTP

  • Severity / confidence: HIGH / Medium
  • Source: framework metadata (spring.security.oauth2.resourceserver.jwt.issuer-uri, spring.security.oauth2.client.provider.*.issuer-uri, and quarkus.oidc.auth-server-url)
  • Fires when: any configured OAuth2/OIDC issuer/auth-server URL starts with http:// (case-insensitive). The Spring resource-server property and Quarkus auth-server URL are read directly; Spring 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 endpoints that issue or validate tokens. A plaintext issuer exposes authorization codes, access tokens, and ID tokens to network interception, and undermines discovery-document integrity (an on-path attacker can rewrite .well-known/openid-configuration).
  • Recommendation: use an https:// issuer/auth-server 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.

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 grant type is exactly implicit. 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. Two checks were retired by this review:

  • 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.

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, FRAMEWORK_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