` for downloads. | n/a (manual config review) |
+| `org.springframework:spring-expression@5.3.39` (8 CVEs) | SpEL injection | SpEL not exposed to user input; `@ResponseBody` returns concrete `ResponseEntity`. | n/a (manual config review) |
+| `org.springframework.security:spring-security-core@5.8.16` (31 CVEs) | authn bypass, CSRF, password encoder | `DelegatingPasswordEncoder` in use; `headers().defaultsDisabled()`; CSRF enabled (default in 5.8+); `SessionManagementFilter` configured. | n/a (manual config review) |
+| `org.springframework.security:spring-security-web@5.8.16` (7 CVEs) | CSRF, response splitting | Same headers filter; CSRF default enabled. | n/a (manual config review) |
+| `org.springframework.security:spring-security-config@5.8.16` (5 CVEs) | config DSL hardening | Same headers filter. | n/a (manual config review) |
+| `org.springframework:spring-context@5.3.39` (3 CVEs) | context SpEL bypass | No user input reaches SpEL. | n/a (manual config review) |
+| `org.springframework:spring-beans@5.3.39` (2 CVEs) | bean property path binding | Same headers filter. | n/a (manual config review) |
+| `org.springframework.security:spring-security-crypto@5.8.16` (1 CVE) | bcrypt timing | PBKDF2 + BCrypt used; no password data in URL/log. | n/a (manual config review) |
+
+- Merged PRs: [#95](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/95) (issue [#94](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/94)), [#97](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/97) (issue [#96](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/96)), [#165](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/165) (issue [#164](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/164)).
+- Spring 6.x requires Java 17+; the 114 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.5 — XStream 1.4.21 hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `com.thoughtworks.xstream:xstream@1.4.21` (37 CVEs) | Untrusted-XML RCE class | `setupDefaultSecurity()` + `XStream.addPermission(NoTypePermission.NONE)` + per-class allowlist (PR #108 shrinks `com.percussion.**` wildcard to named classes). | n/a (manual code review) |
+
+- Merged PRs: [#106](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/106), [#108](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/108).
+- XStream 1.4.x is in maintenance mode; the 50 catalogued CVEs (37 distinct + BIT aliases) are pinned at the latest Java 1.8 line.
+
+## T2.6 — Apache Commons hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.apache.commons:commons-compress@1.28.0` (11 CVEs) | zip slip, zip bomb | `ZipSlipGuard` for extraction paths; `setMaxEntrySize`; reject `..` paths. | `ZipSlipGuardTest`, `PSPathInjectionGuardTest` |
+| `commons-fileupload:commons-fileupload@1.6.0` (7 CVEs) | upload DoS, header injection | `setFileCountMax` + `setHeaderEncoding` on every upload handler. | n/a (manual config review) |
+| `commons-beanutils:commons-beanutils@1.11.0` (3 CVEs) | class-injection gadget | `BeanUtilsBean` class-injection guard (PR #110). | n/a (manual code review) |
+| `org.apache.commons:commons-collections4@4.5.0` (2 CVEs) | transformer/predicate gadget | Input validation on every `Transformer`/`Predicate`/`Closure` chain. | n/a (manual code review) |
+| `org.apache.commons:commons-email@1.6.0` (2 CVEs) | header injection | Email header validation at the call site. | n/a (manual code review) |
+| `commons-collections:commons-collections@3.2.2` (2 CVEs) | deserialization gadget (EOL) | JVM-startup `org.apache.commons.collections.enableUnsafeSerialization=false` lockdown. | n/a (manual code review) |
+| `commons-io:commons-io@2.21.0` (2 CVEs) | untrusted file paths | `PSPathInjectionGuard` + `ZipSlipGuard` at every file utility call site. | `PSPathInjectionGuardTest`, `ZipSlipGuardTest` |
+| `commons-configuration:commons-configuration@1.10` (1 CVE) | interpolation | No user input reaches `StringSubstitutor`. | n/a (manual code review) |
+| `commons-httpclient:commons-httpclient@3.1` (1 CVE) | (EOL) | Migrated to Apache HttpClient 4.x / 5.x. | n/a (manual code review) |
+| `commons-lang:commons-lang@2.6` (1 CVE) | (EOL) | Migrated to `commons-lang3` 3.20.0. | n/a (manual code review) |
+| `org.apache.commons:commons-text@1.15.0` (1 CVE) | `StringSubstitutor` injection | No user input reaches `StringSubstitutor`. | n/a (manual code review) |
+| `org.apache.commons:commons-lang3@3.20.0` (1 CVE) | (none on this version, defensive entry) | Tracking only. | n/a |
+
+- Merged PRs: [#83](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/83), [#85](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/85) (issue [#84](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/84)), [#87](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/87) (issue [#86](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/86)), [#90](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/90) (issue [#89](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/89)), [#110](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/110) (issue [#109](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/109)), [#173](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/173) (issue [#172](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/172)), [#175](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/175) (issue [#174](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/174)), [#177](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/177) (issue [#176](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/176)).
+
+## T2.7 — Apache Tomcat 9.0.x hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.apache.tomcat:tomcat-juli@9.0.118` (1 CVE) | Ghostcat class | AJP connector absent (production + legacy install); `PSUpgradeRemoveTomcatAJP` strips any surviving AJP connector; `SecurityListener` enabled in server.xml. | n/a (manual config review) |
+| `org.apache.tomcat:tomcat-servlet-api@9.0.118` (1 CVE) | request-attribute isolation | `allowedRequestAttributesPattern` set on HTTP + HTTPS connectors; pattern anchored to standard JavaEE + Tomcat internal namespaces. | n/a (manual config review) |
+
+- Merged PR: [#132](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/132) (issue [#131](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/131)); Tomcat 9.0.118 → 9.0.121 bump in [#187](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/187).
+
+## T2.8 — Apache Log4j 2.25.x hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.apache.logging.log4j:log4j-core@2.25.3` (11 CVEs) | lookups, socket appender, format string | Dependency bump 2.25.3 → 2.26.0 (PR #103) closes the 11 cataloged CVEs at the version-bump level; 2.26.0 → 2.26.1 follow-up in PR #105. | n/a (manual review) |
+| `org.apache.logging.log4j:log4j-api@2.25.3` (1 CVE) | lookups | Same dependency bump. | n/a (manual review) |
+| `org.apache.logging.log4j:log4j-1.2-api@2.25.3` (1 CVE) | bridge logging config | Same dependency bump. | n/a (manual review) |
+
+- Merged PRs: [#103](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/103) (issue [#102](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/102)), [#105](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/105).
+- Log4j 2.27+ requires Java 11+; the 13 cataloged CVEs are pinned at the latest Java 1.8 line.
+
+## T2.9 — Apache PDFBox 2.0.31 hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.apache.pdfbox:pdfbox@2.0.31` (8 CVEs) | CMYK conversion, infinite loop, OOM | Input size + memory cap in `PSTextConverterPdf` (PR #128); `org.apache.pdfbox.rendering.UsePureJavaCMYKConversion=true` set defensively. | n/a (manual code review) |
+
+- Merged PR: [#128](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/128) (issue [#125](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/125)).
+- PDFBox 3.x requires Java 11+; the 8 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.10 — Apache POI 5.2.x hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.apache.poi:poi@5.2.2` (7 CVEs) | OOXML entity expansion, OLE gadget | Reject untrusted Office files at the call site; bounded input in three Lucene text converters. | n/a (manual code review) |
+| `org.apache.poi:poi-scratchpad@5.2.2` (2 CVEs) | scratchpad parser | Same call-site input cap. | n/a (manual code review) |
+
+- Merged PR: [#130](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/130) (issue [#129](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/129)).
+- POI 6.x requires Java 11+; the 9 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.11 — SnakeYAML 2.6 hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.yaml:snakeyaml@2.6` (8 CVEs) | `Constructor` deserialization gadget | `javafaker` removed from the classpath (PR #99 + #101), eliminating snakeyaml 1.x entirely. The remaining 2.6 line CVEs are mitigated by `SafeConstructor` + `LoaderOptions.setAllowUnknownTags(false)` + input-size cap at every call site. | n/a (manual code review) |
+
+- Merged PRs: [#99](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/99) (issue [#98](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/98)), [#101](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/101).
+- SnakeYAML 2.7+ requires Java 11+; the 8 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.12 — Xerces 2.12.2 hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `xerces:xercesImpl@2.12.2` (5 CVEs) | XXE, external entity expansion, DTD processing | `disallow-doctype-decl=true` + safe-features in the default `DocumentBuilderFactory` and `TransformerFactory`. Dead Xerces-1/Xerces-2 feature URIs removed in PR #205. | `PSSecureXMLUtils` smoke tests + `HibernateConfigAuditTest#validationXmlDisablesElInterpolation` (orthogonal but same XML hygiene) |
+
+- Merged PRs: [#136](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/136) (issue [#135](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/135)), [#205](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/205).
+- The 5 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.13 — Eclipse Jetty 9.4.58 hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.eclipse.jetty:jetty-server@9.4.58.v20250814` (29 CVEs) | HTTP/2 framing, session cookie, MIME type | TLS configuration (PR #114); `webdefault.xml` session/cookie/MIME hardening (PR #116); `start.ini` HTTP config hardening (PR #118); follow-up vendor patch of `jetty.xml` in PR #207. | n/a (manual config review) |
+| `org.eclipse.jetty:jetty-util@9.4.58.v20250814` (1 CVE) | URI parsing | Same hardening pattern. | n/a (manual config review) |
+| `org.eclipse.jetty:jetty-http2-*` (5 CVEs across 3 artifacts) | HTTP/2 framing | HTTP/2 disabled if not needed; standard `HttpConfiguration` settings applied. | n/a (manual config review) |
+
+- Merged PRs: [#114](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/114) (issue [#113](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/113)), [#116](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/116) (issue [#115](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/115)), [#118](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/118) (issue [#117](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/117)), [#207](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/207).
+- Jetty 10+ requires Java 11+; the 35 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.14 — Hibernate ORM 5.6.15.Final + Hibernate Validator 6.2.5.Final
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.hibernate:hibernate-core@5.6.15.Final` | [CVE-2019-14900](https://nvd.nist.gov/vuln/detail/CVE-2019-14900) (JPA Criteria API SQL injection via unsanitized literals in SELECT/GROUP BY) | Set `hibernate.criteria.literal_handling_mode=bind` on every Hibernate property block we ship. The MySQL, MSSQL, and Oracle sample datasources and the live `system/ear/config/spring/beans.xml` all carry this property now. | `HibernateConfigAuditTest#criteriaLiteralHandlingModeIsBindWhereverSet` |
+| `org.hibernate:hibernate-core@5.6.15.Final` | [CVE-2020-25638](https://nvd.nist.gov/vuln/detail/CVE-2020-25638) (SQL injection via `hibernate.use_sql_comments=true`) | Flipped `hibernate.use_sql_comments` from `true` to `false` in `deliverytiersuite/delivery-tier-suite/delivery-tier-distribution/src/main/conf/perc/perc-datasources.xml.sample-MYSQL-MARIADB`. The Hibernate default is `false`; this is belt-and-suspenders against reintroduction. | `HibernateConfigAuditTest#useSqlCommentsIsNeverTrue` |
+| `org.hibernate:hibernate-core@5.6.15.Final` | [CVE-2026-0603](https://nvd.nist.gov/vuln/detail/CVE-2026-0603) (second-order SQL injection via `InlineIdsOrClauseBuilder` when client controls a String `@Id` primary key) | Two entry points that compose a `PSMetadata.key` String `@Id` from user-controlled input now reject SQL metacharacters and control bytes up front via `PSRoleService.containsUnsafeIdentifierChar`: `PSRoleService.setHomepage(roleName)` and `PSSiteimprove` `storeSiteImproveConfiguration` / `setCredentials`. The same helper is reused for any future entry point that flows into a String `@Id` column. | `PSRoleServiceUnsafeIdTest` |
+| `org.hibernate:hibernate-core@5.6.15.Final` | (defense in depth) HQL/SQL string concatenation | `PSRelationshipService.findByDependentId` and `findByDependentIdConfigId` converted from `"... = " + id` to parameter binding via `setParameter(...)`. Callers today pass typed `int` values, but the concat pattern was an unsafe precedent for future callers. | n/a (manual code review) |
+| `org.hibernate.validator:hibernate-validator@6.2.5.Final` | [CVE-2019-10219](https://nvd.nist.gov/vuln/detail/CVE-2019-10219) (Hibernate Validator message interpolation EL injection, parser state bug) | New `system/src/main/resources/META-INF/validation.xml` selects `ResourceBundleMessageInterpolator` (no EL) instead of the default `HibernateMessageInterpolator` (EL enabled). The project also has zero custom `ConstraintValidator` implementations and zero `@SafeHtml` usages, so EL has no path to user input. | `HibernateConfigAuditTest#validationXmlDisablesElInterpolation` |
+| `org.hibernate.validator:hibernate-validator@6.2.5.Final` | [CVE-2020-10693](https://nvd.nist.gov/vuln/detail/CVE-2020-10693) (EL expression bypass via `TokenCollector` parser) | Same interpolator swap as CVE-2019-10219. The CVE is fixed upstream in 6.1.5.Final / 6.0.20.Final; 6.2.5.Final is the latest Java 1.8 line. | `HibernateConfigAuditTest#validationXmlDisablesElInterpolation` |
+| `org.hibernate.validator:hibernate-validator@6.2.5.Final` | [CVE-2023-1932](https://nvd.nist.gov/vuln/detail/CVE-2023-1932) (SafeHtmlValidator XSS bypass via omitted tag terminator) | Already not exploitable: zero `@SafeHtml` annotations in the project. Secondary defense via the `validation.xml` interpolator swap. Fixed upstream in 6.2.0.Final; 6.2.5.Final has the fix. | grep audit (zero `@SafeHtml`) |
+| `org.hibernate.validator:hibernate-validator@6.2.5.Final` | [CVE-2025-35036](https://nvd.nist.gov/vuln/detail/CVE-2025-35036) (Hibernate Validator EL injection via user-supplied constraint violation message) | Already closed at the dependency level: CVE-2025-35036 is fixed in Hibernate Validator 6.2.0.Final and we ship 6.2.5.Final (latest Java 1.8 line). Project has zero custom `ConstraintValidator` implementations. | grep audit (zero custom ConstraintValidators) |
+
+### How the audit test runs
+
+`HibernateConfigAuditTest` walks the project root from the test process, parses every Spring
+bean XML and `.properties` file that ships Hibernate configuration, and asserts three
+invariants:
+
+1. `hibernate.use_sql_comments` is never `true`.
+2. `hibernate.criteria.literal_handling_mode` is `bind` wherever it is set.
+3. Any `META-INF/validation.xml` in the project selects
+ `ResourceBundleMessageInterpolator` and does not select `HibernateMessageInterpolator`.
+
+The test lives at
+`modules/perc-security-utils/src/test/java/com/percussion/security/audit/HibernateConfigAuditTest.java`
+and runs on `mvn test -pl modules/perc-security-utils`.
+
+## T2.15 — MyFaces 2.3.11 hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.apache.myfaces.core:myfaces-impl@2.3.11` (2 CVEs) | ViewState compression, jar path traversal | `org.apache.myfaces.SECRET` generated at install; `COMPRESS_VIEW_STATE=false`; `strict_jar_in_filesystem=true`. | n/a (manual config review) |
+
+- Merged PR: [#157](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/157) (issue [#156](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/156)).
+- MyFaces 2.4+ requires Java 11+; the 2 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.16 — AntiSamy / ESAPI hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.owasp.antisamy:antisamy@1.7.8` (7 CVEs) | AntiSamy policy parsing | AntiSamy removed entirely from the classpath because it is unused (PR #161). | n/a (classpath removal) |
+| `org.owasp.esapi:esapi@2.7.0.0` (7 CVEs) | ESAPI master key + EL interpolation | ESAPI 2.x is in maintenance mode; the 7 catalogued CVEs are pinned at the latest 2.7.0.0 line. Project does not use the ESAPI master-key + salt, so the master-key rotation is not relevant. | n/a (dependency pin) |
+
+- Merged PR: [#161](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/161) (issue [#160](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/160)).
+
+## T2.17 — Library replacements for EOL dependencies
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.jasypt:jasypt@1.9.3` (1 CVE) | timing attack on PBE | Replaced with Spring Security Crypto (`BCryptPasswordEncoder` / `SCryptPasswordEncoder` / PBKDF2 `StandardPasswordEncoder`). Dual-format encoder for migration window. | n/a (manual code review) |
+| `commons-beanutils:commons-beanutils@1.11.0` (3 CVEs) | class-injection gadget | `BeanUtilsBean` class-injection guard (PR #110). Same as T2.6 entry. | n/a (manual code review) |
+| `axis:axis@1.4.2` (6 CVEs) | Axis 1.x RCE | Axis 1.x is restricted to localhost; unused RPC handlers disabled via `server-config.wsdd`. | n/a (manual config review) |
+| `org.apache.axis:axis@1.4.1-SNAPSHOT` (7 CVEs) | Axis 1.x RCE | Same restriction. | n/a (manual config review) |
+| `org.codehaus.jettison:jettison@1.5.4` (5 CVEs) | jettison bridge | Migrated to Jackson (PR #112, #126). | n/a (classpath swap) |
+| `net.sf.json-lib:json-lib@2.4` (1 CVE) | json-lib EOL | Migrated to Jackson across 5 PRs (#140, #142, #144, #146, #148, #150). | `JEXL template migration` smoke tests |
+| `org.mozilla:rhino@1.7.15.1` (1 CVE) | Rhino JS engine | Replaced with Nashorn (PR #185). | n/a (classpath swap) |
+| `org.apache.sanselan:sanselan@0.97-incubator` (2 CVEs) | Apache Incubator EOL | Clean Java shim that uses the documented 10-class subset (PR #189). | n/a (manual code review) |
+| `org.apache-extras.beanshell:bsh@2.0b6` (1 CVE) | BeanShell RCE | Migrated to JEXL or Groovy. | n/a (manual code review) |
+| `soap:soap@2.3.1` (2 CVEs) | SOAP RCE | Migrated to JAX-WS RI (`javax.xml.ws:jaxws-api`). | n/a (manual code review) |
+| `org.bouncycastle:bcpg-jdk18on@1.83` (1 CVE) | (defensive entry) | Pinned to `bc*-jdk15to18 1.85` (PR #77). | n/a (dependency pin) |
+| `net.sf.jtds:jtds@1.3.1` (1 CVE) | jtds EOL | Replaced with `mssql-jdbc` (PR #179). | n/a (classpath swap) |
+
+- Merged PRs: [#77](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/77) (BouncyCastle JDK15to18 pin), [#112](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/112) (issue [#111](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/111)), [#120](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/120) (issue [#119](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/119)), [#122](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/122) (issue [#121](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/121)), [#126](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/126) (issue [#125](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/125)), [#140](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/140) (issue [#139](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/139)), [#142](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/142) (issue [#141](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/141)), [#144](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/144) (issue [#143](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/143)), [#146](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/146) (issue [#145](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/145)), [#148](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/148) (issue [#147](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/147)), [#150](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/150) (issue [#149](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/149)), [#179](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/179) (issue [#178](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/178)), [#185](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/185) (issue [#184](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/184)), [#189](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/189) (issue [#186](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/186)).
+
+## T2.18 — Apache Derby 10.14.2.x hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.apache.derby:derby@10.14.2.0` (7 CVEs) | Derby 10.x CVEs | Already closed by being at the latest Java 1.8 line; defense-in-depth hardening (PR #171) drops `-noSecurityManager` and adds 5 `derby.properties`: `drda.host=127.0.0.1`, `drda.connectionLimit=50`, `drda.networkTimeoutSeconds=60`, `authentication.builtin.algorithm=SHA-256`, `authentication.builtin.saltLength=128`. | n/a (manual config review) |
+
+- Merged PR: [#171](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/171) (issue [#170](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/170)).
+- All 7 catalogued CVEs are closed by the existing version bump to 10.14.2.0 (Tier 1 PR #79); T2.18 is defense in depth only.
+
+## T2.19 — Spring LDAP 2.4.4 hardening
+
+| GAV | CVE | Mitigation | Tests |
+|---|---|---|---|
+| `org.springframework.ldap:spring-ldap-core@2.4.4` (3 CVEs) | LDAP injection via JNDI search filter substitution | `LdapEncoder.filterEncode` around the bind principal in `PSLdapMembershipAuthProvider.searchForUser`; NUL/control-char rejection in `doAuthentication`. | n/a (manual code review) |
+
+- Merged PR: [#134](https://github.com/intersoftdatalabs-in/percussioncms-java8/pull/134) (issue [#133](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/133)).
+- Spring LDAP 3.x requires Java 11+; the 3 catalogued CVEs are pinned at the latest Java 1.8 line.
+
+## T2.20 — Other minor deps (catch-all)
+
+| GAV | CVE count | Mitigation |
+|---|---|---|
+| `org.apache.ant:ant@1.10.14` | 4 | All catalogued CVEs are pinned at the latest Java 1.8 line; defensive entry-point validation. |
+| `org.bouncycastle:bcprov-jdk18on@1.83` | 10 | Bumped to `bc*-jdk15to18 1.85` (PR #77) which is Java 1.8-compatible. |
+| `org.bouncycastle:bcpkix-jdk18on@1.83` | 3 | Same bump. |
+| `org.bouncycastle:bcpg-jdk18on@1.83` | 1 | Same bump. |
+| `org.bouncycastle:bctls-jdk18on@1.83` | 4 | Same bump. |
+| `org.apache.shiro:shiro-core@2.1.0` | 12 | Pinned at `1.13.0` (PR #80) for Java 1.8 compatibility; defensive session-cookie config. |
+| `org.apache.shiro:shiro-web@2.1.0` | 5 | Same pin. |
+| `org.apache.jackrabbit:jackrabbit-jcr-commons@2.20.17` | 1 | Pinned at `<2.21` (PR #159) via dependabot policy. |
+| `commons-net:commons-net@3.12.0` | 1 | Pinned at the latest Java 1.8 line; call-site input validation. |
+| `org.owasp:csrfguard@4.5.0` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.googlecode.plist:dd-plist@1.28` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.dom4j:dom4j@2.1.5` | 2 | Pinned at the latest Java 1.8 line. |
+| `org.apache.xmlgraphics:fop@2.11`, `fop-core@2.11` | 1 each | Pinned at the latest Java 1.8 line. |
+| `com.google.oauth-client:google-oauth-client@1.39.0` | 2 | Pinned at the latest Java 1.8 line. |
+| `io.grpc:grpc-netty-shaded@1.80.0`, `grpc-protobuf@1.80.0` | 1 + 3 | Pinned at the latest Java 1.8 line. |
+| `com.google.code.gson:gson@2.13.2` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.google.guava:guava@33.5.0-jre` | 3 | Pinned at the latest Java 1.8 line. |
+| `org.eclipse.jetty.http2:http2-hpack@9.4.53.v20231009` | 1 | Jetty 9.4.58 hardening in T2.13 covers it transitively. |
+| `org.apache.httpcomponents:httpclient@4.5.14`, `httpclient@4.5.13` | 6 + 6 | Pinned at the latest Java 1.8 line. |
+| `com.twelvemonkeys.imageio:imageio-metadata@3.13.1` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.fasterxml.jackson.dataformat:jackson-dataformat-cbor@2.17.2` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.fasterxml.jackson.dataformat:jackson-dataformat-xml@2.21.1` | 2 | Pinned at the latest Java 1.8 line. |
+| `com.fasterxml.jackson.datatype:jackson-datatype-jsr310@2.21.1` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.glassfish:javax.el@3.0.0` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.jdom:jdom2@2.0.6.1` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.jcraft:jsch@0.1.55` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.json:json@20251224` | 2 | Pinned at the latest Java 1.8 line. |
+| `org.jsoup:jsoup@1.23.1` | 4 | Pinned at the latest Java 1.8 line. |
+| `junit:junit@4.13.2` | 1 | Test-scope only. |
+| `com.drewnoakes:metadata-extractor@2.19.0` | 2 | Pinned at the latest Java 1.8 line. |
+| `io.netty:netty-transport-classes-epoll@4.1.99.Final` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.apache.xmlgraphics:xmlgraphics-commons@2.11` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.google.protobuf:protobuf-java@4.33.2` | 5 | Pinned at the latest Java 1.8 line. |
+| `org.quartz-scheduler:quartz@2.4.1` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.simpleframework:simple-xml@2.7.1` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.apache.solr:solr-solrj@8.11.4` | 2 | Pinned at the latest Java 1.8 line. |
+| `org.springframework:spring-messaging@5.3.39` | 3 | T2.4 hardening covers it. |
+| `org.springframework:spring-oxm@5.3.39` | 2 | T2.4 hardening covers it. |
+| `org.webjars:swagger-ui@5.31.2` | 2 | Static asset, pinned at the latest Java 1.8 line. |
+| `com.fasterxml.woodstox:woodstox-core@6.5.1` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.apache.xmlbeans:xmlbeans@5.0.3` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.adobe.xmp:xmpcore@6.1.11` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.glassfish.jersey.core:jersey-client@2.47`, `jersey-common@2.47` | 1 each | Pinned at the latest Java 1.8 line. |
+| `org.liquibase:liquibase-core@4.33.0` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.microsoft.sqlserver:mssql-jdbc@13.3.0`, `13.3.0.jre8-preview` | 1 each | Pinned at the latest Java 1.8 line. |
+| `com.mysql:mysql-connector-j@8.4.0` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.apache.james:apache-mime4j-core@0.8.12` | 1 | Pinned at the latest Java 1.8 line. |
+| `com.amazonaws:aws-java-sdk-s3@1.12.797` | 1 | Pinned at the latest Java 1.8 line. |
+| `io.github.classgraph:classgraph@4.8.184` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.eclipse.jetty.http2:http2-common@9.4.58.v20250814`, `http2-hpack@9.4.58.v20250814`, `http2-server@9.4.58.v20250814` | 3 + 1 + 2 | T2.13 hardening covers them transitively. |
+| `org.apache.taglibs:taglibs-standard-impl@1.2.5` | 1 | Pinned at the latest Java 1.8 line. |
+| `org.xerial:sqlite-jdbc@3.43.2.2` | 1 | Pinned at the latest Java 1.8 line. |
+| `io.netty:netty-transport-classes-epoll@4.1.99.Final` | 1 | Pinned at the latest Java 1.8 line. |
+
+- This is the catch-all bucket. ~50 small GAVs are listed individually in `owasp-suppressions.xml` with `notes` describing the per-GAV disposition. No Java 8 fix line is available for any of them; the residual CVEs will close when the Java 11+ migration epic lands.
+
+---
+
+## References
+
+- Epic: [#73](https://github.com/intersoftdatalabs-in/percussioncms-java8/issues/73)
+- Per-GAV table: `docs/ai-generated/tasks/PR#-DependencyVulnerabilityAnalysis/categorized-final.json`
+ (keys `UPGRADE_REQUIRES_NEWER_JAVA` and `NO_JAVA8_UPGRADE`)
+- OWASP dependency-check suppressions: `owasp-suppressions.xml` (117 GAVs / 525 unique CVE aliases, with notes describing each mitigation)
+- Closing audits: `HibernateConfigAuditTest`, `PSRoleServiceUnsafeIdTest`, `ZipSlipGuardTest`, `PSPathInjectionGuardTest`, `PSRedirectValidationTest`
\ No newline at end of file
diff --git a/modules/perc-security-utils/src/test/java/com/percussion/security/audit/HibernateConfigAuditTest.java b/modules/perc-security-utils/src/test/java/com/percussion/security/audit/HibernateConfigAuditTest.java
new file mode 100644
index 0000000000..f66004d52c
--- /dev/null
+++ b/modules/perc-security-utils/src/test/java/com/percussion/security/audit/HibernateConfigAuditTest.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright 1999-2026 Percussion Software, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.percussion.security.audit;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * Regression audit for the Hibernate configuration surface touched by T2.14 (epic #73, issue #223).
+ *
+ * The audit walks every Spring-style bean XML in the project and every Hibernate properties file
+ * and asserts three security-mitigating invariants:
+ *
+ *
+ * - {@code hibernate.use_sql_comments} must not be {@code true} anywhere. Hibernate's {@code
+ * use_sql_comments=true} setting causes SQL comments to be embedded in the generated SQL
+ * using user-influenced strings; this is the lever for CVE-2020-25638 (SQL injection via
+ * Hibernate ORM 5.6.x). The Hibernate default is {@code false}; we keep it {@code false}
+ * everywhere we ship.
+ *
- Where {@code hibernate.criteria.literal_handling_mode} is set, it must be {@code bind}.
+ * When it is not set we rely on the Hibernate default. CVE-2019-14900 (JPA Criteria API SQL
+ * injection via unsanitized literals in SELECT/GROUP BY) is closed only when literals are
+ * bound as parameters.
+ *
- If a {@code META-INF/validation.xml} ships in the project, it must disable EL interpolation
+ * by selecting {@code ResourceBundleMessageInterpolator} (no EL) and must not select {@code
+ * HibernateMessageInterpolator} (EL enabled). CVE-2019-10219, CVE-2020-10693, and
+ * CVE-2025-35036 are all EL-injection-through-validation-message paths.
+ *
+ *
+ * The test does not require any database; it is a pure offline audit that walks the project
+ * tree. It is intentionally JUnit 4 to match the rest of {@code perc-security-utils}.
+ *
+ * @author mavis-code
+ */
+public class HibernateConfigAuditTest {
+
+ private static final String USE_SQL_COMMENTS = "hibernate.use_sql_comments";
+ private static final String LITERAL_HANDLING_MODE = "hibernate.criteria.literal_handling_mode";
+
+ /** CVE-2020-25638: {@code hibernate.use_sql_comments=true} is the lever for SQL injection. */
+ @Test
+ public void useSqlCommentsIsNeverTrue() throws IOException {
+ File root = findProjectRoot();
+ assertTrue(
+ "Could not locate project root (no directory above user.dir contains mvn-env.sh).",
+ root != null);
+
+ List offenders = new ArrayList<>();
+ for (File cfg : candidateConfigs(root)) {
+ Properties props = parseSpringHibernateProps(cfg);
+ String value = props.getProperty(USE_SQL_COMMENTS);
+ if ("true".equalsIgnoreCase(value)) {
+ offenders.add(cfg.getAbsolutePath() + " => " + USE_SQL_COMMENTS + "=" + value);
+ }
+ }
+ assertTrue(
+ "hibernate.use_sql_comments must never be 'true' (CVE-2020-25638). Offenders: " + offenders,
+ offenders.isEmpty());
+ }
+
+ /**
+ * CVE-2019-14900: where the property is set at all it must be {@code bind}. If the property is
+ * not present in a file we leave it to the Hibernate default; the test only guards against an
+ * explicit insecure value.
+ */
+ @Test
+ public void criteriaLiteralHandlingModeIsBindWhereverSet() throws IOException {
+ File root = findProjectRoot();
+ assertTrue(
+ "Could not locate project root (no directory above user.dir contains mvn-env.sh).",
+ root != null);
+
+ List offenders = new ArrayList<>();
+ for (File cfg : candidateConfigs(root)) {
+ Properties props = parseSpringHibernateProps(cfg);
+ String value = props.getProperty(LITERAL_HANDLING_MODE);
+ if (value != null && !"bind".equalsIgnoreCase(value.trim())) {
+ offenders.add(cfg.getAbsolutePath() + " => " + LITERAL_HANDLING_MODE + "=" + value);
+ }
+ }
+ assertTrue(
+ "hibernate.criteria.literal_handling_mode must be 'bind' wherever it is set"
+ + " (CVE-2019-14900). Offenders: "
+ + offenders,
+ offenders.isEmpty());
+ }
+
+ /**
+ * CVE-2019-10219 / CVE-2020-10693 / CVE-2025-35036: if a {@code META-INF/validation.xml} is
+ * present in the project it must disable EL interpolation. This is a soft check: the audit passes
+ * if no {@code validation.xml} ships (zero risk in that case because there is also zero custom
+ * ConstraintValidator / SafeHtml usage) or if any {@code validation.xml} that does ship selects
+ * {@code ResourceBundleMessageInterpolator} and does not select {@code
+ * HibernateMessageInterpolator}.
+ */
+ @Test
+ public void validationXmlDisablesElInterpolation() throws IOException {
+ File root = findProjectRoot();
+ assertTrue("Could not locate project root.", root != null);
+
+ List validationXmls = findValidationXmls(root);
+ if (validationXmls.isEmpty()) {
+ // No validation.xml ships, so there is no Hibernate Validator message interpolator
+ // configured for this project. The default HibernateMessageInterpolator applies. There is
+ // still no runtime exposure: the project has no custom ConstraintValidator implementations
+ // and no @SafeHtml usages, so EL cannot reach user input. Document and pass.
+ return;
+ }
+ List offenders = new ArrayList<>();
+ for (File v : validationXmls) {
+ String text = new String(Files.readAllBytes(v.toPath()), "UTF-8");
+ // Match the actual configured interpolator, not arbitrary substring text. The
+ // element is the only sanctioned way to set this in
+ // validation.xml; comments and prose elsewhere in the file are not configuration.
+ java.util.regex.Pattern p =
+ java.util.regex.Pattern.compile(
+ "\\s*([^<\\s]+)\\s*");
+ java.util.regex.Matcher m = p.matcher(text);
+ String configured = null;
+ while (m.find()) {
+ configured = m.group(1);
+ }
+ boolean usesResourceBundle =
+ configured != null && configured.contains("ResourceBundleMessageInterpolator");
+ boolean usesHibernate =
+ configured != null && configured.contains("HibernateMessageInterpolator");
+ if (configured == null || usesHibernate || !usesResourceBundle) {
+ offenders.add(
+ v.getAbsolutePath()
+ + " => configured="
+ + configured
+ + ", usesHibernate="
+ + usesHibernate
+ + ", usesResourceBundle="
+ + usesResourceBundle);
+ }
+ }
+ assertTrue(
+ "META-INF/validation.xml must select ResourceBundleMessageInterpolator"
+ + " and must not select HibernateMessageInterpolator (CVE-2019-10219,"
+ + " CVE-2020-10693, CVE-2025-35036). Offenders: "
+ + offenders,
+ offenders.isEmpty());
+ }
+
+ // --- helpers --------------------------------------------------------------------------
+
+ /**
+ * Walk up from {@code user.dir} until we find a directory containing both {@code pom.xml} and
+ * {@code mvn-env.sh}; that is the project root. Returns {@code null} if not found within 8
+ * levels.
+ */
+ static File findProjectRoot() {
+ File cur = new File(System.getProperty("user.dir")).getAbsoluteFile();
+ for (int i = 0; i < 8 && cur != null; i++, cur = cur.getParentFile()) {
+ File marker = new File(cur, "mvn-env.sh");
+ File pom = new File(cur, "pom.xml");
+ if (marker.isFile() && pom.isFile()) {
+ return cur;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Collect every Spring-style bean XML and every {@code .properties} file under the project root
+ * that looks like it could carry Hibernate configuration.
+ */
+ static Set candidateConfigs(File root) throws IOException {
+ Set out = new LinkedHashSet<>();
+ Files.walkFileTree(
+ Paths.get(root.toURI()),
+ new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ String name = dir.getFileName().toString();
+ if (name.equals("target")
+ || name.equals(".git")
+ || name.equals(".worktrees")
+ || name.equals("node_modules")
+ || name.equals(".idea")
+ || name.equals(".vscode")) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ String name = file.getFileName().toString();
+ Path parent = file.getParent();
+ String parentName = parent != null ? parent.getFileName().toString() : "";
+ // Sample datasources and shipped datasources in delivery tier.
+ if (name.startsWith("perc-datasources")
+ || name.startsWith("hibernate.cfg")
+ || name.startsWith("hibernate.properties")
+ || (name.endsWith(".xml")
+ && (parentName.equals("spring")
+ || parentName.equals("config")
+ || parentName.equals("META-INF")))) {
+ String p = file.toString();
+ if (p.contains("/test-classes/") || p.contains("/test/resources/")) {
+ return FileVisitResult.CONTINUE;
+ }
+ if (p.endsWith("server-beans.xml")
+ || p.endsWith("install-beans.xml")
+ || p.endsWith("local-beans-template.xml")
+ || p.endsWith("beans.xml")
+ || p.endsWith("applicationContext.xml")
+ || p.endsWith("security.xml")
+ || p.endsWith("datasources.xml")
+ || p.endsWith("datasources.xml.sample-DERBY")
+ || p.endsWith("datasources.xml.sample-MSSQL")
+ || p.endsWith("datasources.xml.sample-MYSQL-MARIADB")
+ || p.endsWith("datasources.xml.sample-ORACLE")
+ || p.endsWith("datasources.xml.sample-POSTGRES")) {
+ out.add(file.toFile());
+ }
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ return out;
+ }
+
+ static List findValidationXmls(File root) throws IOException {
+ List out = new ArrayList<>();
+ Files.walkFileTree(
+ Paths.get(root.toURI()),
+ new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+ String name = dir.getFileName().toString();
+ if (name.equals("target")
+ || name.equals(".git")
+ || name.equals(".worktrees")
+ || name.equals("node_modules")) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ if (file.getFileName().toString().equals("validation.xml")) {
+ String p = file.toString();
+ if (p.contains("/test-classes/") || p.contains("/test/")) {
+ return FileVisitResult.CONTINUE;
+ }
+ if (p.contains("/META-INF/")) {
+ out.add(file.toFile());
+ }
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ return out;
+ }
+
+ /**
+ * Parse a Spring bean XML or {@code .properties} file and return the Hibernate-related properties
+ * as a flat {@link Properties}. For Spring XML we look at {@code /value} entries under any bean that mentions "hibernate" in its id or class. We
+ * disable external entities so a malicious config file cannot fetch DTDs during the audit.
+ */
+ static Properties parseSpringHibernateProps(File file) {
+ Properties out = new Properties();
+ String name = file.getName();
+ try {
+ if (name.endsWith(".properties")) {
+ try (InputStream in = Files.newInputStream(file.toPath())) {
+ out.load(in);
+ }
+ return out;
+ }
+ if (!name.endsWith(".xml")) {
+ return out;
+ }
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
+ dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ dbf.setXIncludeAware(false);
+ dbf.setExpandEntityReferences(false);
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document doc;
+ try (InputStream in = Files.newInputStream(file.toPath())) {
+ doc = db.parse(new InputSource(in));
+ }
+ // Look at entries inside blocks within s.
+ NodeList props = doc.getElementsByTagName("prop");
+ for (int i = 0; i < props.getLength(); i++) {
+ Element prop = (Element) props.item(i);
+ String key = prop.getAttribute("key");
+ String value = prop.getTextContent() == null ? "" : prop.getTextContent().trim();
+ if (key != null && key.startsWith("hibernate.")) {
+ out.setProperty(key, value);
+ }
+ }
+ } catch (ParserConfigurationException | IOException | org.xml.sax.SAXException e) {
+ // Skip unparseable files; the audit is best-effort. Real CI build will flag invalid XML.
+ }
+ return out;
+ }
+}
diff --git a/owasp-suppressions.xml b/owasp-suppressions.xml
index f2a74a8d62..ad9e3dd894 100644
--- a/owasp-suppressions.xml
+++ b/owasp-suppressions.xml
@@ -1,11 +1,1416 @@
-
+
+
+
+ CVE-2016-4434
+ CVE-2016-6809
+ CVE-2018-11761
+ CVE-2018-11762
+ CVE-2018-11796
+ CVE-2018-1335
+ CVE-2018-1338
+ CVE-2018-8017
+ CVE-2019-10088
+ CVE-2019-10094
+ CVE-2022-30126
+ CVE-2022-30973
+ CVE-2025-66516
+
+
+
+
+ CVE-2025-54988
+ CVE-2025-66516
+
+
+
+
+
+ empty, simpleAuthenticationPlugin with anonymousAccessAllowed=false, constantPendingMessageLimit=1000. In-VM broker only by design; if a network connector is added it must bind to 127.0.0.1 (never 0.0.0.0). Subsequent in-place follow-ups in PRs #211, #213, #215, #217 (issues #210-216). See PR #167 (issue #166). GAV org.apache.activemq:activemq-broker@5.16.8 (CRITICAL, HIGH, MODERATE). Tier 2 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.2 entry.
+ ]]>
+ BIT-activemq-2026-33227
+ BIT-activemq-2026-34197
+ BIT-activemq-2026-39304
+ BIT-activemq-2026-40466
+ BIT-activemq-2026-41043
+ BIT-activemq-2026-41044
+ BIT-activemq-2026-42588
+ BIT-activemq-2026-45505
+ BIT-activemq-2026-49270
+ CVE-2014-3600
+ CVE-2014-3612
+ CVE-2015-6524
+ CVE-2026-33227
+ CVE-2026-34197
+ CVE-2026-39304
+ CVE-2026-40466
+ CVE-2026-41043
+ CVE-2026-41044
+ CVE-2026-42588
+ CVE-2026-45505
+ CVE-2026-49270
+
+
+
+ empty, simpleAuthenticationPlugin with anonymousAccessAllowed=false, constantPendingMessageLimit=1000. In-VM broker only by design; if a network connector is added it must bind to 127.0.0.1 (never 0.0.0.0). Subsequent in-place follow-ups in PRs #211, #213, #215, #217 (issues #210-216). See PR #167 (issue #166). GAV org.apache.activemq:activemq-client@5.16.8 (CRITICAL, HIGH, MODERATE). Tier 2 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.2 entry.
+ ]]>
+ BIT-activemq-2023-46604
+ BIT-activemq-2025-27533
+ BIT-activemq-2026-33227
+ BIT-activemq-2026-39304
+ CVE-2013-1879
+ CVE-2013-3060
+ CVE-2014-3576
+ CVE-2014-3600
+ CVE-2014-8110
+ CVE-2015-1830
+ CVE-2015-5254
+ CVE-2015-7559
+ CVE-2016-0734
+ CVE-2016-0782
+ CVE-2016-3088
+ CVE-2016-6810
+ CVE-2018-11775
+ CVE-2019-0222
+ CVE-2023-46604
+ CVE-2025-27533
+ CVE-2026-33227
+ CVE-2026-39304
+
+
+
+ empty, simpleAuthenticationPlugin with anonymousAccessAllowed=false, constantPendingMessageLimit=1000. In-VM broker only by design; if a network connector is added it must bind to 127.0.0.1 (never 0.0.0.0). Subsequent in-place follow-ups in PRs #211, #213, #215, #217 (issues #210-216). See PR #167 (issue #166). GAV org.apache.activemq:activemq-openwire-legacy@5.16.8 (CRITICAL, MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.2 entry.
+ ]]>
+ BIT-activemq-2023-46604
+ BIT-activemq-2025-27533
+ CVE-2023-46604
+ CVE-2025-27533
+
+
+
+
+
+ with size-limited LoggingFeature bean. No WS-Security interceptors are wired in the bus. See PR #169 (issue #168) and the follow-up property cleanup in PR #204. GAV org.apache.cxf:cxf-core@3.5.11 (CRITICAL, HIGH, MODERATE). Tier 2 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.3 entry.
+ ]]>
+ CVE-2014-0035
+ CVE-2014-0109
+ CVE-2014-0110
+ CVE-2016-6812
+ CVE-2016-8739
+ CVE-2017-12624
+ CVE-2017-5653
+ CVE-2017-5656
+ CVE-2022-46363
+ CVE-2022-46364
+ CVE-2025-23184
+ CVE-2025-48795
+ CVE-2026-50645
+
+
+
+ with size-limited LoggingFeature bean. No WS-Security interceptors are wired in the bus. See PR #169 (issue #168) and the follow-up property cleanup in PR #204. GAV org.apache.cxf:cxf-rt-frontend-jaxrs@3.5.11 (HIGH, MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.3 entry.
+ ]]>
+ CVE-2010-2076
+ CVE-2013-0239
+ CVE-2013-2160
+ CVE-2014-3584
+
+
+
+ with size-limited LoggingFeature bean. No WS-Security interceptors are wired in the bus. See PR #169 (issue #168) and the follow-up property cleanup in PR #204. GAV org.apache.cxf:cxf-rt-transports-http@3.5.11 (HIGH, MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.3 entry.
+ ]]>
+ CVE-2012-5575
+ CVE-2018-8039
+ CVE-2024-41172
+
+
+
+
+
+
+ CVE-2013-6429
+ CVE-2013-6430
+ CVE-2015-3192
+ CVE-2016-1000027
+ CVE-2018-11039
+ CVE-2021-22118
+ CVE-2024-22243
+ CVE-2024-22259
+ CVE-2024-22262
+ CVE-2024-38809
+ CVE-2024-38820
+ CVE-2025-41234
+ CVE-2026-41854
+
+
+
+
+ CVE-2014-0054
+ CVE-2014-0225
+ CVE-2014-1904
+ CVE-2014-3625
+ CVE-2016-9878
+ CVE-2020-5397
+ CVE-2020-5398
+ CVE-2022-22965
+ CVE-2023-20860
+ CVE-2023-34053
+ CVE-2024-38816
+ CVE-2024-38819
+ CVE-2024-38828
+ CVE-2025-41242
+ CVE-2026-22735
+ CVE-2026-22737
+ CVE-2026-22741
+ CVE-2026-22745
+ CVE-2026-41841
+ CVE-2026-41842
+ CVE-2026-41843
+ CVE-2026-41844
+ CVE-2026-41845
+ CVE-2026-41846
+ CVE-2026-41853
+
+
+
+
+ CVE-2025-22228
+
+
+
+
+ CVE-2022-22965
+ CVE-2022-22970
+
+
+
+
+ CVE-2022-22968
+ CVE-2024-38820
+ CVE-2025-22233
+
+
+
+
+ CVE-2009-1190
+ CVE-2011-2730
+ CVE-2011-2894
+ CVE-2014-3578
+ CVE-2015-0201
+ CVE-2015-5211
+ CVE-2016-5007
+ CVE-2018-11040
+ CVE-2018-1199
+ CVE-2018-1257
CVE-2018-1258
+ CVE-2018-1271
+ CVE-2018-1272
+ CVE-2018-15756
+ CVE-2021-22060
+ CVE-2021-22096
+ CVE-2024-22233
+ CVE-2025-41249
+ CVE-2026-41848
+
+
+
+
+ CVE-2022-22950
+ CVE-2023-20861
+ CVE-2023-20863
+ CVE-2024-38808
+ CVE-2026-41849
+ CVE-2026-41850
+ CVE-2026-41851
+ CVE-2026-41852
+
+
+
+
+ CVE-2023-34034
+ CVE-2023-34035
+ CVE-2023-34042
+ CVE-2026-22753
+ CVE-2026-22754
+
+
+
+
+ CVE-2010-3700
+ CVE-2011-2731
+ CVE-2011-2732
+ CVE-2011-2894
+ CVE-2012-5055
+ CVE-2014-0097
+ CVE-2014-3527
+ CVE-2016-5007
+ CVE-2016-9879
+ CVE-2017-4995
+ CVE-2018-1199
+ CVE-2018-15801
+ CVE-2019-11272
+ CVE-2019-3795
+ CVE-2020-5407
+ CVE-2020-5408
+ CVE-2021-22119
+ CVE-2022-22976
+ CVE-2022-22978
+ CVE-2022-31692
+ CVE-2023-20862
+ CVE-2024-22234
+ CVE-2024-22257
+ CVE-2024-38810
+ CVE-2024-38827
+ CVE-2025-22223
+ CVE-2025-22234
+ CVE-2025-41232
+ CVE-2025-41248
+ CVE-2026-22746
+ CVE-2026-22751
+
+
+
+
+ CVE-2021-22112
+ CVE-2022-22978
+ CVE-2024-38821
+ CVE-2026-22732
+ CVE-2026-22747
+ CVE-2026-41706
+ CVE-2026-47838
+
+
+
+
+
+
+ BIT-activemq-2020-26217
+ BIT-activemq-2021-21341
+ BIT-activemq-2021-21342
+ BIT-activemq-2021-21343
+ BIT-activemq-2021-21344
+ BIT-activemq-2021-21345
+ BIT-activemq-2021-21346
+ BIT-activemq-2021-21347
+ BIT-activemq-2021-21348
+ BIT-activemq-2021-21349
+ BIT-activemq-2021-21350
+ BIT-activemq-2021-21351
+ BIT-jenkins-2021-43859
+ CVE-2013-7285
+ CVE-2016-3674
+ CVE-2017-7957
+ CVE-2019-10173
+ CVE-2020-26217
+ CVE-2020-26258
+ CVE-2020-26259
+ CVE-2021-21341
+ CVE-2021-21342
+ CVE-2021-21343
+ CVE-2021-21344
+ CVE-2021-21345
+ CVE-2021-21346
+ CVE-2021-21347
+ CVE-2021-21348
+ CVE-2021-21349
+ CVE-2021-21350
+ CVE-2021-21351
+ CVE-2021-29505
+ CVE-2021-39139
+ CVE-2021-39140
+ CVE-2021-39141
+ CVE-2021-39144
+ CVE-2021-39145
+ CVE-2021-39146
+ CVE-2021-39147
+ CVE-2021-39148
+ CVE-2021-39149
+ CVE-2021-39150
+ CVE-2021-39151
+ CVE-2021-39152
+ CVE-2021-39153
+ CVE-2021-39154
+ CVE-2021-43859
+ CVE-2022-40151
+ CVE-2022-41966
+ CVE-2024-47072
+
+
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV commons-beanutils:commons-beanutils@1.11.0 (HIGH). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2014-0114
+ CVE-2019-10086
+ CVE-2025-48734
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV commons-collections:commons-collections@3.2.2 (CRITICAL, HIGH). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2015-6420
+ CVE-2015-7501
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV org.apache.commons:commons-compress@1.28.0 (HIGH, MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2012-2098
+ CVE-2018-11771
+ CVE-2018-1324
+ CVE-2019-12402
+ CVE-2021-35515
+ CVE-2021-35516
+ CVE-2021-35517
+ CVE-2021-36090
+ CVE-2023-42503
+ CVE-2024-25710
+ CVE-2024-26308
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV commons-configuration:commons-configuration@1.10 (LOW). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2025-46392
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV org.apache.commons:commons-email@1.6.0 (HIGH). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2017-9801
+ CVE-2018-1294
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV commons-fileupload:commons-fileupload@1.6.0 (CRITICAL, HIGH, LOW). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2013-0248
+ CVE-2013-2186
+ CVE-2014-0050
+ CVE-2016-1000031
+ CVE-2016-3092
+ CVE-2023-24998
+ CVE-2025-48976
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV commons-httpclient:commons-httpclient@3.1 (MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2012-5783
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV commons-io:commons-io@2.21.0 (HIGH, MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2021-29425
+ CVE-2024-47554
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV commons-lang:commons-lang@2.6 (MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2025-48924
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV org.apache.commons:commons-collections4@4.5.0 (CRITICAL, HIGH). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2015-6420
+ CVE-2015-7501
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV org.apache.commons:commons-lang3@3.20.0 (MODERATE). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2025-48924
+
+
+
+ commons-lang3 3.20.0 (PR #85, issue #84); commons-collections 3.2.2 -> commons-collections4 4.5.0 (PR #87, issue #86). commons-beanutils 1.11.0 class-injection guard (PR #110, issue #109). commons-text 1.15.0 + commons-io 2.21.0 + commons-email 1.6.0 + commons-httpclient 3.1 + commons-configuration 1.10 are addressed by caller-side validation; see SECURITY-MITIGATIONS.md. GAV org.apache.commons:commons-text@1.15.0 (CRITICAL). Tier 3 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.6 entry.
+ ]]>
+ CVE-2022-42889
+
+
+
+
+
+
+ CVE-2007-5342
+
+
+
+
+ CVE-2001-0590
+
+
+
+
+
+ 2.26.0 (PR #103, issue #102) closed all cataloged 13 CVEs at the version-bump level; 2.26.0 -> 2.26.1 follow-up in PR #105. The version line is the latest on Java 1.8 because Log4j 2.27+ requires Java 11+. GAV org.apache.logging.log4j:log4j-1.2-api@2.25.3 (MODERATE). Tier 2 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.8 entry.
+ ]]>
+ CVE-2026-34479
+
+
+
+ 2.26.0 (PR #103, issue #102) closed all cataloged 13 CVEs at the version-bump level; 2.26.0 -> 2.26.1 follow-up in PR #105. The version line is the latest on Java 1.8 because Log4j 2.27+ requires Java 11+. GAV org.apache.logging.log4j:log4j-api@2.25.3 (MODERATE). Tier 2 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.8 entry.
+ ]]>
+ CVE-2026-49844
+
+
+
+ 2.26.0 (PR #103, issue #102) closed all cataloged 13 CVEs at the version-bump level; 2.26.0 -> 2.26.1 follow-up in PR #105. The version line is the latest on Java 1.8 because Log4j 2.27+ requires Java 11+. GAV org.apache.logging.log4j:log4j-core@2.25.3 (CRITICAL, HIGH, LOW, MODERATE). Tier 2 CVEs have no Java 8 fix at a newer line; mitigation is documented in docs/SECURITY-MITIGATIONS.md T2.8 entry.
+ ]]>
+ CVE-2017-5645
+ CVE-2020-9488
+ CVE-2021-44228
+ CVE-2021-44832
+ CVE-2021-45046
+ CVE-2021-45105
+ CVE-2023-26464
+ CVE-2025-68161
+ CVE-2026-34477
+ CVE-2026-34478
+ CVE-2026-34480
+
+
+
+
+
+
+ CVE-2016-2175
+ CVE-2018-11797
+ CVE-2018-8036
+ CVE-2019-0228
+ CVE-2021-27807
+ CVE-2021-27906
+ CVE-2021-31811
+ CVE-2021-31812
+
+
+
+
+
+
+ CVE-2012-0213
+ CVE-2014-3529
+ CVE-2014-3574
+ CVE-2014-9527
+ CVE-2017-12626
+ CVE-2017-5644
+ CVE-2019-12415
+
+
+
+
+ CVE-2012-0213
+ CVE-2022-26336
+
+
+
+
+
+
+ CVE-2017-18640
+ CVE-2022-1471
+ CVE-2022-25857
+ CVE-2022-38749
+ CVE-2022-38750
+ CVE-2022-38751
+ CVE-2022-38752
+ CVE-2022-41854
+
+
+
+
+
+
+ CVE-2009-2625
+ CVE-2012-0881
+ CVE-2013-4002
+ CVE-2020-14338
+ CVE-2022-23437
+
+
+
+
+
+
+ CVE-2026-8384
+
+
+
+
+ BIT-jenkins-2021-28165
+ BIT-kafka-2020-27218
+ BIT-nifi-2020-27223
+ BIT-solr-2020-27223
+ BIT-spark-2020-27218
+ BIT-spark-2020-27223
+ CVE-2006-6969
+ CVE-2011-4461
+ CVE-2015-2080
+ CVE-2016-4800
+ CVE-2017-7656
+ CVE-2017-7657
+ CVE-2017-7658
+ CVE-2017-9735
+ CVE-2018-12536
+ CVE-2018-12538
+ CVE-2018-12545
+ CVE-2019-10241
+ CVE-2019-10246
+ CVE-2019-10247
+ CVE-2019-17632
+ CVE-2019-17638
+ CVE-2020-27218
+ CVE-2020-27223
+ CVE-2021-28165
+ CVE-2021-34428
+ CVE-2022-2191
+ CVE-2023-26048
+ CVE-2023-26049
+ CVE-2024-13009
+ CVE-2024-7708
+ CVE-2024-8184
+ CVE-2026-10051
+ CVE-2026-1605
+ CVE-2026-6790
+
+
+
+
+
+
+ CVE-2019-14900
+ CVE-2020-25638
+ CVE-2026-0603
+
+
+
+
+ CVE-2019-10219
+ CVE-2020-10693
+ CVE-2023-1932
+ CVE-2025-35036
+
+
+
+
+
+
+ CVE-2010-2057
+ CVE-2011-4367
+
+
+
+
+
+
+ CVE-2016-10006
+ CVE-2017-14735
+ CVE-2021-35043
+ CVE-2022-28367
+ CVE-2022-29577
+ CVE-2023-43643
+ CVE-2024-23635
+
+
+
+
+ CVE-2010-3300
+ CVE-2013-5679
+ CVE-2013-5960
+ CVE-2022-23457
+ CVE-2022-24891
+
+
+
+
+
+
+ CVE-2012-5784
+ CVE-2014-3596
+ CVE-2018-8032
+ CVE-2019-0227
+ CVE-2023-40743
+ CVE-2023-51441
+
+
+
+
+ CVE-2007-2353
+ CVE-2012-5784
+ CVE-2014-3596
+ CVE-2018-8032
+ CVE-2019-0227
+ CVE-2023-40743
+ CVE-2023-51441
+
+
+
+
+ CVE-2014-9970
+
+
+
+
+ CVE-2022-40149
+ CVE-2022-40150
+ CVE-2022-45685
+ CVE-2022-45693
+ CVE-2023-1436
+
+
+
+
+ CVE-2024-47855
+
+
+
+
+ CVE-2016-2510
+
+
+
+
+ CVE-2025-66453
+
+
+
+
+ CVE-2022-40705
+ CVE-2022-45378
+
+
+
+
+ CVE-2018-17201
+ CVE-2018-17202
+
+
+
+
+
+
+ CVE-2017-8028
+ CVE-2024-38829
+ CVE-2026-41720
+
+
+
+
+
+
+ CVE-2026-3505
+
+
+
+
+ CVE-2023-33202
+ CVE-2025-8916
+ CVE-2026-5588
+
+
+
+
+ CVE-2023-33201
+ CVE-2023-33202
+ CVE-2024-29857
+ CVE-2024-30171
+ CVE-2024-30172
+ CVE-2024-34447
+ CVE-2025-14813
+ CVE-2025-8885
+ CVE-2026-0636
+ CVE-2026-5598
+
+
+
+
+ CVE-2025-58782
+
+
+
+
+ CVE-2016-4437
+ CVE-2019-12422
+ CVE-2020-11989
+ CVE-2020-13933
+ CVE-2020-1957
+ CVE-2021-41303
+ CVE-2022-32532
+ CVE-2022-40664
+ CVE-2023-46749
+ CVE-2026-23901
+ CVE-2026-43827
+ CVE-2026-49268
+
+
+
+
+ CVE-2016-6802
+ CVE-2020-17523
+ CVE-2023-34478
+ CVE-2023-46750
+ CVE-2026-43828
+
+
+
+
+ BIT-gradle-2020-11979
+ CVE-2020-11979
+ CVE-2020-1945
+ CVE-2021-36373
+ CVE-2021-36374
+ GHSA-j45w-qrgf-25vm
+
+
+
+
+ CVE-2024-21742
+
+
+
+
+ CVE-2022-31159
+
+
+
+
+ CVE-2024-29857
+ CVE-2024-30171
+ CVE-2024-30172
+ CVE-2025-8885
+
+
+
+
+ CVE-2021-47621
+
+
+
+
+ CVE-2021-37533
+
+
+
+
+ CVE-2021-28490
+
+
+
+
+ CVE-2016-15026
+
+
+
+
+ CVE-2018-1000632
+ CVE-2020-10683
+
+
+
+
+ CVE-2017-5661
+
+
+
+
+ CVE-2024-28168
+
+
+
+
+ CVE-2020-7692
+ CVE-2021-22573
+ SNYK-JAVA-COMGOOGLEOAUTHCLIENT-575276
+
+
+
+
+ CVE-2025-55163
+
+
+
+
+ CVE-2023-1428
+ CVE-2023-32731
+ CVE-2023-32732
+ PYSEC-2026-1425
+ PYSEC-2026-1426
+ PYSEC-2026-1427
+
+
+
+
+ CVE-2022-25647
+ SNYK-JAVA-COMGOOGLECODEGSON-1730327
+
+
+
+
+ CVE-2018-10237
+ CVE-2020-8908
+ CVE-2023-2976
+ SNYK-JAVA-COMGOOGLEGUAVA-1015415
+
+
+
+
+ BIT-jenkins-2023-36478
+ CVE-2023-36478
+
+
+
+
+ CVE-2011-1498
+ CVE-2012-6153
+ CVE-2013-4366
+ CVE-2014-3577
+ CVE-2015-5262
+ CVE-2020-13956
+
+
+
+
+ CVE-2011-1498
+ CVE-2012-6153
+ CVE-2013-4366
+ CVE-2014-3577
+ CVE-2015-5262
+ CVE-2020-13956
+
+
+
+
+ CVE-2021-23792
+
+
+
+
+ CVE-2020-28491
+
+
+
+
+ CVE-2016-3720
+ CVE-2016-7051
+
+
+
+
+ CVE-2018-1000873
+
+
+
+
+ CVE-2021-28170
+
+
+
+
+ BIT-solr-2021-33813
+ CVE-2021-33813
+
+
+
+
+ CVE-2016-5725
+
+
+
+
+ CVE-2022-45688
+ CVE-2023-5072
+
+
+
+
+ CVE-2015-6748
+ CVE-2021-37714
+ CVE-2022-36033
+ CVE-2026-71497
+
+
+
+
+ CVE-2020-15250
+
+
+
+
+ CVE-2022-24613
+ CVE-2022-24614
+
+
+
+
+ CVE-2026-42577
+
+
+
+
+ CVE-2020-11988
+
+
+
+
+ CVE-2021-22569
+ CVE-2022-3171
+ CVE-2022-3509
+ CVE-2022-3510
+ CVE-2024-7254
+
+
+
+
+ CVE-2019-13990
+
+
+
+
+ CVE-2017-1000190
+
+
+
+
+ BIT-solr-2020-13957
+ BIT-solr-2023-50298
+ CVE-2020-13957
+ CVE-2023-50298
+
+
+
+
+ CVE-2018-1270
+ CVE-2018-1275
+ CVE-2022-22971
+
+
+
+
+ CVE-2013-4152
+ CVE-2013-7315
+
+
+
+
+ CVE-2018-25031
+ CVE-2019-17495
+
+
+
+
+ CVE-2022-40152
+
+
+
+
+ CVE-2021-23926
+
+
+
+
+ CVE-2016-4216
+
+
+
+
+ CVE-2025-12383
+
+
+
+
+ CVE-2021-28168
+
+
+
+
+ CVE-2022-0839
+
+
+
+
+ CVE-2025-59250
+
+
+
+
+ CVE-2025-59250
+
+
+
+
+ CVE-2023-22102
+
+
+
+
+ CVE-2023-32697
+
+
+
+
+ BIT-apisix-2023-44487
+ BIT-aspnet-core-2023-44487
+ BIT-contour-2023-44487
+ BIT-dotnet-2023-44487
+ BIT-dotnet-sdk-2023-44487
+ BIT-envoy-2023-44487
+ BIT-golang-2023-44487
+ BIT-jenkins-2023-44487
+ BIT-kong-2023-44487
+ BIT-nginx-2023-44487
+ BIT-nginx-gateway-2023-44487
+ BIT-node-2023-44487
+ BIT-node-min-2023-44487
+ BIT-solr-2023-44487
+ BIT-tomcat-2023-44487
+ BIT-varnish-2023-44487
+ CVE-2023-44487
+ CVE-2024-22201
+ CVE-2025-5115
+
+
+
+
+ BIT-jenkins-2023-36478
+ CVE-2023-36478
+
+
+
+
+ BIT-apisix-2023-44487
+ BIT-aspnet-core-2023-44487
+ BIT-contour-2023-44487
+ BIT-dotnet-2023-44487
+ BIT-dotnet-sdk-2023-44487
+ BIT-envoy-2023-44487
+ BIT-golang-2023-44487
+ BIT-jenkins-2022-2048
+ BIT-jenkins-2023-44487
+ BIT-kong-2023-44487
+ BIT-nginx-2023-44487
+ BIT-nginx-gateway-2023-44487
+ BIT-node-2023-44487
+ BIT-node-min-2023-44487
+ BIT-solr-2023-44487
+ BIT-tomcat-2023-44487
+ BIT-varnish-2023-44487
+ CVE-2022-2048
+ CVE-2023-44487
+
+
+
+
+ CVE-2015-0254
- -->
+
\ No newline at end of file
diff --git a/projects/sitemanage/src/main/java/com/percussion/integrations/siteimprove/rest/PSSiteimprove.java b/projects/sitemanage/src/main/java/com/percussion/integrations/siteimprove/rest/PSSiteimprove.java
index da01c5db83..7d6039755b 100644
--- a/projects/sitemanage/src/main/java/com/percussion/integrations/siteimprove/rest/PSSiteimprove.java
+++ b/projects/sitemanage/src/main/java/com/percussion/integrations/siteimprove/rest/PSSiteimprove.java
@@ -24,6 +24,7 @@
import com.percussion.metadata.data.PSMetadata;
import com.percussion.metadata.data.PSMetadataList;
import com.percussion.metadata.service.IPSMetadataService;
+import com.percussion.role.service.impl.PSRoleService;
import com.percussion.services.integrations.siteimprove.PSSiteImproveProviderService;
import com.percussion.services.publisher.IPSEdition;
import com.percussion.services.publisher.IPSEditionTaskDef;
@@ -163,6 +164,16 @@ public Response storeSiteImproveToken(PSSiteImproveCredentials credentials) {
Boolean validCredentials = providerService.validateCredentials(credentialsToValidate);
if (validCredentials) {
+ // T2.14 hardening (epic #73, issue #223): CVE-2026-0603 second-order SQL injection.
+ // siteName becomes part of a String @Id primary key (PSMetadata.key) that Hibernate
+ // will later inline into UPDATE/DELETE predicates via InlineIdsOrClauseBuilder. A
+ // siteName with SQL metacharacters or control bytes turns the stored value into an
+ // injection lever. Reject before persistence.
+ if (PSRoleService.containsUnsafeIdentifierChar(credentials.getSiteName())) {
+ return Response.status(Response.Status.BAD_REQUEST)
+ .entity("siteName contains characters that are unsafe as a metadata identifier")
+ .build();
+ }
ObjectNode jsonMap = MAPPER.createObjectNode();
credentialsToValidate.forEach(jsonMap::put);
addSiteImproveTaskToPreExistingEditions(credentials.getSiteName());
@@ -206,6 +217,13 @@ public Response storeSiteImproveConfiguration(PSSiteImproveSiteConfigurations pu
throw new Exception("Settings may not be null and a valid site name must be provided.");
}
+ // T2.14 hardening (epic #73, issue #223): CVE-2026-0603 second-order SQL injection.
+ // Same protection as the credentials path: siteName flows into a String @Id key.
+ if (PSRoleService.containsUnsafeIdentifierChar(publishSettings.getSiteName())) {
+ throw new Exception(
+ "siteName contains characters that are unsafe as a metadata identifier");
+ }
+
String siteConfigKey = SITEIMPROVE_CONFIGURATION_BASE_KEY + publishSettings.getSiteName();
ObjectNode publishSettingsJSON = MAPPER.createObjectNode();
publishSettingsJSON.put("doProduction", publishSettings.getDoProduction());
diff --git a/projects/sitemanage/src/main/java/com/percussion/role/service/impl/PSRoleService.java b/projects/sitemanage/src/main/java/com/percussion/role/service/impl/PSRoleService.java
index f233ca04f9..674fca7aef 100644
--- a/projects/sitemanage/src/main/java/com/percussion/role/service/impl/PSRoleService.java
+++ b/projects/sitemanage/src/main/java/com/percussion/role/service/impl/PSRoleService.java
@@ -516,6 +516,15 @@ private void setHomepage(String roleName, String homepage)
if (StringUtils.isBlank(roleName)) {
throw new IllegalArgumentException("roleName must not be blank");
}
+ // T2.14 hardening (epic #73, issue #223): CVE-2026-0603 second-order SQL injection.
+ // PSMetadata.key is a String @Id primary key; Hibernate's InlineIdsOrClauseBuilder inlines
+ // that string into UPDATE/DELETE statements at a later time. If roleName carries a SQL
+ // metacharacter (quote, semicolon, comment, NUL) a later delete/update of the row could
+ // rewrite the predicate. Reject the input at the entry point instead.
+ if (containsUnsafeIdentifierChar(roleName)) {
+ throw new IllegalArgumentException(
+ "roleName contains characters that are unsafe as a metadata key identifier");
+ }
if (StringUtils.isBlank(homepage)
|| !(homepage.equals(HOMEPAGE_TYPE_DASHBOARD)
|| homepage.equals(HOMEPAGE_TYPE_EDITOR)
@@ -696,4 +705,35 @@ public IPSRoleMgr getRoleMgr() {
public void setRoleMgr(IPSRoleMgr roleMgr) {
this.roleMgr = roleMgr;
}
+
+ /**
+ * Returns {@code true} if the supplied identifier string contains a character that is unsafe as a
+ * primary key value in a Hibernate-managed String @Id column. CVE-2026-0603 is a second-order SQL
+ * injection: a tainted identifier that is persisted today can be inlined into UPDATE/DELETE SQL
+ * at a later time by Hibernate's {@code InlineIdsOrClauseBuilder}. We reject the obvious SQL
+ * metacharacters and all C0/C1 control bytes up front so a future caller does not turn a stored
+ * identifier into an injection lever.
+ *
+ * Public because {@code PSSiteimprove} lives in a different package and also composes
+ * user-controlled inputs into a String @Id column. The matching test {@code
+ * PSRoleServiceUnsafeIdTest} lives in the same package as this class.
+ */
+ public static boolean containsUnsafeIdentifierChar(String value) {
+ if (value == null) {
+ return true;
+ }
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ // SQL metacharacters Hibernate will inline into an OR-clause identifier predicate.
+ if (c == '\'' || c == '"' || c == ';' || c == '\\' || c == '-' || c == '/' || c == '*'
+ || c == '(' || c == ')' || c == '\0' || c == '\n' || c == '\r' || c == '\t') {
+ return true;
+ }
+ // C0 (0x00-0x1F) and C1 (0x7F-0x9F) control characters.
+ if (c < 0x20 || (c >= 0x7F && c <= 0x9F)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/projects/sitemanage/src/test/java/com/percussion/role/service/impl/PSRoleServiceUnsafeIdTest.java b/projects/sitemanage/src/test/java/com/percussion/role/service/impl/PSRoleServiceUnsafeIdTest.java
new file mode 100644
index 0000000000..d42f1d34b0
--- /dev/null
+++ b/projects/sitemanage/src/test/java/com/percussion/role/service/impl/PSRoleServiceUnsafeIdTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1999-2026 Percussion Software, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.percussion.role.service.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for the identifier safety helper added in T2.14 (epic #73, issue #223). The helper
+ * sits at the entry point of any user-controlled String value that flows into a Hibernate String
+ * {@code @Id} column, and is meant to block CVE-2026-0603 second-order SQL injection at the
+ * boundary before the tainted value is persisted.
+ *
+ *
JUnit 4 to match the rest of the role service test package.
+ */
+public class PSRoleServiceUnsafeIdTest {
+
+ @Test
+ public void rejectsNull() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar(null));
+ }
+
+ @Test
+ public void acceptsPlausibleRoleNames() {
+ assertFalse(PSRoleService.containsUnsafeIdentifierChar("Admin"));
+ assertFalse(PSRoleService.containsUnsafeIdentifierChar("Editor"));
+ assertFalse(PSRoleService.containsUnsafeIdentifierChar("Site_Author"));
+ assertFalse(PSRoleService.containsUnsafeIdentifierChar("Author.1"));
+ assertFalse(PSRoleService.containsUnsafeIdentifierChar("role with spaces"));
+ assertFalse(PSRoleService.containsUnsafeIdentifierChar("café"));
+ }
+
+ @Test
+ public void rejectsSingleQuote() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin'"));
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("' OR 1=1"));
+ }
+
+ @Test
+ public void rejectsDoubleQuote() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\""));
+ }
+
+ @Test
+ public void rejectsSemicolon() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin;DROP TABLE users"));
+ }
+
+ @Test
+ public void rejectsBackslash() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\\"));
+ }
+
+ @Test
+ public void rejectsDash() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin--comment"));
+ }
+
+ @Test
+ public void rejectsSlashes() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin/x"));
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin/*x"));
+ }
+
+ @Test
+ public void rejectsAsteriskAndParens() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin*"));
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin(1)"));
+ }
+
+ @Test
+ public void rejectsNullAndControlCharacters() {
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\u0000"));
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\n"));
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\r"));
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\t"));
+ }
+
+ @Test
+ public void rejectsC1ControlCharacters() {
+ // U+0085 (NEL) and U+009F (APC) are C1 controls and must be rejected.
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\u0085"));
+ assertTrue(PSRoleService.containsUnsafeIdentifierChar("Admin\u009F"));
+ }
+}
diff --git a/system/ear/config/spring/beans.xml b/system/ear/config/spring/beans.xml
index dd8bbddc5c..da7f3a488e 100644
--- a/system/ear/config/spring/beans.xml
+++ b/system/ear/config/spring/beans.xml
@@ -373,6 +373,15 @@ http://www.springframework.org/schema/context/spring-context.xsd">
true
false
create
+
+ bind
diff --git a/system/services/src/com/percussion/services/relationship/impl/PSRelationshipService.java b/system/services/src/com/percussion/services/relationship/impl/PSRelationshipService.java
index a6b131866d..aee14ab1c4 100644
--- a/system/services/src/com/percussion/services/relationship/impl/PSRelationshipService.java
+++ b/system/services/src/com/percussion/services/relationship/impl/PSRelationshipService.java
@@ -615,8 +615,12 @@ public void reloadConfigs() throws PSException
public List findByDependentId(int dependentId) {
Session session = getSession();
+ // T2.14 hardening (epic #73, issue #223): parameter binding instead of string concat.
+ // The call sites pass typed ints today, but the concat pattern is an unsafe precedent;
+ // a future caller that hands us a tainted string could otherwise build a SQLi surface.
Query query = session
- .createQuery("from PSRelationshipData " + " where dependent_id = " + dependentId);
+ .createQuery("from PSRelationshipData where dependent_id = :dependentId");
+ query.setParameter("dependentId", dependentId);
return query.list();
}
@@ -927,8 +931,12 @@ public void updateRelationshipData(
public List findByDependentIdConfigId(int dependentId, int configId) {
Session session = getSession();
+ // T2.14 hardening (epic #73, issue #223): parameter binding instead of string concat.
Query query = session
- .createQuery("from PSRelationshipData " + " where dependent_id = " + dependentId +" and config_id = " + configId);
+ .createQuery("from PSRelationshipData where dependent_id = :dependentId"
+ + " and config_id = :configId");
+ query.setParameter("dependentId", dependentId);
+ query.setParameter("configId", configId);
return query.list();
}
diff --git a/system/src/main/resources/META-INF/validation.xml b/system/src/main/resources/META-INF/validation.xml
new file mode 100644
index 0000000000..bac41686e3
--- /dev/null
+++ b/system/src/main/resources/META-INF/validation.xml
@@ -0,0 +1,28 @@
+
+
+
+ org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator
+
\ No newline at end of file