From 7d7c90f5a15af55e06bc70808f102e71bb01bcdf Mon Sep 17 00:00:00 2001 From: Andrea Cosentino Date: Fri, 10 Jul 2026 11:20:26 +0200 Subject: [PATCH 1/2] CAMEL-23979: Expose published CVE security advisories via camel-catalog and camel-jbang-mcp Sync the published Apache Camel security advisories (camel.apache.org/security) from camel-website into a JSON file shipped with camel-catalog, like the known releases sync: new update-security-advisories goal in camel-package-maven-plugin, new CamelCatalog.camelSecurityAdvisories() API and SecurityAdvisoryModel. The MCP server consumes the catalog fully offline: new camel_security_advisories tool, camel://security/advisories resources, and camel_route_harden_context now embeds the known CVEs affecting the components used by the route. Co-Authored-By: Claude Fable 5 Signed-off-by: Andrea Cosentino --- catalog/camel-catalog/pom.xml | 20 + .../advisories/camel-security-advisories.json | 1067 +++++++++++++++++ .../apache/camel/catalog/CamelCatalog.java | 8 + .../camel/catalog/DefaultCamelCatalog.java | 20 + .../camel/catalog/CamelCatalogTest.java | 20 + .../modules/ROOT/pages/camel-jbang-mcp.adoc | 27 +- .../core/commands/mcp/AdvisoryResources.java | 127 ++ .../core/commands/mcp/AdvisoryService.java | 218 ++++ .../core/commands/mcp/AdvisoryTools.java | 90 ++ .../jbang/core/commands/mcp/HardenTools.java | 70 +- .../commands/mcp/AdvisoryResourcesTest.java | 110 ++ .../commands/mcp/AdvisoryServiceTest.java | 179 +++ .../core/commands/mcp/AdvisoryToolsTest.java | 86 ++ .../commands/mcp/HardenToolsAdvisoryTest.java | 100 ++ .../camel/tooling/model/JsonMapper.java | 49 + .../tooling/model/SecurityAdvisoryModel.java | 122 ++ .../UpdateSecurityAdvisoriesMojo.java | 292 +++++ .../UpdateSecurityAdvisoriesMojoTest.java | 117 ++ .../security-advisories/CVE-2013-4330.md | 23 + .../security-advisories/CVE-2025-27636.md | 53 + 20 files changed, 2792 insertions(+), 6 deletions(-) create mode 100644 catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json create mode 100644 dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResources.java create mode 100644 dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryService.java create mode 100644 dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java create mode 100644 dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResourcesTest.java create mode 100644 dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryServiceTest.java create mode 100644 dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryToolsTest.java create mode 100644 dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenToolsAdvisoryTest.java create mode 100644 tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/SecurityAdvisoryModel.java create mode 100644 tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java create mode 100644 tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java create mode 100644 tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2013-4330.md create mode 100644 tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2025-27636.md diff --git a/catalog/camel-catalog/pom.xml b/catalog/camel-catalog/pom.xml index b69d86249ac59..d49ad0fb9f46e 100644 --- a/catalog/camel-catalog/pom.xml +++ b/catalog/camel-catalog/pom.xml @@ -227,6 +227,26 @@ + + update-security-advisories + + + + org.apache.camel + camel-package-maven-plugin + + + + + update-security-advisories + + generate-resources + + + + + + diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json new file mode 100644 index 0000000000000..bc565492b6ad9 --- /dev/null +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json @@ -0,0 +1,1067 @@ +[ + { + "cve": "CVE-2013-4330", + "date": "2013-10-04T13:55:09.853000", + "severity": "CRITICAL", + "summary": "Writing files using FILE or FTP components, can potentially be exploited by a malicious user.", + "affected": "2.9.0 up to 2.9.7, 2.10.0 up to 2.10.6, 2.11.0 up to 2.11.1, 2.12.0", + "fixed": "2.9.8, 2.10.7, 2.11.2, 2.12.1 and newer", + "mitigation": "2.9.x users should upgrade to 2.9.8, 2.10.x users should upgrade to 2.10.7, 2.11.x users should upgrade to 2.11.2 and 2.12.0 users should upgrade to 2.12.1. This patch will be included from Camel 2.13.0: https:\/\/git-wip-us.apache.org\/repos\/asf?p=camel.git;a=commitdiff;h=27a9752a565fbef436bac4fcf22d339e3295b2a0", + "url": "https:\/\/camel.apache.org\/security\/CVE-2013-4330.html" + }, + { + "cve": "CVE-2014-0002", + "date": "2014-03-21T00:38:59.027000", + "severity": "CRITICAL", + "summary": "The Apache Camel XSLT component will resolve entities in XML messages when transforming them using an xslt route.", + "affected": "2.11.0 up to 2.11.3, 2.12.0 up to 2.12.2", + "fixed": "2.11.4, 2.12.3, 2.13.0 and newer", + "mitigation": "2.11.x users should upgrade to 2.11.4, 2.12.x users should upgrade to 2.12.3. This patch will be included from Camel 2.13.0: https:\/\/git-wip-us.apache.org\/repos\/asf?p=camel.git;a=commitdiff;h=341d4e6cca71c53c90962d1c3d45fc9e05cc50c6", + "url": "https:\/\/camel.apache.org\/security\/CVE-2014-0002.html" + }, + { + "cve": "CVE-2014-0003", + "date": "2014-03-21T00:38:59.057000", + "severity": "CRITICAL", + "summary": "The Apache Camel XSLT component allows XSL stylesheets to perform calls to external Java methods.", + "affected": "2.11.0 up to 2.11.3, 2.12.0 up to 2.12.2", + "fixed": "2.11.4, 2.12.3, 2.13.0 and newer", + "mitigation": "2.11.x users should upgrade to 2.11.4, 2.12.x users should upgrade to 2.12.3. This patch will be included from Camel 2.13.0: https:\/\/git-wip-us.apache.org\/repos\/asf?p=camel.git;a=commitdiff;h=e922f89290f236f3107039de61af0375826bd96d", + "url": "https:\/\/camel.apache.org\/security\/CVE-2014-0003.html" + }, + { + "cve": "CVE-2015-0263", + "date": "2015-06-03T16:59:02.917000", + "severity": "MEDIUM", + "summary": "The XML converter setup in Apache Camel allows remote attackers to read arbitrary files via an SAXSource containing an XML External Entity (XXE) declaration.", + "affected": "2.13.0 up to 2.13.3, 2.14.0 up to 2.14.1", + "fixed": "2.13.4, 2.14.2, 2.15.0 and newer", + "mitigation": "2.13.x users should upgrade to 2.13.4, 2.14.x users should upgrade to 2.14.2. This patch will be included from Camel 2.15.0: https:\/\/git-wip-us.apache.org\/repos\/asf?p=camel.git;a=commitdiff;h=7d19340bcdb42f7aae584d9c5003ac4f7ddaee36", + "url": "https:\/\/camel.apache.org\/security\/CVE-2015-0263.html" + }, + { + "cve": "CVE-2015-0264", + "date": "2015-06-03T16:59:04.403000", + "severity": "MEDIUM", + "summary": "The XPath handling in Apache Camel for invalid XML Strings or invalid XML GenericFile objects allows remote attackers to read arbitrary files via an XML External Entity (XXE) declaration. The XML External Entity (XXE) will be resolved before the Exception is thrown.", + "affected": "2.13.0 up to 2.13.3, 2.14.0 up to 2.14.1", + "fixed": "2.13.4, 2.14.2, 2.15.0 and newer", + "mitigation": "2.13.x users should upgrade to 2.13.4, 2.14.x users should upgrade to 2.14.2. This patch will be included from Camel 2.15.0: https:\/\/git-wip-us.apache.org\/repos\/asf?p=camel.git;a=commitdiff;h=1df559649a96a1ca0368373387e542f46e4820da", + "url": "https:\/\/camel.apache.org\/security\/CVE-2015-0264.html" + }, + { + "cve": "CVE-2015-5344", + "date": "2016-02-03T13:59:00.117000", + "severity": "MEDIUM", + "summary": "Apache Camel's XStream usage is vulnerable to Remote Code Execution attacks.", + "affected": "2.15.0 up to 2.15.4, 2.16.0", + "fixed": "2.15.5, 2.16.1 and newer", + "mitigation": "2.15.x users should upgrade to 2.15.5, 2.16.0 users should upgrade to 2.16.1. And if you are using camel-xstream to serialize payload to Java objects, then you need to explicitly list trusted packages. To see how to do that, please take a look at: http:\/\/camel.apache.org\/xstream", + "url": "https:\/\/camel.apache.org\/security\/CVE-2015-5344.html", + "components": [ + "camel-xstream" + ] + }, + { + "cve": "CVE-2015-5348", + "date": "2016-04-15T11:59:00.110000", + "severity": "MEDIUM", + "summary": "Apache Camel's Jetty\/Servlet usage is vulnerable to Java object de-serialisation vulnerability.", + "affected": "2.15.0 up to 2.15.4, 2.16.0", + "fixed": "2.15.5, 2.16.1 and newer", + "mitigation": "2.15.x users should upgrade to 2.15.5, 2.16.0 users should upgrade to 2.16.1.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2015-5348.html" + }, + { + "cve": "CVE-2016-8749", + "date": "2017-03-28T14:59:00.143000", + "severity": "MEDIUM", + "summary": "Apache Camel's Jackson and JacksonXML unmarshalling operation are vulnerable to Remote Code Execution attacks", + "affected": "2.16.0 up to 2.16.4, 2.17.0 up to 2.17.4, 2.18.0 up to 2.18.1", + "fixed": "2.16.5, 2.17.5, 2.18.2", + "mitigation": "2.16.x users should upgrade to 2.16.5, 2.17.x users should upgrade to 2.17.5, 2.18.x users should upgrade to 2.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2016-8749.html", + "components": [ + "camel-jackson", + "camel-jacksonxml" + ] + }, + { + "cve": "CVE-2017-3159", + "date": "2017-03-07T10:59:00.517000", + "severity": "MEDIUM", + "summary": "Apache Camel's Snakeyaml unmarshalling operation is vulnerable to Remote Code Execution attacks", + "affected": "2.17.0 up to 2.17.4, 2.18.0 up to 2.18.1", + "fixed": "2.17.5, 2.18.2 and newer", + "mitigation": "2.17.x users should upgrade to 2.17.5, 2.18.x users should upgrade to 2.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2017-3159.html", + "components": [ + "camel-snakeyaml" + ] + }, + { + "cve": "CVE-2017-5643", + "date": "2017-03-16T11:59:00.947000", + "severity": "MEDIUM", + "summary": "Apache Camel's Validation Component is vulnerable against SSRF via remote DTDs and XXE", + "affected": "2.17.0 up to 2.17.5, 2.18.0 up to 2.18.2", + "fixed": "2.17.6, 2.18.3 and newer", + "mitigation": "2.17.x users should upgrade to 2.17.6, 2.18.x users should upgrade to 2.18.3.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2017-5643.html" + }, + { + "cve": "CVE-2017-12633", + "date": "2017-11-15T10:29:00.210000", + "severity": "MEDIUM", + "summary": "Apache Camel's Hessian unmarshalling operation is vulnerable to Remote Code Execution attacks", + "affected": "2.19.0 up to 2.19.3, 2.20.0", + "fixed": "2.19.4, 2.20.1 and newer", + "mitigation": "2.19.x users should upgrade to 2.19.4, 2.20.0 users should upgrade to 2.20.1.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2017-12633.html", + "components": [ + "camel-hessian" + ] + }, + { + "cve": "CVE-2017-12634", + "date": "2017-11-15T10:29:00.257000", + "severity": "MEDIUM", + "summary": "Apache Camel's Castor unmarshalling operation is vulnerable to Remote Code Execution attacks", + "affected": "2.19.0 up to 2.19.3, 2.20.0", + "fixed": "2.19.4, 2.20.1 and newer", + "mitigation": "2.19.x users should upgrade to 2.19.4, 2.20.0 users should upgrade to 2.20.1.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2017-12634.html", + "components": [ + "camel-castor" + ] + }, + { + "cve": "CVE-2018-8027", + "date": "2018-07-31T09:29:00.857000", + "severity": "MEDIUM", + "summary": "Apache Camel's Core is vulnerable to XXE in XSD validation processor", + "affected": "2.20.0 up to 2.20.3, 2.21.0", + "fixed": "2.20.4, 2.21.1 and newer", + "mitigation": "2.20.x users should upgrade to 2.20.4, 2.21.0 users should upgrade to 2.21.1. The JIRA tickets: https:\/\/issues.apache.org\/jira\/browse\/CAMEL-12444 and https:\/\/issues.apache.org\/jira\/browse\/CAMEL-10894 (partial fix) refer to the various commits that resovoled the issue, and have more details.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2018-8027.html", + "components": [ + "camel-10894", + "camel-12444" + ] + }, + { + "cve": "CVE-2018-8041", + "date": "2018-09-17T10:29:00.920000", + "severity": "MEDIUM", + "summary": "Apache Camel's Mail is vulnerable to path traversal", + "affected": "2.20.0 up to 2.20.3, 2.21.0 up to 2.21.1, 2.22.0", + "fixed": "2.20.4, 2.21.1, 2.22.1 and newer", + "mitigation": "2.20.x users should upgrade to 2.20.4, 2.21.0 users should upgrade to 2.21.2 and Camel 2.22.x users should upgrade to 2.22.1", + "url": "https:\/\/camel.apache.org\/security\/CVE-2018-8041.html" + }, + { + "cve": "CVE-2019-0188", + "date": "2019-05-27T12:58:33+02:00", + "severity": "MEDIUM", + "summary": "Apache Camel-XMLJson vulnerable to XML external entity injection (XXE)", + "affected": "Apache Camel versions prior to 2.24.0", + "fixed": "2.24.0", + "mitigation": "Update to version 2.24.0", + "url": "https:\/\/camel.apache.org\/security\/CVE-2019-0188.html", + "components": [ + "camel-xmljson" + ] + }, + { + "cve": "CVE-2019-0194", + "date": "2019-04-30T18:29:00.607000", + "severity": "MEDIUM", + "summary": "Apache Camel's File is vulnerable to directory traversal", + "affected": "2.21.0 up to 2.21.3, 2.22.0 up to 2.22.2, 2.23.0", + "fixed": "2.21.5, 2.22.3, 2.23.1", + "mitigation": "2.21.x users should upgrade to 2.21.5, 2.22.x users should upgrade to 2.22.3 and Camel 2.23.x users should upgrade to 2.23.1", + "url": "https:\/\/camel.apache.org\/security\/CVE-2019-0194.html" + }, + { + "cve": "CVE-2020-11971", + "date": "2020-05-14T14:47:42+02:00", + "severity": "MEDIUM", + "summary": "Apache Camel JMX Rebind Flaw Vulnerability", + "affected": "2.22.x, 2.23.x, 2.24.x, 2.25.x, 3.0.0 up to 3.1.0", + "fixed": "3.2.0", + "mitigation": "Users should upgrade to 3.2.0", + "url": "https:\/\/camel.apache.org\/security\/CVE-2020-11971.html" + }, + { + "cve": "CVE-2020-11972", + "date": "2020-05-14T14:47:42+02:00", + "severity": "MEDIUM", + "summary": "Apache Camel RabbitMQ enables Java deserialization by default", + "affected": "2.22.x, 2.23.x, 2.24.x, 2.25.0, 3.0.0 up to 3.1.0", + "fixed": "2.25.1, 3.2.0", + "mitigation": "2.x users should upgrade to 2.25.1, 3.x users should upgrade to 3.2.0", + "url": "https:\/\/camel.apache.org\/security\/CVE-2020-11972.html" + }, + { + "cve": "CVE-2020-11973", + "date": "2020-05-14T14:47:42+02:00", + "severity": "MEDIUM", + "summary": "Apache Camel Netty enables Java deserialization by default", + "affected": "2.22.x, 2.23.x, 2.24.x, 2.25.0, 3.0.0 up to 3.1.0", + "fixed": "2.25.1, 3.2.0", + "mitigation": "2.x users should upgrade to 2.25.1, 3.x users should upgrade to 3.2.0", + "url": "https:\/\/camel.apache.org\/security\/CVE-2020-11973.html" + }, + { + "cve": "CVE-2020-11994", + "date": "2020-07-08T08:47:42+02:00", + "severity": "MEDIUM", + "summary": "Server-Side Template Injection and arbitrary file disclosure on Camel templating components", + "affected": "2.22.x, 2.23.x, 2.24.x, 2.25.0 and 2.25.1, 3.0.0 up to 3.3.0", + "fixed": "2.25.2, 3.4.0", + "mitigation": "2.x users should upgrade to 2.25.2, 3.x users should upgrade to 3.4.0", + "url": "https:\/\/camel.apache.org\/security\/CVE-2020-11994.html" + }, + { + "cve": "CVE-2022-45046", + "date": "2022-12-05T08:47:42+02:00", + "severity": "MEDIUM", + "summary": "LDAP Injection in camel-ldap", + "affected": "3.0.0 up to 3.14.5, and 3.15.0 up to 3.18.3, and 3.19.0.", + "fixed": "3.14.6, 3.18.4", + "mitigation": "Users should upgrade to 3.14.6 or 3.18.4", + "url": "https:\/\/camel.apache.org\/security\/CVE-2022-45046.html", + "components": [ + "camel-ldap" + ] + }, + { + "cve": "CVE-2023-34442", + "date": "2023-07-07T11:15:42+02:00", + "severity": "LOW", + "summary": "Temporary File Local Information Disclosure in camel-jira", + "affected": "3.0.0 up to 3.14.8, and 3.18.0 up to 3.18.7, 3.20.0 up to 3.20.5 and 4.0.0-M1 up to 4.0.0-M3", + "fixed": "3.14.9, 3.18.8, 3.20.6, 3.21.0 and 4.0.0-RC1", + "mitigation": "Users should upgrade to 3.14.9, 3.18.8, 3.20.6 or 3.21.0 and for users on Camel 4.x update to 4.0.0-M1", + "url": "https:\/\/camel.apache.org\/security\/CVE-2023-34442.html", + "components": [ + "camel-jira" + ] + }, + { + "cve": "CVE-2024-22369", + "date": "2024-02-19T09:25:42+02:00", + "severity": "HIGH", + "summary": "Apache Camel: Camel-SQL: Unsafe Deserialization from JDBCAggregationRepository", + "affected": "From 3.0.0 before 3.21.4, from 3.22.0 before 3.22.1, from 4.0.0 before 4.0.4, from 4.1.0 before 4.4.0.", + "fixed": "3.21.4, 3.22.1, 4.0.4 and 4.4.0", + "mitigation": "Users are recommended to upgrade to version 4.4.0, which fixes the issue. If users are on the 4.0.x LTS releases stream, then they are suggested to upgrade to 4.0.4. If users are on 3.x, they are suggested to move to 3.21.4 or 3.22.1", + "url": "https:\/\/camel.apache.org\/security\/CVE-2024-22369.html", + "components": [ + "camel-sql" + ] + }, + { + "cve": "CVE-2024-22371", + "date": "2024-02-19T10:41:48+02:00", + "severity": "LOW", + "summary": "Exposure of sensitive data by by crafting a malicious EventFactory and providing a custom ExchangeCreatedEvent that exposes sensitive data", + "affected": "From 3.0.0 before 3.21.4, from 3.22.0 before 3.22.1, from 4.0.0 before 4.0.4, from 4.1.0 before 4.4.0", + "fixed": "3.21.4, 3.22.1, 4.0.4 and 4.4.0", + "mitigation": "Users are recommended to upgrade to version 4.4.0, which fixes the issue. If users are on the 4.0.x LTS releases stream, then they are suggested to upgrade to 4.0.4. If users are on 3.x, they are suggested to move to 3.21.4 or 3.22.1", + "url": "https:\/\/camel.apache.org\/security\/CVE-2024-22371.html" + }, + { + "cve": "CVE-2024-23114", + "date": "2024-02-19T09:26:42+02:00", + "severity": "HIGH", + "summary": "Apache Camel: Camel-CassandraQL: Unsafe Deserialization from CassandraAggregationRepository", + "affected": "From 3.0.0 before 3.21.4, from 3.22.0 before 3.22.1, from 4.0.0 before 4.0.4, from 4.1.0 before 4.4.0.", + "fixed": "3.21.4, 3.22.1, 4.0.4 and 4.4.0", + "mitigation": "Users are recommended to upgrade to version 4.4.0, which fixes the issue. If users are on the 4.0.x LTS releases stream, then they are suggested to upgrade to 4.0.4. If users are on 3.x, they are suggested to move to 3.21.4 or 3.22.1", + "url": "https:\/\/camel.apache.org\/security\/CVE-2024-23114.html", + "components": [ + "camel-cassandraql" + ] + }, + { + "cve": "CVE-2025-27636", + "date": "2025-03-09T04:30:42+02:00", + "severity": "MEDIUM", + "summary": "Camel Message Header Injection via Improper Filtering", + "affected": "Apache Camel 4.10.0 before 4.10.2. Apache Camel 4.8.0 before 4.8.5. Apache Camel 3.10.0 before 3.22.4.", + "fixed": "3.22.4, 4.8.5 and 4.10.2", + "mitigation": "Users are recommended to upgrade to version 4.10.2 for 4.10.x LTS, 4.8.5 for 4.8.x LTS and 3.22.4 for 3.x releases. Also, users could use removeHeaders EIP, to filter out anything like 'cAmel, cAMEL' etc, or in general everything not starting with 'Camel', 'camel' or 'org.apache.camel.'.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2025-27636.html", + "components": [ + "camel-activemq", + "camel-activemq6", + "camel-amqp", + "camel-aws2-sqs", + "camel-azure-servicebus", + "camel-bean", + "camel-cxf-rest", + "camel-cxf-soap", + "camel-http", + "camel-jetty", + "camel-jms", + "camel-kafka", + "camel-knative", + "camel-mail", + "camel-nats", + "camel-netty-http", + "camel-platform-http", + "camel-rest", + "camel-servlet", + "camel-sjms", + "camel-spring-rabbitmq", + "camel-stomp", + "camel-tahu", + "camel-undertow", + "camel-xmpp" + ] + }, + { + "cve": "CVE-2025-29891", + "date": "2025-03-12T07:30:42+02:00", + "severity": "HIGH", + "summary": "Camel Message Header Injection through request parameters", + "affected": "Apache Camel 4.10.0 before 4.10.2. Apache Camel 4.8.0 before 4.8.5. Apache Camel 3.10.0 before 3.22.4.", + "fixed": "3.22.4, 4.8.5 and 4.10.2", + "mitigation": "Users are recommended to upgrade to version 4.10.2 for 4.10.x LTS, 4.8.5 for 4.8.x LTS and 3.22.4 for 3.x releases. Also, users could use removeHeaders EIP, to filter out anything like 'cAmel, cAMEL' etc, or in general everything not starting with 'Camel', 'camel' or 'org.apache.camel.'.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2025-29891.html", + "components": [ + "camel-bean", + "camel-exec", + "camel-jetty", + "camel-netty-http", + "camel-platform-http", + "camel-servlet", + "camel-undertow" + ] + }, + { + "cve": "CVE-2025-30177", + "date": "2025-04-01T07:30:42+02:00", + "severity": "MEDIUM", + "summary": "Camel-Undertow Message Header Injection via Improper Filtering", + "affected": "Apache Camel 4.10.0 before 4.10.3. Apache Camel 4.8.0 before 4.8.6.", + "fixed": "4.8.6 and 4.10.3", + "mitigation": "Users are recommended to upgrade to version 4.10.3 for 4.10.x LTS and 4.8.6 for 4.8.x LTS.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2025-30177.html", + "components": [ + "camel-bean", + "camel-exec", + "camel-undertow" + ] + }, + { + "cve": "CVE-2025-66169", + "date": "2026-01-13T07:30:42+02:00", + "severity": "MEDIUM", + "summary": "Cypher injection vulnerability in Camel-Neo4j component", + "affected": "Apache Camel 4.10.x before 4.10.8, Apache Camel 4.14.x before 4.14.3, Apache Camel 4.15.0 and 4.16.0.", + "fixed": "4.10.8, 4.14.3 and 4.17.0", + "mitigation": "Users are recommended to upgrade to version 4.10.8 for 4.10.x LTS and 4.14.3 for 4.14.x LTS and 4.17.0.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2025-66169.html", + "components": [ + "camel-neo4j" + ] + }, + { + "cve": "CVE-2026-23552", + "date": "2026-02-17T09:00:00+02:00", + "severity": "HIGH", + "summary": "Apache Camel: Camel-Keycloak: Cross-Realm Token Acceptance in KeycloakSecurityPolicy", + "affected": "From 4.15.0 before 4.18.0.", + "fixed": "4.18.0", + "mitigation": "Users are recommended to upgrade to version 4.18.0, which fixes the issue.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-23552.html", + "components": [ + "camel-keycloak" + ] + }, + { + "cve": "CVE-2026-25747", + "date": "2026-02-18T09:00:00+02:00", + "severity": "HIGH", + "summary": "Apache Camel: Camel-LevelDB: Unsafe Deserialization from LevelDBAggregationRepository", + "affected": "From 3.0.0 before 4.10.9, from 4.11.0 before 4.14.5, from 4.15.0 before 4.18.0.", + "fixed": "4.10.9, 4.14.5 and 4.18.0", + "mitigation": "Users are recommended to upgrade to version 4.18.0, which fixes the issue. If users are on the 4.10.x LTS releases stream, then they are suggested to upgrade to 4.10.9. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.5.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-25747.html", + "components": [ + "camel-leveldb" + ] + }, + { + "cve": "CVE-2026-27172", + "date": "2026-04-24T09:00:00+02:00", + "severity": "HIGH", + "summary": "Apache Camel: Unsafe Java deserialization in camel-consul ConsulRegistry allows arbitrary code execution via malicious values read from the Consul KV store", + "affected": "From 3.0.0 before 4.14.6 and from 4.15.0 before 4.18.1", + "fixed": "4.14.6, 4.18.1 and 4.19.0", + "mitigation": "Users are recommended to upgrade to version 4.19.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.1.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-27172.html", + "components": [ + "camel-consul" + ] + }, + { + "cve": "CVE-2026-33453", + "date": "2026-05-06T09:00:00+02:00", + "severity": "HIGH", + "summary": "Apache Camel: Improperly Controlled Modification of Dynamically-Determined Object Attributes vulnerability in Camel-Coap component.", + "affected": "From 4.14.0 before 4.14.6, from 4.15.0 before 4.18.1.", + "fixed": "4.14.6, 4.18.1 and 4.19.0", + "mitigation": "Users are recommended to upgrade to version 4.18.1, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6. The 4.19.0 development release also contains the fix.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-33453.html", + "components": [ + "camel-bean", + "camel-coap", + "camel-exec", + "camel-file", + "camel-freemarker", + "camel-sql", + "camel-velocity" + ] + }, + { + "cve": "CVE-2026-33454", + "date": "2026-04-24T09:00:00+02:00", + "severity": "HIGH", + "summary": "Camel-Mail Message Header Injection via Improper Filtering", + "affected": "From 3.0.0 before 4.14.6, from 4.15.0 before 4.18.1.", + "fixed": "4.14.6, 4.18.1 and 4.19.0", + "mitigation": "Users are recommended to upgrade to version 4.19.0, which fixes the issue. If users are on the 4.18.x LTS releases stream, then they are suggested to upgrade to 4.18.1. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-33454.html", + "components": [ + "camel-bean", + "camel-exec", + "camel-mail", + "camel-prefixed", + "camel-specific", + "camel-sql", + "camel-undertow" + ] + }, + { + "cve": "CVE-2026-40022", + "date": "2026-04-24T09:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Platform-HTTP-Main: Authentication Bypass on Non-Root Context Paths in camel main runtime", + "affected": "From 4.14.1 before 4.14.6, from 4.15.0 before 4.18.2.", + "fixed": "4.14.6, 4.18.2 and 4.20.0", + "mitigation": "Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, they are suggested to upgrade to 4.14.6. If users are on the 4.18.x LTS releases stream, they are suggested to upgrade to 4.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40022.html", + "components": [ + "camel-platform-http-main" + ] + }, + { + "cve": "CVE-2026-40047", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Docling: Insufficient validation of custom CLI arguments enables argument injection and path traversal in DoclingProducer", + "affected": "From 4.15.0 before 4.18.3.", + "fixed": "4.18.3 and 4.19.0", + "mitigation": "Users are recommended to upgrade to a release that contains the CAMEL-23212 fix. On the mainline the fix is included from Apache Camel 4.19.0 (and later releases such as 4.20.0). For users on the 4.18.x LTS releases stream, upgrade to 4.18.3. The fix replaces the denylist with a strict allowlist of recognized `docling` CLI flags (rejecting any unrecognized flag, and rejecting producer-managed flags such as the output-directory flags), defensively rejects shell metacharacters in argument values, and normalizes path-like values with Path.normalize() before validating them so that traversal sequences which bypass a literal `..\/` check are detected. As defence in depth, route authors should avoid mapping untrusted message content into the `CamelDoclingCustomArguments` header and the path-bearing headers, and should strip Camel-internal headers from messages that arrive from untrusted producers.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40047.html", + "components": [ + "camel-23212", + "camel-docling", + "camel-internal" + ] + }, + { + "cve": "CVE-2026-40048", + "date": "2026-04-24T09:00:00+02:00", + "severity": "HIGH", + "summary": "Camel-PQC: Unsafe Deserialization from FileBasedKeyLifecycleManager", + "affected": "From 4.19.0 before 4.20.0, from 4.18.0 before 4.18.2.", + "fixed": "4.18.2 and 4.20.0", + "mitigation": "Users are recommended to upgrade to version 4.20.0, which fixes the issue by replacing java.io.ObjectInputStream-based key and metadata storage with standard PKCS#8 (private key) \/ X.509 SubjectPublicKeyInfo (public key) Base64 JSON encoding. For users on the 4.18.x LTS releases stream, upgrade to 4.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40048.html", + "components": [ + "camel-pqc" + ] + }, + { + "cve": "CVE-2026-40453", + "date": "2026-04-24T09:00:00+02:00", + "severity": "MEDIUM", + "summary": "Incomplete fix for CVE-2025-27636 in non-HTTP HeaderFilterStrategies (camel-jms, camel-sjms, camel-coap, camel-google-pubsub) allows case-variant header injection", + "affected": "From 3.0.0 before 4.14.6, from 4.15.0 before 4.18.2, from 4.19.0 before 4.20.0.", + "fixed": "4.14.6, 4.18.2 and 4.20.0", + "mitigation": "Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40453.html", + "components": [ + "camel-coap", + "camel-exec", + "camel-file", + "camel-google-pubsub", + "camel-jms", + "camel-sjms" + ] + }, + { + "cve": "CVE-2026-40473", + "date": "2026-04-24T09:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Mina: Unsafe Deserialization in MinaConverter.toObjectInput() via TCP\/UDP", + "affected": "From 3.0.0 before 4.14.6, from 4.15.0 before 4.18.2, from 4.19.0 before 4.20.0.", + "fixed": "4.14.6, 4.18.2 and 4.20.0", + "mitigation": "Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40473.html", + "components": [ + "camel-mina" + ] + }, + { + "cve": "CVE-2026-40858", + "date": "2026-04-24T09:00:00+02:00", + "severity": "HIGH", + "summary": "Camel-Infinispan: Unsafe Deserialization in ProtoStream Remote Aggregation Repository", + "affected": "From 4.0.0 before 4.14.7, from 4.15.0 before 4.18.2, from 4.19.0 before 4.20.0", + "fixed": "4.14.7, 4.18.2 and 4.20.0", + "mitigation": "Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.7. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40858.html", + "components": [ + "camel-infinispan" + ] + }, + { + "cve": "CVE-2026-40859", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Vertx-Http and Camel-Netty-Http: Unsafe Java deserialization of HTTP response bodies via a raw ObjectInputStream when transferException is enabled", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.20.0.", + "fixed": "4.14.8, 4.18.3 and 4.20.0", + "mitigation": "Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, the deserialization performed by both helper utilities is constrained by a default ObjectInputFilter (allow-list java.**;javax.**;org.apache.camel.**;!*), which can be customised through the new deserializationFilter endpoint option or the JVM-wide -Djdk.serialFilter system property. For deployments that cannot upgrade immediately: do not enable transferException=true (or allowJavaSerializedObject=true) on producers that talk to untrusted or network-reachable backends; ensure producer connections use TLS (https) so that a response cannot be substituted by a man-in-the-middle; and, where the option is required, set an explicit -Djdk.serialFilter allow-list (for example java.**;org.apache.camel.**;!*) to constrain deserialization.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40859.html", + "components": [ + "camel-netty-http", + "camel-vertx-http" + ] + }, + { + "cve": "CVE-2026-40860", + "date": "2026-04-24T09:00:00+02:00", + "severity": "HIGH", + "summary": "Unsafe Deserialization of JMS ObjectMessage in camel-jms, camel-sjms, camel-sjms2 and camel-amqp", + "affected": "From 3.0.0 before 4.14.7, from 4.15.0 before 4.18.2, and from 4.19.0 before 4.20.0.", + "fixed": "4.14.7, 4.18.2 and 4.20.0", + "mitigation": "Users are recommended to upgrade to version 4.20.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.7. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.2.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40860.html", + "components": [ + "camel-activemq", + "camel-activemq6", + "camel-amqp", + "camel-jms", + "camel-sjms", + "camel-sjms2" + ] + }, + { + "cve": "CVE-2026-42527", + "date": "2026-04-29T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Permissive default ObjectInputFilter pattern admits java.net.** and enables DNS-based information disclosure", + "affected": "Apache Camel 4.14.0 through 4.14.7 (4.14.x line). Apache Camel 4.18.0 through 4.18.2 (4.18.x line). Apache Camel 4.20.0.", + "fixed": "4.14.8, 4.18.3, 4.21.0.", + "mitigation": "Users are recommended to upgrade to a version that contains the CAMEL-23372 fix once available: 4.21.0 for the 4.21.x line, 4.18.3 for the 4.18.x line, and 4.14.8 for the 4.14.x line. For deployments that cannot upgrade immediately, configure a JMS-provider-side allow-list (Apache ActiveMQ Artemis 'deserializationAllowList' \/ 'deserializationDenyList', Apache ActiveMQ Classic 'org.apache.activemq.SERIALIZABLE_PACKAGES') as the primary mitigation, and\/or override the in-code default via the endpoint-level 'deserializationFilter' option or the JVM-wide '-Djdk.serialFilter' system property with an explicit deny: '!java.net.**;java.**;javax.**;org.apache.camel.**;!*' (or '!java.net.**;java.**;org.apache.camel.**;!*' for the aggregation-repository components, which do not include javax.**).", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-42527.html", + "components": [ + "camel-23372", + "camel-amqp", + "camel-cassandraql", + "camel-consul", + "camel-infinispan", + "camel-jms", + "camel-leveldb", + "camel-mina", + "camel-netty", + "camel-netty-http", + "camel-sjms", + "camel-sql", + "camel-vertx-http" + ] + }, + { + "cve": "CVE-2026-43865", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Hazelcast: Unsafe Java deserialization in default-configured managed Hazelcast instances enables remote code execution", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes Camel apply a default Hazelcast JavaSerializationFilterConfig (whitelisting the java., javax. and org.apache.camel. class-name prefixes and blacklisting java.net.) to instances it creates from its own default configuration, while leaving any user-supplied Config or HazelcastInstance untouched. For deployments that cannot upgrade immediately, configure a deserialization filter on the Hazelcast instance (Hazelcast JavaSerializationFilterConfig, or the JVM-wide system property -Djdk.serialFilter=!java.net.**;java.**;javax.**;org.apache.camel.**;!*) and enable Hazelcast cluster authentication and TLS to restrict who can reach the cluster.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-43865.html", + "components": [ + "camel-hazelcast", + "camel-side" + ] + }, + { + "cve": "CVE-2026-43866", + "date": "2026-07-05T10:00:00+02:00", + "severity": "HIGH", + "summary": "Camel JMS deserialization filter bypass: a forged DefaultExchangeHolder carried in a JMS ObjectMessage passes the CVE-2026-40860 class check and is unmarshalled into the Exchange, letting an attacker who can publish an ObjectMessage inject the message body, headers, exchange properties, variables and exception", + "affected": "From 3.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, JMS ObjectMessage handling is disabled by default in camel-jms, camel-sjms and the JMS-family components (a new objectMessageEnabled option defaults to false at the component and endpoint level), so an incoming ObjectMessage - including a DefaultExchangeHolder payload - is no longer deserialized unless the option is explicitly enabled; only set objectMessageEnabled=true when the consumed JMS destination is fed exclusively by trusted producers. For deployments that cannot upgrade immediately, restrict publish access to the queues and topics consumed by Camel to trusted producers via JMS broker authorization, and do not expose JMS consumers that map ObjectMessage bodies to untrusted networks; a JMS-provider deserialization allow-list does not mitigate this specific bypass because the crafted payload uses only universally-trusted classes.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-43866.html", + "components": [ + "camel-activemq", + "camel-activemq6", + "camel-amqp", + "camel-jms", + "camel-sjms", + "camel-sjms2" + ] + }, + { + "cve": "CVE-2026-43867", + "date": "2026-07-05T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-PQC: The AWS Secrets Manager key-lifecycle manager deserializes persisted key metadata with java.io.ObjectInputStream and no ObjectInputFilter (same defect as CVE-2026-46590, reported independently)", + "affected": "From 4.18.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x LTS releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, restrict write access to the AWS Secrets Manager secret that holds the camel-pqc key metadata so that only the application's own identity holds secretsmanager:PutSecretValue on it (least-privilege IAM), and keep the PQC key material in a secret separate from any data that less-trusted principals can write.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-43867.html", + "components": [ + "camel-23200", + "camel-pqc" + ] + }, + { + "cve": "CVE-2026-45760", + "date": "2026-05-18T09:00:00+02:00", + "severity": "HIGH", + "summary": "Camel K Cross-Namespace Build Deputy Attack", + "affected": "This issue affects Apache Camel K: from 2.0.0 before 2.8.1, from 2.9.0 before 2.9.2, from 2.10.0 before 2.10.1.", + "fixed": "2.8.1, 2.9.2 and 2.10.1", + "mitigation": "Users are recommended to upgrade to version 2.10.1 (or 2.8.1 or 2.9.2), which fixes the issue.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-45760.html" + }, + { + "cve": "CVE-2026-46453", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Elasticsearch-Rest-Client: Exchange header constants without the Camel prefix bypass inbound HTTP header filtering, allowing untrusted clients to override the Elasticsearch query and operation", + "affected": "From 4.3.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix renames the camel-elasticsearch-rest-client Exchange header constant string values (ID, SEARCH_QUERY, INDEX_SETTINGS, INDEX_NAME, OPERATION) to carry the Camel prefix (CamelElasticsearchId, CamelElasticsearchSearchQuery, CamelElasticsearchIndexSettings, CamelElasticsearchIndexName, CamelElasticsearchOperation) so that they are blocked by the inbound HttpHeaderFilterStrategy; the Java field names are unchanged. For deployments that cannot upgrade immediately, strip the affected headers from untrusted inbound messages before they reach the producer (for example removeHeader('SEARCH_QUERY'), removeHeader('OPERATION'), removeHeader('INDEX_NAME'), removeHeader('INDEX_SETTINGS') and removeHeader('ID') in front of the elasticsearch-rest-client endpoint), or apply a custom HeaderFilterStrategy that blocks these names.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46453.html", + "components": [ + "camel-elasticsearch-rest-client" + ] + }, + { + "cve": "CVE-2026-46454", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Cometd: Inbound Bayeux message headers are mapped into the Exchange without a HeaderFilterStrategy, allowing unauthenticated clients to inject Camel control headers", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix implements a HeaderFilterStrategy in the camel-cometd binding (a long-standing TODO in the code) that filters the Camel header namespace case-insensitively on inbound mapping, so client-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from inbound CometD messages before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), and install an explicit Bayeux SecurityPolicy on the CometdComponent so that only authenticated clients can publish.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46454.html", + "components": [ + "camel-cometd", + "camel-internal" + ] + }, + { + "cve": "CVE-2026-46455", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Keycloak: The access-token validity window is not verified because the IS_ACTIVE check is missing from the TokenVerifier, allowing expired tokens to be accepted", + "affected": "From 4.18.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes KeycloakSecurityHelper.parseAndVerifyAccessToken include the TokenVerifier.IS_ACTIVE check so that expired or not-yet-valid access tokens are rejected, aligning the helper with Keycloak's default check set. For deployments that cannot upgrade immediately, enforce token expiration outside the helper - for example validate the access token's exp\/nbf claims in the route before trusting it, keep Keycloak access-token lifetimes short, and ensure any upstream gateway or resource server also validates the token validity window.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46455.html", + "components": [ + "camel-keycloak" + ] + }, + { + "cve": "CVE-2026-46456", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-AWS2-SQS: Inbound message attributes are mapped into the Exchange without an inbound HeaderFilterStrategy, allowing a message sender to inject Camel control headers", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix adds an inbound HeaderFilterStrategy rule to Sqs2HeaderFilterStrategy that filters the Camel header namespace case-insensitively on inbound mapping, so sender-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from inbound messages before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), and restrict who may send to the consumed SQS queue by applying least-privilege sqs:SendMessage permissions on the queue resource policy.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46456.html", + "components": [ + "camel-aws2-sqs", + "camel-internal" + ] + }, + { + "cve": "CVE-2026-46457", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-NATS: Inbound NATS message headers are mapped into the Exchange without a configured HeaderFilterStrategy, allowing a client that can publish to the subject to inject Camel control headers", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes camel-nats default to a dedicated NatsHeaderFilterStrategy that filters the Camel header namespace case-insensitively on inbound mapping, so client-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from inbound NATS messages before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), and enable authentication on the NATS server so that only trusted clients can publish to the consumed subject.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46457.html", + "components": [ + "camel-internal", + "camel-nats" + ] + }, + { + "cve": "CVE-2026-46584", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Mail: The mail producer applied attacker-supplied mail.smtp.* \/ mail.smtps.* message headers as JavaMail session properties, allowing an attacker to weaken the SMTP transport security and, on releases before 4.19.0, redirect the connection and steal the configured SMTP credentials", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, the per-message override is disabled by default; enable it only on trusted endpoints with useJavaMailSessionPropertiesFromHeaders=true. For deployments that cannot upgrade immediately, strip the namespace before the mail producer with removeHeaders('mail.smtp.*') and removeHeaders('mail.smtps.*') between any untrusted ingress and the smtp \/ smtps producer. Even with the opt-in enabled, route authors should still strip the namespace on any path that carries untrusted input.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46584.html", + "components": [ + "camel-internal", + "camel-mail" + ] + }, + { + "cve": "CVE-2026-46585", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Lucene: The query control headers used non-Camel-prefixed names (QUERY, RETURN_LUCENE_DOCS) that bypass the HTTP header filter, allowing an HTTP client to inject the full-text search query", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set the query via the raw header name must use CamelLuceneQuery (and CamelLuceneReturnLuceneDocs) instead of QUERY \/ RETURN_LUCENE_DOCS. For deployments that cannot upgrade immediately, strip the attacker-controllable headers before the Lucene producer and set the query from a trusted source (for example removeHeader('QUERY') and removeHeader('RETURN_LUCENE_DOCS'), then setHeader('QUERY', constant(...)) at the start of the route).", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46585.html", + "components": [ + "camel-lucene", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-46587", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Couchbase: Non-Camel-prefixed Exchange headers bypass HeaderFilterStrategy allowing operation override from untrusted input", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix renames the camel-couchbase Exchange header constant string values (CCB_KEY, CCB_ID, CCB_TTL, CCB_DDN, CCB_VN) to carry the Camel prefix (CamelCouchbaseKey, CamelCouchbaseId, CamelCouchbaseTtl, CamelCouchbaseDesignDocumentName, CamelCouchbaseViewName) so that they are blocked by the inbound HttpHeaderFilterStrategy; the Java constant field names are unchanged. For deployments that cannot upgrade immediately, strip the affected headers from untrusted inbound messages before they reach the producer (for example removeHeader('CCB_KEY'), removeHeader('CCB_ID'), removeHeader('CCB_TTL'), removeHeader('CCB_DDN') and removeHeader('CCB_VN') in front of the couchbase endpoint), or apply a custom HeaderFilterStrategy that blocks these names.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46587.html", + "components": [ + "camel-couchbase", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-46588", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-CouchDB: Non-Camel-prefixed Exchange headers bypass HeaderFilterStrategy allowing operation override from untrusted input", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix renames the camel-couchdb Exchange header constant string values (CouchDbDatabase, CouchDbSeq, CouchDbId, CouchDbRev, CouchDbMethod) to carry the Camel prefix (CamelCouchDbDatabase, CamelCouchDbSeq, CamelCouchDbId, CamelCouchDbRev, CamelCouchDbMethod) so that they are blocked by the inbound HttpHeaderFilterStrategy; the Java constant field names are unchanged. For deployments that cannot upgrade immediately, strip the affected headers from untrusted inbound messages before they reach the producer (for example removeHeader('CouchDbDatabase'), removeHeader('CouchDbId'), removeHeader('CouchDbRev'), removeHeader('CouchDbSeq') and removeHeader('CouchDbMethod') in front of the couchdb endpoint), or apply a custom HeaderFilterStrategy that blocks these names.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46588.html", + "components": [ + "camel-couchdb", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-46590", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-PQC: The HashiCorp Vault and AWS Secrets Manager key-lifecycle managers deserialize persisted key metadata with java.io.ObjectInputStream and no ObjectInputFilter (incomplete remediation of CVE-2026-40048)", + "affected": "From 4.18.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x LTS releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, restrict write access to the key backend so that only the application's own identity can write the camel-pqc secrets (least-privilege HashiCorp Vault policies and secretsmanager:PutSecretValue IAM), and keep the PQC key material in a backend separate from any data that less-trusted principals can write.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46590.html", + "components": [ + "camel-23200", + "camel-pqc" + ] + }, + { + "cve": "CVE-2026-46591", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Neo4j: JSON property names from the CamelNeo4jMatchProperties header are interpolated into the Cypher WHERE clause without validation, allowing Cypher injection (incomplete remediation of CVE-2025-66169)", + "affected": "From 4.10.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, do not populate the CamelNeo4jMatchProperties map from untrusted input: validate or allow-list the property names (for example against ^[A-Za-z_][A-Za-z0-9_]*$) before the Neo4j producer, and ensure that any consumer feeding such a route filters inbound Camel* \/ camel* headers so the match header cannot be supplied by an external sender.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46591.html", + "components": [ + "camel-neo4j", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-46592", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-CXF: The SOAP operation-selection headers used non-Camel-prefixed names (operationName, operationNamespace) that bypass the HTTP header filter, allowing an HTTP client to redirect the invoked SOAP operation", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, the operation-selection headers are named CamelCxfOperationName \/ CamelCxfOperationNamespace and are filtered at transport boundaries; see the 4.21 upgrade guide for the cross-transport carrier-header pattern. For deployments that cannot upgrade immediately, do not select the CXF operation from untrusted input: strip the operationName and operationNamespace headers from any untrusted ingress before the cxf: producer and set the operation from a trusted source in the route.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46592.html", + "components": [ + "camel-cxf", + "camel-cxf-common", + "camel-cxfrs", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-46726", + "date": "2026-07-03T10:00:00+02:00", + "severity": "HIGH", + "summary": "Camel-Vertx-Websocket: The inbound consumer maps externally-supplied WebSocket query and path parameters into the Exchange without a HeaderFilterStrategy, allowing injection of Camel control headers - enabling server-side request forgery and disclosure of secrets when bridged to an HTTP producer", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes the affected consumers apply a HeaderFilterStrategy that filters the Camel header namespace case-insensitively on inbound mapping, so externally-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from the inbound message before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), require authentication on the WebSocket endpoint, and avoid bridging an untrusted consumer directly into an HTTP producer whose target URI can be driven from message headers.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46726.html", + "components": [ + "camel-internal", + "camel-vertx-websocket" + ] + }, + { + "cve": "CVE-2026-47323", + "date": "2026-05-18T09:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-CXF and Camel-Knative Message Header Injection via Missing Inbound Filtering", + "affected": "from 3.18.0 before 4.14.6, from 4.15.0 before 4.18.2, from 4.19.0 before 4.19.0", + "fixed": "4.14.6, 4.18.2 and 4.19.0", + "mitigation": "Users are recommended to upgrade to version 4.19.0, which fixes the issue. If users are on the 4.18.x LTS releases stream, then they are suggested to upgrade to 4.18.2. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.6.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-47323.html", + "components": [ + "camel-cxf", + "camel-cxf-rest", + "camel-cxf-transport", + "camel-exec", + "camel-file", + "camel-internal", + "camel-knative", + "camel-knative-http", + "camel-undertow" + ] + }, + { + "cve": "CVE-2026-48203", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Solr: The SolrParam. and SolrField. Exchange header prefixes used non-Camel-prefixed names that bypass the HTTP header filter, allowing an HTTP client to inject Solr query parameters (server-side request forgery) and document fields", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set Solr parameters or fields via the raw header prefixes must use CamelSolrParam. \/ CamelSolrField. instead of SolrParam. \/ SolrField.. For deployments that cannot upgrade immediately, strip the SolrParam.* and SolrField.* headers from any untrusted ingress before the solr: producer, and set the required Solr parameters and fields from a trusted source in the route.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48203.html", + "components": [ + "camel-prefixed", + "camel-solr" + ] + }, + { + "cve": "CVE-2026-48204", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-MongoDB-GridFS: The gridfs.* control headers used non-Camel-prefixed names that bypass the HTTP header filter, allowing an HTTP client to switch the GridFS operation - including destructive file deletion - in the default configuration", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that drive GridFS operations or metadata via the raw header names must use CamelGridFsOperation \/ CamelGridFsObjectId \/ CamelGridFsMetadata \/ CamelGridFsChunkSize \/ CamelGridFsFileId instead of the gridfs.* names. For deployments that cannot upgrade immediately, set an explicit operation on the mongodb-gridfs: endpoint so the operation is not taken from a header, and strip the gridfs.* headers from any untrusted ingress before the producer.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48204.html", + "components": [ + "camel-mongodb-gridfs", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-48205", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-DNS: The dns.* and term Exchange header constants used non-Camel-prefixed names that bypass the HTTP header filter, allowing an HTTP client to redirect DNS queries to an attacker-controlled server (server-side request forgery) and enumerate internal hostnames", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that drive DNS operations via the raw header names must use CamelDnsServer \/ CamelDnsName \/ CamelDnsDomain \/ CamelDnsType \/ CamelDnsClass \/ CamelDnsTerm instead of the dns.* \/ term names. For deployments that cannot upgrade immediately, strip the dns.* and term headers from any untrusted ingress before the dns: producer, and set the DNS server and lookup parameters from a trusted source in the route.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48205.html", + "components": [ + "camel-dns", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-48206", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-JIRA: A set of non-Camel-prefixed Exchange header constants (IssueKey, ProjectKey, IssueTransitionId, ...) bypass the HTTP header filter, allowing an HTTP client to drive arbitrary JIRA issue operations using the endpoint's configured credentials", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that drive JIRA operations via the raw header names must use the CamelJira* names (for example CamelJiraIssueKey) instead of the old values. For deployments that cannot upgrade immediately, strip the camel-jira control headers from any untrusted ingress before the jira: producer (for example removing the IssueKey, ProjectKey, IssueTransitionId and related headers at the start of the route), and set the required JIRA operation parameters from a trusted source.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48206.html", + "components": [ + "camel-jira", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-49042", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Langchain4j-Tools: Tool argument headers are not filtered against declared parameters, allowing an LLM to inject arbitrary Exchange headers via tool call arguments", + "affected": "From 4.8.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, only tool argument fields that match a declared parameter in the tool specification are set as Exchange headers. Tools defined without parameter declarations will have zero argument headers set from LLM tool calls - this is a breaking change for routes that rely on implicit argument passthrough; to restore argument flow, declare the expected parameters explicitly via the parameter.NAME=TYPE endpoint option. For deployments that cannot upgrade immediately, strip untrusted headers after the tool invocation (for example removeHeaders('Camel*') and removeHeaders('camel*') after the langchain4j-tools endpoint) and declare explicit parameter schemas for every tool so the LLM-returned arguments are constrained.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49042.html", + "components": [ + "camel-internal", + "camel-langchain4j-agent", + "camel-langchain4j-tools", + "camel-spring-ai-tools" + ] + }, + { + "cve": "CVE-2026-49086", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Dapr: The Dapr Pub\/Sub consumer copied the inbound CloudEvent's pub\/sub-name and topic into producer-direction routing headers, allowing an actor who can publish to the subscribed topic to redirect the re-published message to an arbitrary Dapr Pub\/Sub component and topic", + "affected": "From 4.12.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, remove the CamelDaprPubSubName and CamelDaprTopic headers from the Exchange between the Dapr consumer and any Dapr producer in the route (for example removeHeaders('CamelDaprPubSubName', 'CamelDaprTopic')), and restrict who can publish to the subscribed Dapr Pub\/Sub topic so that only trusted producers can send to it.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49086.html", + "components": [ + "camel-dapr" + ] + }, + { + "cve": "CVE-2026-49097", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-IRC: The irc.sendTo (and other irc.*) Exchange header constants used non-Camel-prefixed names that bypass the HTTP header filter, allowing an HTTP client to redirect outgoing IRC messages to arbitrary channels or users", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set IRC headers via the raw header names must use the CamelIrc* names (for example CamelIrcSendTo) instead of the old irc.* values. For deployments that cannot upgrade immediately, strip the irc.* headers from any untrusted ingress before the irc: producer (for example removeHeaders('irc.*') at the start of the route), and set the IRC destination from a trusted source.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49097.html", + "components": [ + "camel-irc", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-49098", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Kafka: The kafka.OVERRIDE_TOPIC (and other kafka.*) Exchange header constants used non-Camel-prefixed names that bypass the upstream HTTP header filter, allowing an HTTP client to redirect Kafka messages to an arbitrary topic", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set or read Kafka headers via the raw header names must use the CamelKafka* names (for example CamelKafkaOverrideTopic and CamelKafkaTopic) instead of the old kafka.* values. For deployments that cannot upgrade immediately, strip the kafka.* headers from any untrusted ingress before the kafka: producer (for example removeHeaders('kafka.*') at the start of the route), and set the target topic from a trusted source.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49098.html", + "components": [ + "camel-kafka", + "camel-prefixed" + ] + }, + { + "cve": "CVE-2026-49099", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Salesforce: Non-Camel-prefixed Exchange header constants (sObjectQuery, sObjectSearch, apexUrl, ...) bypass the HTTP header filter, allowing an HTTP client to inject SOQL\/SOSL queries, override the target SObject, and redirect Apex REST calls using the connected Salesforce user's permissions", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set Salesforce operation parameters via the raw header names must use the CamelSalesforce* names (for example CamelSalesforceSObjectQuery and CamelSalesforceApexUrl) instead of the old sObject* \/ apex* values; the endpoint-option spelling is unchanged. For deployments that cannot upgrade immediately, strip the Salesforce control headers from any untrusted ingress before the salesforce: producer (for example removeHeaders('sObject*') and removeHeaders('apex*') at the start of the route), and set the query, SObject and Apex parameters from a trusted source.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49099.html", + "components": [ + "camel-prefixed", + "camel-salesforce" + ] + }, + { + "cve": "CVE-2026-49365", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Netty-HTTP: The muteException consumer option defaulted to false, so a processing error returned the full Java stack trace in the HTTP response body, disclosing sensitive internal information to unauthenticated clients", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, set muteException=true explicitly on the camel-netty-http consumer (for example netty-http:http:\/\/0.0.0.0:8080\/api?muteException=true, or globally via the camel.component.netty-http.configuration.mute-exception=true property), so that processing errors no longer return the stack trace to the client.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49365.html", + "components": [ + "camel-http", + "camel-jetty", + "camel-netty-http", + "camel-platform-http", + "camel-servlet" + ] + }, + { + "cve": "CVE-2026-53913", + "date": "2026-07-03T10:00:00+02:00", + "severity": "HIGH", + "summary": "Camel-Keycloak: KeycloakSecurityPolicy verifies the bearer access token only inside its role and permission checks, so in the default configuration (no required roles or permissions) the token is never verified and any non-null bearer value is accepted - a fail-open authentication bypass", + "affected": "From 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, configure a non-empty requiredRoles or requiredPermissions on every KeycloakSecurityPolicy so that the token-verification path is exercised, set allowTokenFromHeader to false where the token is not expected from the request header, or perform token verification at the framework layer ahead of the policy.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-53913.html", + "components": [ + "camel-keycloak" + ] + }, + { + "cve": "CVE-2026-55993", + "date": "2026-07-03T10:00:00+02:00", + "severity": "HIGH", + "summary": "Camel-Atmosphere-Websocket: The inbound consumer maps externally-supplied WebSocket query parameters into the Exchange without a HeaderFilterStrategy, allowing injection of Camel control headers - enabling server-side request forgery and disclosure of secrets when bridged to an HTTP producer", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes the consumer apply the HeaderFilterStrategy it already inherits from the HTTP\/servlet stack, filtering the Camel header namespace case-insensitively on inbound mapping, so externally-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from the inbound message before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), require authentication on the WebSocket endpoint, and avoid bridging an untrusted consumer directly into an HTTP producer whose target URI can be driven from message headers.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-55993.html", + "components": [ + "camel-atmosphere-websocket", + "camel-internal" + ] + }, + { + "cve": "CVE-2026-55994", + "date": "2026-07-03T10:00:00+02:00", + "severity": "HIGH", + "summary": "Camel-Iggy: The inbound consumer maps externally-supplied Iggy message user-headers into the Exchange without a HeaderFilterStrategy, allowing injection of Camel control headers - enabling server-side request forgery and disclosure of secrets when bridged to an HTTP producer", + "affected": "From 4.17.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix adds a dedicated IggyHeaderFilterStrategy (and a headerFilterStrategy endpoint option) that filters the Camel header namespace case-insensitively on inbound mapping, so externally-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from the inbound message before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), restrict who can publish to the consumed Iggy stream\/topic, and avoid bridging an untrusted consumer directly into an HTTP producer whose target URI can be driven from message headers.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-55994.html", + "components": [ + "camel-iggy", + "camel-internal" + ] + }, + { + "cve": "CVE-2026-56139", + "date": "2026-07-03T10:00:00+02:00", + "severity": "MEDIUM", + "summary": "Camel-Undertow: The muteException consumer option defaulted to false, so a processing error returned the full Java stack trace in the HTTP response body, disclosing sensitive internal information to unauthenticated clients - and the option was not honoured at all for Rest DSL consumers", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, set muteException=true explicitly on the camel-undertow consumer (for example undertow:http:\/\/0.0.0.0:8080\/api?muteException=true, or globally via the camel.component.undertow.mute-exception=true property), so that processing errors no longer return the stack trace to the client; note that on affected releases this workaround does not cover Rest DSL consumers, whose binding ignores the option until the fix is applied.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-56139.html", + "components": [ + "camel-http", + "camel-jetty", + "camel-platform-http", + "camel-servlet", + "camel-undertow" + ] + }, + { + "cve": "CVE-2026-56140", + "date": "2026-07-03T10:00:00+02:00", + "severity": "LOW", + "summary": "Camel-AWS2-SNS: An inbound Camel-namespace filter was added to Sns2HeaderFilterStrategy to align it with sibling components; because camel-aws2-sns is producer-only (no consumer) there is no reachable inbound header-injection path, so this is a defense-in-depth hardening change related to the camel-aws2-sqs issue CVE-2026-46456", + "affected": "From 4.0.0 before 4.14.8, from 4.15.0 before 4.18.3, from 4.19.0 before 4.21.0.", + "fixed": "4.14.8, 4.18.3 and 4.21.0", + "mitigation": "This is a defense-in-depth hardening change with no known exploit path in camel-aws2-sns, which is producer-only, so no urgent action or workaround is required. Users who want the aligned behaviour can upgrade to version 4.21.0, or to 4.14.8 on the 4.14.x LTS releases stream, or to 4.18.3 on the 4.18.x releases stream, which contain the change. As a general best practice, operators should continue to apply least-privilege IAM permissions on their SNS topics.", + "url": "https:\/\/camel.apache.org\/security\/CVE-2026-56140.html", + "components": [ + "camel-23506", + "camel-aws2-sns", + "camel-aws2-sqs", + "camel-namespace" + ] + } +] diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java index 69a8fa438dbda..2fb23d1150cf2 100644 --- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java +++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java @@ -36,6 +36,7 @@ import org.apache.camel.tooling.model.OtherModel; import org.apache.camel.tooling.model.PojoBeanModel; import org.apache.camel.tooling.model.ReleaseModel; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; import org.apache.camel.tooling.model.TransformerModel; /** @@ -663,6 +664,13 @@ default BaseModel model(Kind kind, String name) { */ List camelQuarkusReleases(); + /** + * Load all published Camel CVE security advisories from catalog (the data behind + * camel.apache.org/security, synced into the catalog when it was + * built). + */ + List camelSecurityAdvisories(); + /** * Checks whether two endpoint URIs refer to the same logical endpoint. *

diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java index 7b71938bba9d6..3425f4f7786a3 100644 --- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java +++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java @@ -47,6 +47,7 @@ import org.apache.camel.tooling.model.OtherModel; import org.apache.camel.tooling.model.PojoBeanModel; import org.apache.camel.tooling.model.ReleaseModel; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; import org.apache.camel.tooling.model.TransformerModel; import org.apache.camel.util.json.JsonArray; import org.apache.camel.util.json.JsonObject; @@ -693,6 +694,25 @@ private List camelReleases(String file) { }); } + @Override + public List camelSecurityAdvisories() { + return cache("camel-security-advisories.json", () -> { + try { + List answer = new ArrayList<>(); + InputStream is = loadResource("advisories", "camel-security-advisories.json"); + String json = CatalogHelper.loadText(is); + JsonArray arr = (JsonArray) Jsoner.deserialize(json); + for (Object o : arr) { + JsonObject jo = (JsonObject) o; + answer.add(JsonMapper.generateSecurityAdvisoryModel(jo)); + } + return answer; + } catch (Exception e) { + return Collections.emptyList(); + } + }); + } + private static boolean matchArtifact(ArtifactModel am, String groupId, String artifactId, String version) { if (am == null) { return false; diff --git a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java index 90f613eafd3b7..8cbd73220d533 100644 --- a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java +++ b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java @@ -37,6 +37,7 @@ import org.apache.camel.tooling.model.LanguageModel; import org.apache.camel.tooling.model.PojoBeanModel; import org.apache.camel.tooling.model.ReleaseModel; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -1752,6 +1753,25 @@ public void camelQuarkusReleases() { Assertions.assertEquals("11", rel.getJdk()); } + @Test + public void camelSecurityAdvisories() { + List list = catalog.camelSecurityAdvisories(); + Assertions.assertTrue(list.size() > 70); + + // oldest advisory first + SecurityAdvisoryModel advisory = list.get(0); + Assertions.assertEquals("CVE-2013-4330", advisory.getCve()); + Assertions.assertEquals("CRITICAL", advisory.getSeverity()); + + advisory = list.stream().filter(a -> a.getCve().equals("CVE-2025-27636")).findFirst().orElse(null); + Assertions.assertNotNull(advisory); + Assertions.assertEquals("MEDIUM", advisory.getSeverity()); + Assertions.assertTrue(advisory.getAffected().contains("4.10.0 before 4.10.2")); + Assertions.assertTrue(advisory.getFixed().contains("4.10.2")); + Assertions.assertEquals("https://camel.apache.org/security/CVE-2025-27636.html", advisory.getUrl()); + Assertions.assertTrue(advisory.getComponents().contains("camel-bean")); + } + @Test public void testFindPojoBeanNames() { List names = catalog.findBeansNames(); diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-mcp.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang-mcp.adoc index 613624b8afe78..1002fcff0566c 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang-mcp.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-mcp.adoc @@ -194,7 +194,8 @@ The assistant discovers components, looks up documentation, builds a YAML route, === Understanding, security, and testing * _"Explain what this route does"_ — uses `camel_route_context` for catalog-enriched analysis -* _"Analyze this route for security concerns"_ — uses `camel_route_harden_context` to detect hardcoded credentials, plain-text protocols, etc. +* _"Analyze this route for security concerns"_ — uses `camel_route_harden_context` to detect hardcoded credentials, plain-text protocols, known CVE advisories, etc. +* _"Is my Camel 4.10.1 project affected by known CVEs?"_ — uses `camel_security_advisories` to match the published Apache Camel security advisories against a Camel version or component * _"Generate a JUnit 5 test for this route"_ — uses `camel_route_test_scaffold` to produce test class with mock endpoints and test-infra stubs === Error diagnosis @@ -366,8 +367,28 @@ plus prompts that provide structured multi-step workflows. | `camel_route_harden_context` | Analyzes a route for security concerns. Identifies security-sensitive components, assigns risk levels, detects issues like hardcoded credentials or plain-text protocols, and returns structured security findings alongside - best practices. -|=== + best practices and the known published CVE advisories affecting the components used by the route at the given + Camel version. + +| `camel_security_advisories` +| Lists the published Apache Camel CVE security advisories (the data behind + https://camel.apache.org/security/[camel.apache.org/security]), optionally filtered by Camel version, component + and severity. Each advisory includes the summary, affected and fixed versions, mitigation, and a best-effort + verdict on whether the given Camel version is affected. Use it to answer questions such as "is my Camel 4.10.1 + project affected by known CVEs?". +|=== + +==== Security advisory data + +The advisory data ships with the Camel catalog bundled in the MCP server, where it is synced from the official +published Apache Camel security advisories (the sources of +https://camel.apache.org/security/[camel.apache.org/security]) when Camel is built — the same way the known +releases are synced. Lookups are therefore fully offline, only published advisories are included, and the data +is as fresh as the Camel version of the MCP server: advisories published after that release are not included, +so check the web page for the very latest. When the catalog carries no advisory data the tools report it as +unavailable rather than returning an empty list, so a missing data set is never mistaken for "no known CVEs". +The advisories are also browseable as MCP resources: `camel://security/advisories` (full list) and +`camel://security/advisory/\{cve}` (detail for one CVE). === Error Diagnosis diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResources.java b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResources.java new file mode 100644 index 0000000000000..a56a1608f4e2d --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResources.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.dsl.jbang.core.commands.mcp; + +import java.util.Optional; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import io.quarkiverse.mcp.server.Resource; +import io.quarkiverse.mcp.server.ResourceTemplate; +import io.quarkiverse.mcp.server.ResourceTemplateArg; +import io.quarkiverse.mcp.server.TextResourceContents; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; + +/** + * MCP Resources exposing the published Apache Camel CVE security advisories from + * camel.apache.org/security (shipped with the Camel catalog). + *

+ * These resources provide browseable advisory data that clients can pull into context independently of route analysis. + * When the catalog carries no advisory data, the resources return an explicit {@code advisoryDataUnavailable} marker + * instead of an empty list, so a missing data set is never mistaken for "no known CVEs". + */ +@ApplicationScoped +public class AdvisoryResources { + + @Inject + AdvisoryService advisoryService; + + /** + * All published security advisories (one summary entry per CVE). + */ + @Resource(uri = "camel://security/advisories", + name = "camel_security_advisories_list", + title = "Published Camel CVE Security Advisories", + description = "List of all published Apache Camel CVE security advisories (the data behind " + + "https://camel.apache.org/security/) with severity, summary, fixed versions and link. " + + "The data ships with the Camel catalog bundled in this MCP server.", + mimeType = "application/json") + public TextResourceContents securityAdvisories() { + JsonObject result = new JsonObject(); + try { + JsonArray advisories = new JsonArray(); + for (SecurityAdvisoryModel advisory : advisoryService.advisories()) { + JsonObject json = new JsonObject(); + json.put("cve", advisory.getCve()); + json.put("severity", advisory.getSeverity()); + json.put("summary", advisory.getSummary()); + json.put("fixed", advisory.getFixed()); + json.put("url", advisory.getUrl()); + advisories.add(json); + } + result.put("advisories", advisories); + result.put("totalCount", advisories.size()); + result.put("source", AdvisoryService.SECURITY_PAGE_URL); + } catch (Exception e) { + result.put("advisoryDataUnavailable", true); + result.put("message", e.getMessage()); + } + return new TextResourceContents("camel://security/advisories", result.toJson(), "application/json"); + } + + /** + * Full detail for a single published security advisory. + */ + @ResourceTemplate(uriTemplate = "camel://security/advisory/{cve}", + name = "camel_security_advisory_detail", + title = "Camel CVE Security Advisory Detail", + description = "Full detail for a single published Apache Camel security advisory (by CVE id, " + + "e.g. CVE-2025-27636) including affected and fixed versions, mitigation and " + + "affected components.", + mimeType = "application/json") + public TextResourceContents securityAdvisoryDetail( + @ResourceTemplateArg(name = "cve") String cve) { + + String uri = "camel://security/advisory/" + cve; + String wanted = cve == null ? "" : cve.trim(); + + JsonObject result = new JsonObject(); + try { + Optional found = advisoryService.advisories().stream() + .filter(advisory -> advisory.getCve().equalsIgnoreCase(wanted)) + .findFirst(); + + if (found.isEmpty()) { + result.put("cve", cve); + result.put("found", false); + result.put("message", "No published Apache Camel security advisory found for '" + cve + "'. " + + "See " + AdvisoryService.SECURITY_PAGE_URL + " for the full list."); + } else { + SecurityAdvisoryModel advisory = found.get(); + result.put("cve", advisory.getCve()); + result.put("found", true); + result.put("severity", advisory.getSeverity()); + result.put("summary", advisory.getSummary()); + result.put("affected", advisory.getAffected()); + result.put("fixed", advisory.getFixed()); + result.put("mitigation", advisory.getMitigation()); + result.put("date", advisory.getDate()); + result.put("url", advisory.getUrl()); + JsonArray components = new JsonArray(); + components.addAll(advisory.getComponents()); + result.put("components", components); + } + } catch (Exception e) { + result.put("advisoryDataUnavailable", true); + result.put("message", e.getMessage()); + } + return new TextResourceContents(uri, result.toJson(), "application/json"); + } +} diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryService.java b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryService.java new file mode 100644 index 0000000000000..ad9ee7ffa3706 --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryService.java @@ -0,0 +1,218 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.dsl.jbang.core.commands.mcp; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import jakarta.enterprise.context.ApplicationScoped; + +import org.apache.camel.catalog.CamelCatalog; +import org.apache.camel.catalog.DefaultCamelCatalog; +import org.apache.camel.dsl.jbang.core.common.VersionHelper; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; + +/** + * Answers queries against the published Apache Camel CVE security advisories (the data behind + * camel.apache.org/security). + *

+ * The advisory data ships with the Camel catalog ({@link CamelCatalog#camelSecurityAdvisories()}), where it is synced + * from the camel-website sources by the {@code update-security-advisories} goal of the camel-package-maven-plugin, the + * same way the known releases are synced. Lookups are therefore fully offline; the data is as fresh as the catalog + * bundled with this MCP server. + *

+ * When the catalog contains no advisory data at all (which cannot happen for a correctly built catalog), the service + * fails with an explicit {@link AdvisoriesUnavailableException} rather than returning an empty result — an empty result + * must never be mistaken for "no known CVEs". + */ +@ApplicationScoped +public class AdvisoryService { + + static final String SECURITY_PAGE_URL = "https://camel.apache.org/security/"; + + private static final Pattern CVE_ID = Pattern.compile("CVE-(\\d{4})-(\\d+)"); + + // Version range grammars used by the advisory "affected" prose, in the order they are consumed: + // "4.10.0 before 4.10.2" / "4.10.0 up to but not including 4.10.2" -> affected range [from, to) + private static final Pattern RANGE_EXCLUSIVE = Pattern.compile( + "(\\d+(?:\\.\\d+){1,3})\\s+(?:before|up to but not including)\\s+(\\d+(?:\\.\\d+){1,3})"); + // "2.9.0 up to 2.9.7" / "2.9.0 through 2.9.7" / "2.9.0 to 2.9.7" -> affected range [from, to] + private static final Pattern RANGE_INCLUSIVE = Pattern.compile( + "(\\d+(?:\\.\\d+){1,3})\\s+(?:up to|through|to)\\s+(\\d+(?:\\.\\d+){1,3})"); + // "prior to 2.24.0" / "before 2.24.0" without a starting version -> everything below is affected + private static final Pattern BELOW = Pattern.compile( + "(?:prior to|before|until)\\s+(\\d+(?:\\.\\d+){1,3})"); + // a remaining bare version is an exactly affected release, e.g. the trailing "2.12.0" in CVE-2013-4330 + private static final Pattern VERSION_TOKEN = Pattern.compile("\\d+(?:\\.\\d+){1,3}"); + + private final CamelCatalog catalog; + + public AdvisoryService() { + this(new DefaultCamelCatalog()); + } + + AdvisoryService(CamelCatalog catalog) { + this.catalog = catalog; + } + + /** + * All published advisories from the catalog bundled with this MCP server. + * + * @throws AdvisoriesUnavailableException when the catalog carries no advisory data + */ + public List advisories() { + List advisories = catalog.camelSecurityAdvisories(); + if (advisories == null || advisories.isEmpty()) { + throw new AdvisoriesUnavailableException( + "Security advisory data is not available in the Camel catalog used by this MCP server. " + + "See " + SECURITY_PAGE_URL + + " for the published advisories."); + } + return advisories; + } + + /** + * Filter advisories and flatten them to {@link AdvisoryView}, newest first. When {@code camelVersion} is given, + * advisories whose parsed affected ranges exclude that version are dropped; advisories whose ranges could not be + * parsed are kept with {@code affectsGivenVersion} unset so the caller can judge from the {@code affected} prose. + */ + static List query( + List advisories, String camelVersion, String component, String severity) { + List result = new ArrayList<>(); + for (SecurityAdvisoryModel advisory : advisories) { + if (!matchesComponent(advisory, component) || !matchesSeverity(advisory, severity)) { + continue; + } + AdvisoryView view = AdvisoryView.of(advisory, camelVersion); + if (Boolean.FALSE.equals(view.affectsGivenVersion())) { + continue; + } + result.add(view); + } + result.sort(Comparator.comparingLong((AdvisoryView view) -> cveOrdinal(view.cve())).reversed()); + return result; + } + + /** + * Whether the advisory names the given component (with or without the {@code camel-} prefix). Best-effort: the + * match is against the components named by the advisory text, and some (mostly older) advisories do not name + * components at all. + */ + static boolean matchesComponent(SecurityAdvisoryModel advisory, String component) { + if (component == null || component.isBlank()) { + return true; + } + String name = component.trim().toLowerCase(Locale.ROOT); + if (!name.startsWith("camel-")) { + name = "camel-" + name; + } + return advisory.getComponents() != null && advisory.getComponents().contains(name); + } + + static boolean matchesSeverity(SecurityAdvisoryModel advisory, String severity) { + if (severity == null || severity.isBlank()) { + return true; + } + return advisory.getSeverity() != null && advisory.getSeverity().equalsIgnoreCase(severity.trim()); + } + + /** + * Best-effort verdict on whether the given Camel version falls inside the affected ranges stated by the advisory + * {@code affected} prose. Returns {@code null} when the prose contains no parseable version ranges — the caller + * must then fall back to the prose itself. + */ + static Boolean affectsVersion(String affected, String version) { + if (affected == null || affected.isBlank() || version == null || version.isBlank()) { + return null; + } + // strip qualifiers such as -SNAPSHOT or vendor suffixes before comparing + String plainVersion = version.trim(); + int dash = plainVersion.indexOf('-'); + if (dash > 0) { + plainVersion = plainVersion.substring(0, dash); + } + + boolean parsedAny = false; + boolean affectedHit = false; + String text = affected; + + Matcher matcher = RANGE_EXCLUSIVE.matcher(text); + while (matcher.find()) { + parsedAny = true; + affectedHit |= VersionHelper.isBetween(plainVersion, matcher.group(1), matcher.group(2)); + } + text = matcher.replaceAll(" "); + + matcher = RANGE_INCLUSIVE.matcher(text); + while (matcher.find()) { + parsedAny = true; + affectedHit |= VersionHelper.isGE(plainVersion, matcher.group(1)) + && VersionHelper.isLE(plainVersion, matcher.group(2)); + } + text = matcher.replaceAll(" "); + + matcher = BELOW.matcher(text); + while (matcher.find()) { + parsedAny = true; + affectedHit |= VersionHelper.compare(plainVersion, matcher.group(1)) < 0; + } + text = matcher.replaceAll(" "); + + matcher = VERSION_TOKEN.matcher(text); + while (matcher.find()) { + parsedAny = true; + affectedHit |= VersionHelper.compare(plainVersion, matcher.group()) == 0 + && plainVersion.length() == matcher.group().length(); + } + + return parsedAny ? affectedHit : null; + } + + private static long cveOrdinal(String cve) { + Matcher matcher = CVE_ID.matcher(cve == null ? "" : cve); + if (matcher.find()) { + return Long.parseLong(matcher.group(1)) * 1_000_000L + Long.parseLong(matcher.group(2)); + } + return 0; + } + + /** Flattened advisory returned by MCP tools, with the optional per-version verdict. */ + public record AdvisoryView( + String cve, String severity, String summary, String affected, String fixed, + String mitigation, String url, List components, Boolean affectsGivenVersion) { + + static AdvisoryView of(SecurityAdvisoryModel advisory, String camelVersion) { + Boolean affects = camelVersion == null || camelVersion.isBlank() + ? null : affectsVersion(advisory.getAffected(), camelVersion); + return new AdvisoryView( + advisory.getCve(), advisory.getSeverity(), advisory.getSummary(), advisory.getAffected(), + advisory.getFixed(), advisory.getMitigation(), advisory.getUrl(), advisory.getComponents(), + affects); + } + } + + /** Signals that the catalog used by this MCP server carries no advisory data. */ + public static class AdvisoriesUnavailableException extends RuntimeException { + public AdvisoriesUnavailableException(String message) { + super(message); + } + } +} diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java new file mode 100644 index 0000000000000..68f2703ffbffd --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.dsl.jbang.core.commands.mcp; + +import java.util.List; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import io.quarkiverse.mcp.server.Tool; +import io.quarkiverse.mcp.server.ToolArg; +import io.quarkiverse.mcp.server.ToolCallException; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; + +/** + * MCP Tool exposing the published Apache Camel CVE security advisories from + * camel.apache.org/security (shipped with the Camel catalog). + *

+ * Lets an LLM answer questions such as "is my Camel 4.10.1 project affected by known CVEs?" or "which CVEs were + * published for camel-kafka and in which versions are they fixed?". + */ +@ApplicationScoped +public class AdvisoryTools { + + @Inject + AdvisoryService advisoryService; + + @Tool(annotations = @Tool.Annotations(readOnlyHint = true, destructiveHint = false, openWorldHint = false), + description = "List published Apache Camel CVE security advisories (the data behind " + + "https://camel.apache.org/security/), optionally filtered by Camel version, component and " + + "severity. When camelVersion is set, advisories whose parsed affected ranges exclude that " + + "version are dropped; advisories whose ranges cannot be parsed are kept with " + + "affectsGivenVersion unset - judge those from the 'affected' text. The advisory data ships " + + "with the Camel catalog (synced from the published advisories when Camel is released), so " + + "advisories published after this Camel version was released are not included - check the " + + "web page for the very latest.") + public AdvisoriesResult camel_security_advisories( + @ToolArg(description = "Camel version to check, e.g. 4.10.1 (optional)") String camelVersion, + @ToolArg(description = "Component to filter by, e.g. kafka or camel-kafka (optional; best-effort match " + + "against components named in the advisory text - older advisories may not name " + + "components)") String component, + @ToolArg(description = "Severity to filter by as published, e.g. LOW, MEDIUM, MODERATE, IMPORTANT or " + + "CRITICAL (optional)") String severity) { + try { + List advisories = advisoryService.advisories(); + List matches + = AdvisoryService.query(advisories, camelVersion, component, severity); + return new AdvisoriesResult( + AdvisoryService.SECURITY_PAGE_URL, + advisories.size(), + matches.size(), + blankToNull(camelVersion), + blankToNull(component), + blankToNull(severity), + matches); + } catch (AdvisoryService.AdvisoriesUnavailableException e) { + throw new ToolCallException(e.getMessage(), e); + } catch (ToolCallException e) { + throw e; + } catch (Throwable e) { + throw new ToolCallException( + "Failed to load security advisories (" + e.getClass().getName() + "): " + e.getMessage(), null); + } + } + + private static String blankToNull(String value) { + return value == null || value.isBlank() ? null : value.trim(); + } + + // Result records + + public record AdvisoriesResult( + String source, int totalPublished, int matched, String camelVersion, String component, String severity, + List advisories) { + } +} diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java index 22116be69e33c..ef7768dcc4fa8 100644 --- a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java +++ b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenTools.java @@ -17,7 +17,11 @@ package org.apache.camel.dsl.jbang.core.commands.mcp; import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -27,6 +31,7 @@ import io.quarkiverse.mcp.server.ToolCallException; import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.tooling.model.ComponentModel; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; /** * MCP Tool for providing security hardening context and analysis for Camel routes. @@ -37,20 +42,28 @@ @ApplicationScoped public class HardenTools { + /** Upper bound of known-CVE advisories embedded in the hardening context to keep the response focused. */ + private static final int MAX_ADVISORIES = 20; + @Inject CatalogService catalogService; @Inject SecurityData securityData; + @Inject + AdvisoryService advisoryService; + /** * Tool to get security hardening context for a Camel route. */ @Tool(annotations = @Tool.Annotations(readOnlyHint = true, destructiveHint = false, openWorldHint = false), description = "Get security hardening analysis context for a Camel route. " + "Returns security-sensitive components, potential vulnerabilities, " + - "and security best practices. Use this context to provide security " + - "hardening recommendations for the route.") + "security best practices, and known published CVE advisories affecting " + + "the components used by the route at the given Camel version (advisory data " + + "from https://camel.apache.org/security/ shipped with the Camel catalog). " + + "Use this context to provide security hardening recommendations for the route.") public HardenContextResult camel_route_harden_context( @ToolArg(description = "The Camel route content (YAML, XML, or Java DSL)") String route, @ToolArg(description = "Route format: yaml, xml, or java (default: yaml)") String format, @@ -85,6 +98,27 @@ public HardenContextResult camel_route_harden_context( // Best practices List bestPractices = List.copyOf(securityData.getBestPractices()); + // Known published CVE advisories affecting the components used by the route. + // Failures here must degrade to a note, never break the hardening analysis. + List knownAdvisories = null; + String advisoriesNote = null; + try { + String effectiveVersion = camelVersion != null && !camelVersion.isBlank() + ? camelVersion : catalog.getCatalogVersion(); + knownAdvisories = matchAdvisories( + advisoryService.advisories(), catalog, securityComponentNames, effectiveVersion); + if (knownAdvisories.size() > MAX_ADVISORIES) { + advisoriesNote = "Showing " + MAX_ADVISORIES + " of " + knownAdvisories.size() + + " matched advisories; use the camel_security_advisories tool for the full list."; + knownAdvisories = knownAdvisories.subList(0, MAX_ADVISORIES); + } + if (knownAdvisories.isEmpty()) { + knownAdvisories = null; + } + } catch (Exception e) { + advisoriesNote = "Known-CVE advisory check skipped: " + e.getMessage(); + } + // Summary HardenSummary summary = new HardenSummary( securityComponents.size(), @@ -95,7 +129,8 @@ public HardenContextResult camel_route_harden_context( usesTLS(route), hasAuthentication(route)); return new HardenContextResult( - resolvedFormat, route, securityComponents, securityAnalysis, bestPractices, summary); + resolvedFormat, route, securityComponents, securityAnalysis, bestPractices, + knownAdvisories, advisoriesNote, summary); } catch (ToolCallException e) { throw e; } catch (Throwable e) { @@ -120,6 +155,34 @@ private List extractSecurityComponents(String route) { return found; } + /** + * Match published CVE advisories against the components used by the route, keeping only advisories that affect the + * given Camel version (advisories whose affected ranges cannot be parsed are kept for the LLM to judge). Components + * are matched by Maven artifact id where the catalog knows it (e.g. scheme {@code https} maps to + * {@code camel-http}), with the scheme-derived {@code camel-} as fallback. + */ + private List matchAdvisories( + List advisories, CamelCatalog catalog, + List componentNames, String camelVersion) { + + Set artifacts = new LinkedHashSet<>(); + for (String name : componentNames) { + ComponentModel model = catalog.componentModel(name); + if (model != null && model.getArtifactId() != null) { + artifacts.add(model.getArtifactId()); + } + artifacts.add("camel-" + name); + } + + Map byCve = new LinkedHashMap<>(); + for (String artifact : artifacts) { + for (AdvisoryService.AdvisoryView view : AdvisoryService.query(advisories, camelVersion, artifact, null)) { + byCve.putIfAbsent(view.cve(), view); + } + } + return new ArrayList<>(byCve.values()); + } + /** * Analyze security concerns in the route. */ @@ -282,6 +345,7 @@ private boolean hasAuthentication(String route) { public record HardenContextResult( String format, String route, List securitySensitiveComponents, SecurityAnalysis securityAnalysis, List securityBestPractices, + List knownSecurityAdvisories, String advisoriesNote, HardenSummary summary) { } diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResourcesTest.java b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResourcesTest.java new file mode 100644 index 0000000000000..2953aacbf0c7b --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryResourcesTest.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.dsl.jbang.core.commands.mcp; + +import io.quarkiverse.mcp.server.TextResourceContents; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; +import org.apache.camel.util.json.Jsoner; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for the {@code camel://security/advisories} MCP resources, backed by the advisory data shipped with the Camel + * catalog. Fully offline. + */ +class AdvisoryResourcesTest { + + private AdvisoryResources resources() { + AdvisoryResources resources = new AdvisoryResources(); + resources.advisoryService = new AdvisoryService(); + return resources; + } + + @Test + void advisoriesListReturnsValidJson() throws Exception { + TextResourceContents contents = resources().securityAdvisories(); + + assertThat(contents.uri()).isEqualTo("camel://security/advisories"); + assertThat(contents.mimeType()).isEqualTo("application/json"); + + JsonObject result = (JsonObject) Jsoner.deserialize(contents.text()); + assertThat(result.getInteger("totalCount")).isGreaterThan(70); + assertThat(result.getString("source")).isEqualTo("https://camel.apache.org/security/"); + assertThat(result.containsKey("advisoryDataUnavailable")).isFalse(); + + JsonArray advisories = result.getCollection("advisories"); + JsonObject known = null; + for (Object o : advisories) { + JsonObject json = (JsonObject) o; + if ("CVE-2025-27636".equals(json.getString("cve"))) { + known = json; + } + } + assertThat(known).isNotNull(); + assertThat(known.getString("severity")).isEqualTo("MEDIUM"); + assertThat(known.getString("fixed")).contains("4.10.2"); + assertThat(known.getString("url")).isEqualTo("https://camel.apache.org/security/CVE-2025-27636.html"); + } + + @Test + void advisoryDetailReturnsAllFields() throws Exception { + TextResourceContents contents = resources().securityAdvisoryDetail("CVE-2013-4330"); + + JsonObject result = (JsonObject) Jsoner.deserialize(contents.text()); + assertThat(result.getBoolean("found")).isTrue(); + assertThat(result.getString("cve")).isEqualTo("CVE-2013-4330"); + assertThat(result.getString("severity")).isEqualTo("CRITICAL"); + assertThat(result.getString("affected")).contains("2.9.0 up to 2.9.7"); + assertThat(result.getString("fixed")).contains("2.12.1"); + assertThat(result.getString("mitigation")).isNotBlank(); + assertThat(result.getString("date")).isNotBlank(); + } + + @Test + void advisoryDetailIsCaseInsensitive() throws Exception { + TextResourceContents contents = resources().securityAdvisoryDetail("cve-2025-27636"); + + JsonObject result = (JsonObject) Jsoner.deserialize(contents.text()); + assertThat(result.getBoolean("found")).isTrue(); + JsonArray components = result.getCollection("components"); + assertThat(components).contains("camel-bean", "camel-undertow"); + } + + @Test + void advisoryDetailReportsUnknownCve() throws Exception { + TextResourceContents contents = resources().securityAdvisoryDetail("CVE-1999-0001"); + + JsonObject result = (JsonObject) Jsoner.deserialize(contents.text()); + assertThat(result.getBoolean("found")).isFalse(); + assertThat(result.getString("message")).contains("No published Apache Camel security advisory"); + } + + @Test + void unavailableAdvisoryDataIsExplicitNotEmpty() throws Exception { + AdvisoryResources resources = new AdvisoryResources(); + resources.advisoryService = AdvisoryServiceTest.unavailableService(); + + JsonObject list = (JsonObject) Jsoner.deserialize(resources.securityAdvisories().text()); + assertThat(list.getBoolean("advisoryDataUnavailable")).isTrue(); + assertThat(list.containsKey("advisories")).isFalse(); + + JsonObject detail = (JsonObject) Jsoner.deserialize(resources.securityAdvisoryDetail("CVE-2025-27636").text()); + assertThat(detail.getBoolean("advisoryDataUnavailable")).isTrue(); + } +} diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryServiceTest.java b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryServiceTest.java new file mode 100644 index 0000000000000..7403951be7f09 --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryServiceTest.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.dsl.jbang.core.commands.mcp; + +import java.util.List; + +import org.apache.camel.catalog.DefaultCamelCatalog; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests for {@link AdvisoryService}: loading the published advisories from the Camel catalog, the best-effort affected + * version matching, and the query filtering. Fully offline - the advisory data ships with camel-catalog. + */ +class AdvisoryServiceTest { + + /** Builds a synthetic advisory for deterministic filter tests. */ + static SecurityAdvisoryModel advisory(String cve, String severity, String affected, String... components) { + SecurityAdvisoryModel model = new SecurityAdvisoryModel(); + model.setCve(cve); + model.setSeverity(severity); + model.setAffected(affected); + model.setSummary("Synthetic advisory " + cve); + model.setFixed("n/a"); + model.setUrl("https://camel.apache.org/security/" + cve + ".html"); + model.getComponents().addAll(List.of(components)); + return model; + } + + /** An {@link AdvisoryService} whose catalog carries no advisory data. */ + static AdvisoryService unavailableService() { + return new AdvisoryService(new DefaultCamelCatalog() { + @Override + public List camelSecurityAdvisories() { + return List.of(); + } + }); + } + + // ---- loading from the catalog ---- + + @Test + void loadsPublishedAdvisoriesFromCatalog() { + List advisories = new AdvisoryService().advisories(); + + assertThat(advisories.size()).isGreaterThan(70); + + SecurityAdvisoryModel known = advisories.stream() + .filter(a -> "CVE-2025-27636".equals(a.getCve())) + .findFirst().orElse(null); + assertThat(known).isNotNull(); + assertThat(known.getSeverity()).isEqualTo("MEDIUM"); + assertThat(known.getAffected()).contains("4.10.0 before 4.10.2"); + assertThat(known.getFixed()).contains("4.10.2"); + assertThat(known.getUrl()).isEqualTo("https://camel.apache.org/security/CVE-2025-27636.html"); + assertThat(known.getComponents()).contains("camel-bean", "camel-undertow", "camel-kafka"); + } + + @Test + void emptyCatalogDataFailsExplicitly() { + assertThatThrownBy(() -> unavailableService().advisories()) + .isInstanceOf(AdvisoryService.AdvisoriesUnavailableException.class) + .hasMessageContaining("not available"); + } + + // ---- affected version matching ---- + + @Test + void affectsVersionWithExclusiveRanges() { + String affected = "Apache Camel 4.10.0 before 4.10.2. Apache Camel 4.8.0 before 4.8.5. " + + "Apache Camel 3.10.0 before 3.22.4."; + + assertThat(AdvisoryService.affectsVersion(affected, "4.10.1")).isTrue(); + assertThat(AdvisoryService.affectsVersion(affected, "4.10.0")).isTrue(); + assertThat(AdvisoryService.affectsVersion(affected, "4.8.4")).isTrue(); + assertThat(AdvisoryService.affectsVersion(affected, "3.15.0")).isTrue(); + + assertThat(AdvisoryService.affectsVersion(affected, "4.10.2")).isFalse(); + assertThat(AdvisoryService.affectsVersion(affected, "4.8.5")).isFalse(); + assertThat(AdvisoryService.affectsVersion(affected, "4.11.0")).isFalse(); + assertThat(AdvisoryService.affectsVersion(affected, "3.22.4")).isFalse(); + } + + @Test + void affectsVersionWithInclusiveRangesAndBareVersion() { + // the affected style used by the old advisories, e.g. CVE-2013-4330 + String affected = "2.9.0 up to 2.9.7, 2.10.0 up to 2.10.6, 2.11.0 up to 2.11.1, 2.12.0"; + + assertThat(AdvisoryService.affectsVersion(affected, "2.9.0")).isTrue(); + assertThat(AdvisoryService.affectsVersion(affected, "2.9.7")).isTrue(); + assertThat(AdvisoryService.affectsVersion(affected, "2.12.0")).isTrue(); + + assertThat(AdvisoryService.affectsVersion(affected, "2.9.8")).isFalse(); + assertThat(AdvisoryService.affectsVersion(affected, "2.12.1")).isFalse(); + assertThat(AdvisoryService.affectsVersion(affected, "2.8.0")).isFalse(); + } + + @Test + void affectsVersionStripsQualifierSuffix() { + String affected = "Apache Camel 4.10.0 before 4.10.2."; + + assertThat(AdvisoryService.affectsVersion(affected, "4.10.1-SNAPSHOT")).isTrue(); + assertThat(AdvisoryService.affectsVersion(affected, "4.10.2-SNAPSHOT")).isFalse(); + } + + @Test + void affectsVersionIsNullWhenNotParseable() { + assertThat(AdvisoryService.affectsVersion("All versions of Apache Camel", "4.10.1")).isNull(); + assertThat(AdvisoryService.affectsVersion(null, "4.10.1")).isNull(); + assertThat(AdvisoryService.affectsVersion(" ", "4.10.1")).isNull(); + assertThat(AdvisoryService.affectsVersion("Apache Camel 4.10.0 before 4.10.2.", null)).isNull(); + assertThat(AdvisoryService.affectsVersion("Apache Camel 4.10.0 before 4.10.2.", " ")).isNull(); + } + + // ---- query filtering ---- + + @Test + void queryFiltersByComponentSeverityAndVersion() { + List advisories = List.of( + advisory("CVE-2013-4330", "CRITICAL", "2.9.0 up to 2.9.7, 2.12.0"), + advisory("CVE-2025-27636", "MEDIUM", "Apache Camel 4.10.0 before 4.10.2.", "camel-bean", + "camel-undertow")); + + // no filters: everything, newest first, no version verdict + List views = AdvisoryService.query(advisories, null, null, null); + assertThat(views).hasSize(2); + assertThat(views.get(0).cve()).isEqualTo("CVE-2025-27636"); + assertThat(views.get(0).affectsGivenVersion()).isNull(); + + // component filter accepts both bare and camel- prefixed names + assertThat(AdvisoryService.query(advisories, null, "bean", null)).hasSize(1); + assertThat(AdvisoryService.query(advisories, null, "camel-bean", null)).hasSize(1); + assertThat(AdvisoryService.query(advisories, null, "does-not-exist", null)).isEmpty(); + + // severity filter is case-insensitive + assertThat(AdvisoryService.query(advisories, null, null, "medium")).hasSize(1); + assertThat(AdvisoryService.query(advisories, null, null, "CRITICAL")).hasSize(1); + assertThat(AdvisoryService.query(advisories, null, null, "IMPORTANT")).isEmpty(); + + // version filter drops advisories whose parsed ranges exclude the version + List affected = AdvisoryService.query(advisories, "4.10.1", null, null); + assertThat(affected).hasSize(1); + assertThat(affected.get(0).cve()).isEqualTo("CVE-2025-27636"); + assertThat(affected.get(0).affectsGivenVersion()).isTrue(); + + assertThat(AdvisoryService.query(advisories, "4.10.2", null, null)).isEmpty(); + assertThat(AdvisoryService.query(advisories, "2.12.0", null, null)) + .singleElement() + .satisfies(view -> assertThat(view.cve()).isEqualTo("CVE-2013-4330")); + } + + @Test + void queryKeepsAdvisoriesWithUnparseableRanges() { + List advisories + = List.of(advisory("CVE-2099-11111", "MEDIUM", "All versions", "camel-bar")); + + List views = AdvisoryService.query(advisories, "4.10.1", null, null); + + assertThat(views).hasSize(1); + assertThat(views.get(0).affectsGivenVersion()).isNull(); + } +} diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryToolsTest.java b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryToolsTest.java new file mode 100644 index 0000000000000..034c7025bb90f --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryToolsTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.dsl.jbang.core.commands.mcp; + +import io.quarkiverse.mcp.server.ToolCallException; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests for the {@code camel_security_advisories} MCP tool, backed by the advisory data shipped with the Camel catalog. + * Fully offline. + */ +class AdvisoryToolsTest { + + private AdvisoryTools tools() { + AdvisoryTools tools = new AdvisoryTools(); + tools.advisoryService = new AdvisoryService(); + return tools; + } + + @Test + void listsAllPublishedAdvisoriesWithoutFilters() { + AdvisoryTools.AdvisoriesResult result = tools().camel_security_advisories(null, null, null); + + assertThat(result.totalPublished()).isGreaterThan(70); + assertThat(result.matched()).isEqualTo(result.totalPublished()); + assertThat(result.source()).isEqualTo("https://camel.apache.org/security/"); + // newest first: the very first published Camel advisory comes last + assertThat(result.advisories().get(result.advisories().size() - 1).cve()).isEqualTo("CVE-2013-4330"); + assertThat(result.advisories().get(0).affectsGivenVersion()).isNull(); + } + + @Test + void filtersByVersionComponentAndSeverity() { + AdvisoryTools.AdvisoriesResult result = tools().camel_security_advisories("4.10.1", "bean", "MEDIUM"); + + assertThat(result.camelVersion()).isEqualTo("4.10.1"); + assertThat(result.component()).isEqualTo("bean"); + assertThat(result.severity()).isEqualTo("MEDIUM"); + assertThat(result.matched()).isGreaterThanOrEqualTo(1); + + AdvisoryService.AdvisoryView view = result.advisories().stream() + .filter(a -> "CVE-2025-27636".equals(a.cve())) + .findFirst().orElse(null); + assertThat(view).isNotNull(); + assertThat(view.affectsGivenVersion()).isTrue(); + assertThat(view.fixed()).contains("4.10.2"); + assertThat(view.mitigation()).isNotBlank(); + } + + @Test + void blankArgumentsAreTreatedAsNoFilter() { + AdvisoryTools.AdvisoriesResult result = tools().camel_security_advisories(" ", "", " "); + + assertThat(result.matched()).isEqualTo(result.totalPublished()); + assertThat(result.camelVersion()).isNull(); + assertThat(result.component()).isNull(); + assertThat(result.severity()).isNull(); + } + + @Test + void unavailableAdvisoryDataThrowsExplicitToolError() { + AdvisoryTools tools = new AdvisoryTools(); + tools.advisoryService = AdvisoryServiceTest.unavailableService(); + + assertThatThrownBy(() -> tools.camel_security_advisories(null, null, null)) + .isInstanceOf(ToolCallException.class) + .hasMessageContaining("not available"); + } +} diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenToolsAdvisoryTest.java b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenToolsAdvisoryTest.java new file mode 100644 index 0000000000000..896c4e1176595 --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/HardenToolsAdvisoryTest.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.dsl.jbang.core.commands.mcp; + +import java.util.List; + +import org.apache.camel.tooling.model.SecurityAdvisoryModel; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests the known-CVE advisory integration of the {@code camel_route_harden_context} tool: matched advisories are + * embedded in the hardening context, unaffected versions report nothing, and advisory lookup failures degrade to a note + * without breaking the hardening analysis. + */ +class HardenToolsAdvisoryTest { + + private static final String KAFKA_ROUTE = """ + - route: + from: + uri: kafka:orders + steps: + - to: log:done + """; + + private HardenTools hardenTools(AdvisoryService advisoryService) { + HardenTools tools = new HardenTools(); + tools.catalogService = new CatalogService(); + tools.securityData = new SecurityData(); + tools.advisoryService = advisoryService; + return tools; + } + + private static AdvisoryService stubService(SecurityAdvisoryModel... advisories) { + return new AdvisoryService() { + @Override + public List advisories() { + return List.of(advisories); + } + }; + } + + @Test + void matchedAdvisoriesAreEmbeddedInHardenContext() { + // an advisory naming camel-kafka whose affected range cannot be parsed is kept for the LLM to judge + AdvisoryService stub = stubService( + AdvisoryServiceTest.advisory("CVE-2099-11111", "MEDIUM", "All versions", "camel-kafka"), + AdvisoryServiceTest.advisory("CVE-2099-22222", "HIGH", "All versions", "camel-ftp")); + + HardenTools.HardenContextResult result = hardenTools(stub) + .camel_route_harden_context(KAFKA_ROUTE, "yaml", null, null, null); + + assertThat(result.knownSecurityAdvisories()).hasSize(1); + assertThat(result.knownSecurityAdvisories().get(0).cve()).isEqualTo("CVE-2099-11111"); + assertThat(result.knownSecurityAdvisories().get(0).affectsGivenVersion()).isNull(); + assertThat(result.advisoriesNote()).isNull(); + } + + @Test + void unaffectedVersionReportsNoAdvisories() { + // the advisory affected range excludes the current catalog version, so nothing is reported + AdvisoryService stub = stubService( + AdvisoryServiceTest.advisory("CVE-2025-27636", "MEDIUM", + "Apache Camel 4.10.0 before 4.10.2.", "camel-kafka")); + + HardenTools.HardenContextResult result = hardenTools(stub) + .camel_route_harden_context(KAFKA_ROUTE, "yaml", null, null, null); + + assertThat(result.knownSecurityAdvisories()).isNull(); + assertThat(result.advisoriesNote()).isNull(); + } + + @Test + void advisoryLookupFailureDegradesToNote() { + HardenTools.HardenContextResult result = hardenTools(AdvisoryServiceTest.unavailableService()) + .camel_route_harden_context(KAFKA_ROUTE, "yaml", null, null, null); + + assertThat(result).isNotNull(); + assertThat(result.knownSecurityAdvisories()).isNull(); + assertThat(result.advisoriesNote()).contains("Known-CVE advisory check skipped"); + // the hardening analysis itself is unaffected by the advisory failure + assertThat(result.securitySensitiveComponents()).extracting(HardenTools.SecurityComponent::name) + .contains("kafka"); + } +} diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java index 1f8d15deb97ef..40723b4e4acbe 100644 --- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java +++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java @@ -1053,6 +1053,55 @@ public static ReleaseModel generateReleaseModel(JsonObject obj) { return model; } + public static JsonObject asJsonObject(SecurityAdvisoryModel model) { + JsonObject json = new JsonObject(); + json.put("cve", model.getCve()); + if (model.getDate() != null) { + json.put("date", model.getDate()); + } + if (model.getSeverity() != null) { + json.put("severity", model.getSeverity()); + } + if (model.getSummary() != null) { + json.put("summary", model.getSummary()); + } + if (model.getAffected() != null) { + json.put("affected", model.getAffected()); + } + if (model.getFixed() != null) { + json.put("fixed", model.getFixed()); + } + if (model.getMitigation() != null) { + json.put("mitigation", model.getMitigation()); + } + if (model.getUrl() != null) { + json.put("url", model.getUrl()); + } + if (model.getComponents() != null && !model.getComponents().isEmpty()) { + json.put("components", new JsonArray(model.getComponents())); + } + return json; + } + + public static SecurityAdvisoryModel generateSecurityAdvisoryModel(JsonObject obj) { + SecurityAdvisoryModel model = new SecurityAdvisoryModel(); + model.setCve(obj.getString("cve")); + model.setDate(obj.getString("date")); + model.setSeverity(obj.getString("severity")); + model.setSummary(obj.getString("summary")); + model.setAffected(obj.getString("affected")); + model.setFixed(obj.getString("fixed")); + model.setMitigation(obj.getString("mitigation")); + model.setUrl(obj.getString("url")); + JsonArray components = (JsonArray) obj.get("components"); + if (components != null) { + for (Object component : components) { + model.getComponents().add(String.valueOf(component)); + } + } + return model; + } + public static String createJsonSchema(MainModel model) { JsonObject wrapper = asJsonObject(model); return serialize(wrapper); diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/SecurityAdvisoryModel.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/SecurityAdvisoryModel.java new file mode 100644 index 0000000000000..62f8632dd3b41 --- /dev/null +++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/SecurityAdvisoryModel.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.tooling.model; + +import java.util.ArrayList; +import java.util.List; + +/** + * A published Apache Camel CVE security advisory, as listed on + * camel.apache.org/security. + */ +public class SecurityAdvisoryModel { + + protected String cve; + protected String date; + protected String severity; + protected String summary; + protected String affected; + protected String fixed; + protected String mitigation; + protected String url; + protected List components = new ArrayList<>(); + + public String getCve() { + return cve; + } + + public void setCve(String cve) { + this.cve = cve; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + /** + * The affected Camel versions as stated by the advisory, e.g. "Apache Camel 4.10.0 before 4.10.2". + */ + public String getAffected() { + return affected; + } + + public void setAffected(String affected) { + this.affected = affected; + } + + /** + * The Camel versions that fix the vulnerability. + */ + public String getFixed() { + return fixed; + } + + public void setFixed(String fixed) { + this.fixed = fixed; + } + + public String getMitigation() { + return mitigation; + } + + public void setMitigation(String mitigation) { + this.mitigation = mitigation; + } + + /** + * Link to the published advisory page. + */ + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + /** + * The Camel components named by the advisory text (Maven artifact ids such as camel-kafka). May be empty when the + * advisory does not name specific components. + */ + public List getComponents() { + return components; + } + + public void setComponents(List components) { + this.components = components; + } +} diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java new file mode 100644 index 0000000000000..28eb848b7df9f --- /dev/null +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java @@ -0,0 +1,292 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.maven.packaging; + +import java.io.File; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Path; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; + +import org.apache.camel.tooling.model.JsonMapper; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; +import org.apache.camel.util.json.JsonArray; +import org.apache.camel.util.json.JsonObject; +import org.apache.camel.util.json.Jsoner; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProjectHelper; +import org.codehaus.plexus.build.BuildContext; +import org.snakeyaml.engine.v2.api.Load; +import org.snakeyaml.engine.v2.api.LoadSettings; + +/** + * Syncs the published Apache Camel CVE security advisories (the sources behind + * camel.apache.org/security, maintained as Markdown files with YAML + * front matter in the camel-website git repository) into a JSON file shipped with camel-catalog, the same way the known + * releases are synced by {@code update-camel-releases}. + */ +@Mojo(name = "update-security-advisories", threadSafe = true, defaultPhase = LifecyclePhase.GENERATE_RESOURCES) +public class UpdateSecurityAdvisoriesMojo extends AbstractGeneratorMojo { + + private static final String GIT_SECURITY_URL + = "https://api.github.com/repos/apache/camel-website/contents/content/security"; + private static final String WEBSITE_BASE_URL = "https://camel.apache.org"; + + private static final Pattern ADVISORY_FILE = Pattern.compile("CVE-\\d{4}-\\d{4,}\\.md"); + private static final Pattern COMPONENT_TOKEN = Pattern.compile("camel-[a-z0-9]+(?:-[a-z0-9]+)*"); + private static final Pattern CVE_ID = Pattern.compile("CVE-(\\d{4})-(\\d+)"); + + /** + * The output directory for the generated catalog advisories file + */ + @Parameter(defaultValue = "${project.basedir}/src/generated/resources/org/apache/camel/catalog/advisories") + protected File outDir; + + @Inject + public UpdateSecurityAdvisoriesMojo(MavenProjectHelper projectHelper, BuildContext buildContext) { + super(projectHelper, buildContext); + } + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + if (outDir == null) { + outDir = new File(project.getBasedir(), "src/generated/resources"); + } + + try { + getLog().info("Updating Camel security advisories from camel-website"); + List links = fetchAdvisoryLinks(); + List advisories = processAdvisories(links); + advisories.sort(Comparator.comparingLong(UpdateSecurityAdvisoriesMojo::cveOrdinal)); + getLog().info("Found " + advisories.size() + " published security advisories"); + + JsonArray arr = new JsonArray(); + for (SecurityAdvisoryModel advisory : advisories) { + arr.add(JsonMapper.asJsonObject(advisory)); + } + String json = Jsoner.serialize(arr); + json = Jsoner.prettyPrint(json, 4); + + Path path = outDir.toPath(); + updateResource(path, "camel-security-advisories.json", json); + addResourceDirectory(path); + } catch (Exception e) { + throw new MojoExecutionException(e); + } + } + + private List processAdvisories(List urls) throws Exception { + List answer = new ArrayList<>(); + + try (CloseableHttpClient hc = new CloseableHttpClient()) { + for (String url : urls) { + HttpResponse res + = hc.send(HttpRequest.newBuilder(new URI(url)).timeout(Duration.ofSeconds(20)).build(), + HttpResponse.BodyHandlers.ofString()); + + if (res.statusCode() == 200) { + SecurityAdvisoryModel model = parseAdvisory(res.body()); + if (model != null) { + answer.add(model); + } + } + } + } + + return answer; + } + + /** + * Parse one advisory Markdown file (YAML front matter). Returns {@code null} for drafts, non-advisory pages and + * files without parseable front matter, so only published advisories are included. + */ + static SecurityAdvisoryModel parseAdvisory(String content) { + Map frontMatter = frontMatter(content); + if (frontMatter == null) { + return null; + } + if (!"security-advisory".equals(str(frontMatter.get("type")))) { + return null; + } + Object draft = frontMatter.get("draft"); + if (Boolean.TRUE.equals(draft) || "true".equalsIgnoreCase(str(draft))) { + return null; + } + String cve = str(frontMatter.get("cve")); + if (cve == null || cve.isBlank()) { + return null; + } + + SecurityAdvisoryModel model = new SecurityAdvisoryModel(); + model.setCve(cve.trim()); + model.setDate(trimmed(frontMatter.get("date"))); + String severity = str(frontMatter.get("severity")); + if (severity != null) { + model.setSeverity(severity.trim().toUpperCase(Locale.ROOT)); + } + model.setSummary(trimmed(frontMatter.get("summary"))); + model.setAffected(trimmed(frontMatter.get("affected"))); + model.setFixed(trimmed(frontMatter.get("fixed"))); + model.setMitigation(trimmed(frontMatter.get("mitigation"))); + + String url = str(frontMatter.get("url")); + if (url == null || url.isBlank()) { + url = "/security/" + model.getCve() + ".html"; + } + if (url.startsWith("/")) { + url = WEBSITE_BASE_URL + url; + } + model.setUrl(url.trim()); + + model.setComponents(extractComponents(str(frontMatter.get("title")), model.getSummary(), + str(frontMatter.get("description")), model.getMitigation())); + return model; + } + + @SuppressWarnings("unchecked") + static Map frontMatter(String content) { + if (content == null) { + return null; + } + String trimmedContent = content.stripLeading(); + if (!trimmedContent.startsWith("---")) { + return null; + } + int start = trimmedContent.indexOf('\n'); + if (start < 0) { + return null; + } + int end = trimmedContent.indexOf("\n---", start); + if (end < 0) { + return null; + } + String yaml = trimmedContent.substring(start + 1, end); + try { + Object parsed = new Load(LoadSettings.builder().build()).loadFromString(yaml); + return parsed instanceof Map ? (Map) parsed : null; + } catch (Exception e) { + return null; + } + } + + /** + * The Camel components named by the advisory text, as {@code camel-*} tokens (best-effort: some older advisories do + * not name components at all). + */ + static List extractComponents(String... texts) { + TreeSet found = new TreeSet<>(); + for (String text : texts) { + if (text == null) { + continue; + } + Matcher matcher = COMPONENT_TOKEN.matcher(text.toLowerCase(Locale.ROOT)); + while (matcher.find()) { + found.add(matcher.group()); + } + } + return new ArrayList<>(found); + } + + private List fetchAdvisoryLinks() throws Exception { + List answer = new ArrayList<>(); + + // use JDK http client to call github api + try (CloseableHttpClient hc = new CloseableHttpClient()) { + HttpResponse res = hc.send( + HttpRequest.newBuilder(new URI(GIT_SECURITY_URL)).timeout(Duration.ofSeconds(20)).build(), + HttpResponse.BodyHandlers.ofString()); + + // follow redirect + if (res.statusCode() == 302) { + String loc = res.headers().firstValue("location").orElse(null); + if (loc != null) { + res = hc.send(HttpRequest.newBuilder(new URI(loc)).timeout(Duration.ofSeconds(20)).build(), + HttpResponse.BodyHandlers.ofString()); + } + } + + if (res.statusCode() == 200) { + JsonArray root = (JsonArray) Jsoner.deserialize(res.body()); + for (Object o : root) { + JsonObject jo = (JsonObject) o; + String name = jo.getString("name"); + if (name != null && ADVISORY_FILE.matcher(name).matches()) { + String url = jo.getString("download_url"); + if (url != null) { + answer.add(url); + } + } + } + } + } + + return answer; + } + + private static long cveOrdinal(SecurityAdvisoryModel advisory) { + Matcher matcher = CVE_ID.matcher(advisory.getCve() == null ? "" : advisory.getCve()); + if (matcher.find()) { + return Long.parseLong(matcher.group(1)) * 1_000_000L + Long.parseLong(matcher.group(2)); + } + return 0; + } + + private static String str(Object value) { + return value == null ? null : String.valueOf(value); + } + + private static String trimmed(Object value) { + String text = str(value); + return text == null ? null : text.trim(); + } + + /** + * Wrapper that makes {@link HttpClient} usable in try-with-resources. On Java 21+ HttpClient implements + * AutoCloseable natively; the instanceof check future-proofs us for when the minimum JDK is raised. + */ + private static final class CloseableHttpClient implements AutoCloseable { + private final HttpClient httpClient = HttpClient.newHttpClient(); + + HttpResponse send(HttpRequest request, HttpResponse.BodyHandler responseBodyHandler) + throws java.io.IOException, InterruptedException { + return httpClient.send(request, responseBodyHandler); + } + + @Override + public void close() throws Exception { + if (httpClient instanceof AutoCloseable closeable) { + closeable.close(); + } + } + } +} diff --git a/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java new file mode 100644 index 0000000000000..425a45dbab4fc --- /dev/null +++ b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.camel.maven.packaging; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import org.apache.camel.tooling.model.JsonMapper; +import org.apache.camel.tooling.model.SecurityAdvisoryModel; +import org.apache.camel.util.json.JsonObject; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests the advisory front-matter parsing of {@link UpdateSecurityAdvisoriesMojo} against canned copies of two real + * published advisories: CVE-2025-27636 (recent front matter style) and CVE-2013-4330 (old style). + */ +class UpdateSecurityAdvisoriesMojoTest { + + private static String fixture(String name) throws IOException { + try (InputStream in = UpdateSecurityAdvisoriesMojoTest.class + .getResourceAsStream("/security-advisories/" + name)) { + assertThat(in).as("fixture /security-advisories/" + name).isNotNull(); + return new String(in.readAllBytes(), StandardCharsets.UTF_8); + } + } + + @Test + void parsesRecentAdvisoryStyle() throws Exception { + SecurityAdvisoryModel model = UpdateSecurityAdvisoriesMojo.parseAdvisory(fixture("CVE-2025-27636.md")); + + assertThat(model).isNotNull(); + assertThat(model.getCve()).isEqualTo("CVE-2025-27636"); + assertThat(model.getSeverity()).isEqualTo("MEDIUM"); + assertThat(model.getSummary()).contains("Header Injection"); + assertThat(model.getAffected()).contains("4.10.0 before 4.10.2"); + assertThat(model.getFixed()).contains("4.10.2"); + assertThat(model.getMitigation()).isNotBlank(); + assertThat(model.getUrl()).isEqualTo("https://camel.apache.org/security/CVE-2025-27636.html"); + assertThat(model.getComponents()) + .contains("camel-bean", "camel-undertow", "camel-kafka", "camel-platform-http"); + } + + @Test + void parsesOldAdvisoryStyle() throws Exception { + SecurityAdvisoryModel model = UpdateSecurityAdvisoriesMojo.parseAdvisory(fixture("CVE-2013-4330.md")); + + assertThat(model).isNotNull(); + assertThat(model.getCve()).isEqualTo("CVE-2013-4330"); + assertThat(model.getSeverity()).isEqualTo("CRITICAL"); + assertThat(model.getAffected()).startsWith("2.9.0 up to 2.9.7"); + assertThat(model.getFixed()).contains("2.12.1"); + assertThat(model.getUrl()).isEqualTo("https://camel.apache.org/security/CVE-2013-4330.html"); + // the old advisory does not name camel-* components + assertThat(model.getComponents()).isEmpty(); + } + + @Test + void skipsDraftsAndNonAdvisories() { + String draft = """ + --- + type: security-advisory + draft: true + cve: CVE-2099-99999 + severity: LOW + --- + body + """; + assertThat(UpdateSecurityAdvisoriesMojo.parseAdvisory(draft)).isNull(); + + String wrongType = """ + --- + type: blog-post + draft: false + cve: CVE-2099-99999 + --- + body + """; + assertThat(UpdateSecurityAdvisoriesMojo.parseAdvisory(wrongType)).isNull(); + + assertThat(UpdateSecurityAdvisoriesMojo.parseAdvisory("no front matter")).isNull(); + assertThat(UpdateSecurityAdvisoriesMojo.parseAdvisory(null)).isNull(); + } + + @Test + void modelRoundTripsThroughJsonMapper() throws Exception { + SecurityAdvisoryModel model = UpdateSecurityAdvisoriesMojo.parseAdvisory(fixture("CVE-2025-27636.md")); + + JsonObject json = JsonMapper.asJsonObject(model); + SecurityAdvisoryModel copy = JsonMapper.generateSecurityAdvisoryModel(json); + + assertThat(copy.getCve()).isEqualTo(model.getCve()); + assertThat(copy.getSeverity()).isEqualTo(model.getSeverity()); + assertThat(copy.getSummary()).isEqualTo(model.getSummary()); + assertThat(copy.getAffected()).isEqualTo(model.getAffected()); + assertThat(copy.getFixed()).isEqualTo(model.getFixed()); + assertThat(copy.getMitigation()).isEqualTo(model.getMitigation()); + assertThat(copy.getUrl()).isEqualTo(model.getUrl()); + assertThat(copy.getComponents()).isEqualTo(model.getComponents()); + } +} diff --git a/tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2013-4330.md b/tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2013-4330.md new file mode 100644 index 0000000000000..0568ebc756a48 --- /dev/null +++ b/tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2013-4330.md @@ -0,0 +1,23 @@ +--- +title: "Apache Camel Security Advisory - CVE-2013-4330" +url: /security/CVE-2013-4330.html +date: 2013-10-04T13:55:09.853000 +draft: false +type: security-advisory +cve: CVE-2013-4330 +severity: CRITICAL +summary: "Writing files using FILE or FTP components, can potentially be exploited by a malicious user." +description: "When sending an Exchange with the in Message Header 'CamelFileName' with a value of '$simple{...}' to a FILE or FTP producer, it will interpret the value as simple language expression which can be exploited by a malicious user." +mitigation: "2.9.x users should upgrade to 2.9.8, 2.10.x users should upgrade to 2.10.7, 2.11.x users should upgrade to 2.11.2 and 2.12.0 users should upgrade to 2.12.1. This patch will be included from Camel 2.13.0: https://git-wip-us.apache.org/repos/asf?p=camel.git;a=commitdiff;h=27a9752a565fbef436bac4fcf22d339e3295b2a0" +credit: "This issue was discovered by Grégory Draperi" +affected: 2.9.0 up to 2.9.7, 2.10.0 up to 2.10.6, 2.11.0 up to 2.11.1, 2.12.0 +fixed: 2.9.8, 2.10.7, 2.11.2, 2.12.1 and newer +--- + +Example: Create a simple route which moves files from one directory to another, e.g.: + + from("file:c:/tmp/in") + .to("file:/c:/tmp/out"); + +If you are using Windows, create an file with a name like `"$simple{}"` (without the quotes) and drop it into the "c:/tmp/in" directory. The file consumer will read and process this file. It will also set the Exchange in Message Header '`CamelFileName`' with the value `"$simple{}"`. In the next step, the file producer will interpreted the value of this header as simple language expression and execute the malicious code. + diff --git a/tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2025-27636.md b/tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2025-27636.md new file mode 100644 index 0000000000000..c561508b7948c --- /dev/null +++ b/tooling/maven/camel-package-maven-plugin/src/test/resources/security-advisories/CVE-2025-27636.md @@ -0,0 +1,53 @@ +--- +title: "Apache Camel Security Advisory - CVE-2025-27636" +date: 2025-03-09T04:30:42+02:00 +url: /security/CVE-2025-27636.html +draft: false +type: security-advisory +cve: CVE-2025-27636 +severity: MEDIUM +summary: "Camel Message Header Injection via Improper Filtering" +description: "This vulnerability is only present in the following situation. The user is using one of the following HTTP Servers via one the of the following Camel components: camel-servlet, camel-jetty, camel-undertow, camel-platform-http and camel-netty-http and in the route, the exchange will be routed to a camel-bean producer. So ONLY camel-bean component is affected. In particular: The bean invocation (is only affected if you use any of the above together with camel-bean component) and the bean that can be called, has more than 1 method implemented. In these, limited and particular, conditions an attacker could be able to forge a Camel header name and make the bean component invoking other methods in the SAME bean. The vulnerability arises due to a bug in the default filtering mechanism that only blocks headers starting with 'Camel', 'camel', or 'org.apache.camel.'. This vulnerability is present in Camel's default incoming header filter, that allows an attacker to include Camel specific +headers that for some Camel components can alter the behaviours such as the camel-bean component, to call another method +on the bean, than was coded in the application. In the camel-jms component, then a mallicous header can be used to send +the message to another queue (on the same broker) than was coded in the application. + +The attacker would need to inject custom headers, such as HTTP protocols. So if you have Camel applications that are +directly connected to the internet via HTTP, then an attacker could include malicious HTTP headers in the HTTP requests +that are send to the Camel application. + +All the known Camel HTTP component such as camel-servlet, camel-jetty, camel-undertow, camel-platform-http, and camel-netty-http would be vulnerable out of the box. + +In terms of usage of the default header filter strategy the list of components using that is: + +camel-activemq +camel-activemq6 +camel-amqp +camel-aws2-sqs +camel-azure-servicebus +camel-cxf-rest +camel-cxf-soap +camel-http +camel-jetty +camel-jms +camel-kafka +camel-knative +camel-mail +camel-nats +camel-netty-http +camel-platform-http +camel-rest +camel-servlet +camel-sjms +camel-spring-rabbitmq +camel-stomp +camel-tahu +camel-undertow +camel-xmpp" +mitigation: "Users are recommended to upgrade to version 4.10.2 for 4.10.x LTS, 4.8.5 for 4.8.x LTS and 3.22.4 for 3.x releases. Also, users could use removeHeaders EIP, to filter out anything like 'cAmel, cAMEL' etc, or in general everything not starting with 'Camel', 'camel' or 'org.apache.camel.'." +credit: "This issue was discovered by Mark Thorson of AT&T" +affected: Apache Camel 4.10.0 before 4.10.2. Apache Camel 4.8.0 before 4.8.5. Apache Camel 3.10.0 before 3.22.4. +fixed: 3.22.4, 4.8.5 and 4.10.2 +--- + +The JIRA ticket: https://issues.apache.org/jira/browse/CAMEL-21828 refers to the various commits that resolved the issue, and have more details. From 3531d80ee6edf96ec09a8bdf30e1540a88bbf69f Mon Sep 17 00:00:00 2001 From: Andrea Cosentino Date: Fri, 10 Jul 2026 15:33:13 +0200 Subject: [PATCH 2/2] CAMEL-23979: Address review feedback - Component token extraction no longer produces false positives: the first segment must start with a letter (drops lowercased JIRA ids) and common English prose such as Camel-internal is denylisted. Deliberately not validated against the current catalog so that advisories naming removed components (camel-xstream, camel-hessian, ...) remain filterable. - Regenerated camel-security-advisories.json: 11 bogus tokens removed. - Severity filter description now lists the actual values (LOW, MEDIUM, HIGH, CRITICAL). - Added @since 4.22 to CamelCatalog#camelSecurityAdvisories(). Co-Authored-By: Claude Fable 5 Signed-off-by: Andrea Cosentino --- .../advisories/camel-security-advisories.json | 71 +++++-------------- .../apache/camel/catalog/CamelCatalog.java | 2 + .../core/commands/mcp/AdvisoryTools.java | 4 +- .../UpdateSecurityAdvisoriesMojo.java | 21 +++++- .../UpdateSecurityAdvisoriesMojoTest.java | 10 +++ 5 files changed, 50 insertions(+), 58 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json index bc565492b6ad9..569f7e6a4aa1a 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/advisories/camel-security-advisories.json @@ -143,11 +143,7 @@ "affected": "2.20.0 up to 2.20.3, 2.21.0", "fixed": "2.20.4, 2.21.1 and newer", "mitigation": "2.20.x users should upgrade to 2.20.4, 2.21.0 users should upgrade to 2.21.1. The JIRA tickets: https:\/\/issues.apache.org\/jira\/browse\/CAMEL-12444 and https:\/\/issues.apache.org\/jira\/browse\/CAMEL-10894 (partial fix) refer to the various commits that resovoled the issue, and have more details.", - "url": "https:\/\/camel.apache.org\/security\/CVE-2018-8027.html", - "components": [ - "camel-10894", - "camel-12444" - ] + "url": "https:\/\/camel.apache.org\/security\/CVE-2018-8027.html" }, { "cve": "CVE-2018-8041", @@ -439,8 +435,6 @@ "camel-bean", "camel-exec", "camel-mail", - "camel-prefixed", - "camel-specific", "camel-sql", "camel-undertow" ] @@ -468,9 +462,7 @@ "mitigation": "Users are recommended to upgrade to a release that contains the CAMEL-23212 fix. On the mainline the fix is included from Apache Camel 4.19.0 (and later releases such as 4.20.0). For users on the 4.18.x LTS releases stream, upgrade to 4.18.3. The fix replaces the denylist with a strict allowlist of recognized `docling` CLI flags (rejecting any unrecognized flag, and rejecting producer-managed flags such as the output-directory flags), defensively rejects shell metacharacters in argument values, and normalizes path-like values with Path.normalize() before validating them so that traversal sequences which bypass a literal `..\/` check are detected. As defence in depth, route authors should avoid mapping untrusted message content into the `CamelDoclingCustomArguments` header and the path-bearing headers, and should strip Camel-internal headers from messages that arrive from untrusted producers.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-40047.html", "components": [ - "camel-23212", - "camel-docling", - "camel-internal" + "camel-docling" ] }, { @@ -572,7 +564,6 @@ "mitigation": "Users are recommended to upgrade to a version that contains the CAMEL-23372 fix once available: 4.21.0 for the 4.21.x line, 4.18.3 for the 4.18.x line, and 4.14.8 for the 4.14.x line. For deployments that cannot upgrade immediately, configure a JMS-provider-side allow-list (Apache ActiveMQ Artemis 'deserializationAllowList' \/ 'deserializationDenyList', Apache ActiveMQ Classic 'org.apache.activemq.SERIALIZABLE_PACKAGES') as the primary mitigation, and\/or override the in-code default via the endpoint-level 'deserializationFilter' option or the JVM-wide '-Djdk.serialFilter' system property with an explicit deny: '!java.net.**;java.**;javax.**;org.apache.camel.**;!*' (or '!java.net.**;java.**;org.apache.camel.**;!*' for the aggregation-repository components, which do not include javax.**).", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-42527.html", "components": [ - "camel-23372", "camel-amqp", "camel-cassandraql", "camel-consul", @@ -597,8 +588,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes Camel apply a default Hazelcast JavaSerializationFilterConfig (whitelisting the java., javax. and org.apache.camel. class-name prefixes and blacklisting java.net.) to instances it creates from its own default configuration, while leaving any user-supplied Config or HazelcastInstance untouched. For deployments that cannot upgrade immediately, configure a deserialization filter on the Hazelcast instance (Hazelcast JavaSerializationFilterConfig, or the JVM-wide system property -Djdk.serialFilter=!java.net.**;java.**;javax.**;org.apache.camel.**;!*) and enable Hazelcast cluster authentication and TLS to restrict who can reach the cluster.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-43865.html", "components": [ - "camel-hazelcast", - "camel-side" + "camel-hazelcast" ] }, { @@ -629,7 +619,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x LTS releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, restrict write access to the AWS Secrets Manager secret that holds the camel-pqc key metadata so that only the application's own identity holds secretsmanager:PutSecretValue on it (least-privilege IAM), and keep the PQC key material in a secret separate from any data that less-trusted principals can write.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-43867.html", "components": [ - "camel-23200", "camel-pqc" ] }, @@ -666,8 +655,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix implements a HeaderFilterStrategy in the camel-cometd binding (a long-standing TODO in the code) that filters the Camel header namespace case-insensitively on inbound mapping, so client-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from inbound CometD messages before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), and install an explicit Bayeux SecurityPolicy on the CometdComponent so that only authenticated clients can publish.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46454.html", "components": [ - "camel-cometd", - "camel-internal" + "camel-cometd" ] }, { @@ -693,8 +681,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix adds an inbound HeaderFilterStrategy rule to Sqs2HeaderFilterStrategy that filters the Camel header namespace case-insensitively on inbound mapping, so sender-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from inbound messages before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), and restrict who may send to the consumed SQS queue by applying least-privilege sqs:SendMessage permissions on the queue resource policy.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46456.html", "components": [ - "camel-aws2-sqs", - "camel-internal" + "camel-aws2-sqs" ] }, { @@ -707,7 +694,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes camel-nats default to a dedicated NatsHeaderFilterStrategy that filters the Camel header namespace case-insensitively on inbound mapping, so client-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from inbound NATS messages before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), and enable authentication on the NATS server so that only trusted clients can publish to the consumed subject.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46457.html", "components": [ - "camel-internal", "camel-nats" ] }, @@ -721,7 +707,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, the per-message override is disabled by default; enable it only on trusted endpoints with useJavaMailSessionPropertiesFromHeaders=true. For deployments that cannot upgrade immediately, strip the namespace before the mail producer with removeHeaders('mail.smtp.*') and removeHeaders('mail.smtps.*') between any untrusted ingress and the smtp \/ smtps producer. Even with the opt-in enabled, route authors should still strip the namespace on any path that carries untrusted input.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46584.html", "components": [ - "camel-internal", "camel-mail" ] }, @@ -735,8 +720,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set the query via the raw header name must use CamelLuceneQuery (and CamelLuceneReturnLuceneDocs) instead of QUERY \/ RETURN_LUCENE_DOCS. For deployments that cannot upgrade immediately, strip the attacker-controllable headers before the Lucene producer and set the query from a trusted source (for example removeHeader('QUERY') and removeHeader('RETURN_LUCENE_DOCS'), then setHeader('QUERY', constant(...)) at the start of the route).", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46585.html", "components": [ - "camel-lucene", - "camel-prefixed" + "camel-lucene" ] }, { @@ -749,8 +733,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix renames the camel-couchbase Exchange header constant string values (CCB_KEY, CCB_ID, CCB_TTL, CCB_DDN, CCB_VN) to carry the Camel prefix (CamelCouchbaseKey, CamelCouchbaseId, CamelCouchbaseTtl, CamelCouchbaseDesignDocumentName, CamelCouchbaseViewName) so that they are blocked by the inbound HttpHeaderFilterStrategy; the Java constant field names are unchanged. For deployments that cannot upgrade immediately, strip the affected headers from untrusted inbound messages before they reach the producer (for example removeHeader('CCB_KEY'), removeHeader('CCB_ID'), removeHeader('CCB_TTL'), removeHeader('CCB_DDN') and removeHeader('CCB_VN') in front of the couchbase endpoint), or apply a custom HeaderFilterStrategy that blocks these names.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46587.html", "components": [ - "camel-couchbase", - "camel-prefixed" + "camel-couchbase" ] }, { @@ -763,8 +746,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix renames the camel-couchdb Exchange header constant string values (CouchDbDatabase, CouchDbSeq, CouchDbId, CouchDbRev, CouchDbMethod) to carry the Camel prefix (CamelCouchDbDatabase, CamelCouchDbSeq, CamelCouchDbId, CamelCouchDbRev, CamelCouchDbMethod) so that they are blocked by the inbound HttpHeaderFilterStrategy; the Java constant field names are unchanged. For deployments that cannot upgrade immediately, strip the affected headers from untrusted inbound messages before they reach the producer (for example removeHeader('CouchDbDatabase'), removeHeader('CouchDbId'), removeHeader('CouchDbRev'), removeHeader('CouchDbSeq') and removeHeader('CouchDbMethod') in front of the couchdb endpoint), or apply a custom HeaderFilterStrategy that blocks these names.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46588.html", "components": [ - "camel-couchdb", - "camel-prefixed" + "camel-couchdb" ] }, { @@ -777,7 +759,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x LTS releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, restrict write access to the key backend so that only the application's own identity can write the camel-pqc secrets (least-privilege HashiCorp Vault policies and secretsmanager:PutSecretValue IAM), and keep the PQC key material in a backend separate from any data that less-trusted principals can write.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46590.html", "components": [ - "camel-23200", "camel-pqc" ] }, @@ -791,8 +772,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. For deployments that cannot upgrade immediately, do not populate the CamelNeo4jMatchProperties map from untrusted input: validate or allow-list the property names (for example against ^[A-Za-z_][A-Za-z0-9_]*$) before the Neo4j producer, and ensure that any consumer feeding such a route filters inbound Camel* \/ camel* headers so the match header cannot be supplied by an external sender.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46591.html", "components": [ - "camel-neo4j", - "camel-prefixed" + "camel-neo4j" ] }, { @@ -807,8 +787,7 @@ "components": [ "camel-cxf", "camel-cxf-common", - "camel-cxfrs", - "camel-prefixed" + "camel-cxfrs" ] }, { @@ -821,7 +800,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes the affected consumers apply a HeaderFilterStrategy that filters the Camel header namespace case-insensitively on inbound mapping, so externally-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from the inbound message before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), require authentication on the WebSocket endpoint, and avoid bridging an untrusted consumer directly into an HTTP producer whose target URI can be driven from message headers.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-46726.html", "components": [ - "camel-internal", "camel-vertx-websocket" ] }, @@ -840,7 +818,6 @@ "camel-cxf-transport", "camel-exec", "camel-file", - "camel-internal", "camel-knative", "camel-knative-http", "camel-undertow" @@ -856,7 +833,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set Solr parameters or fields via the raw header prefixes must use CamelSolrParam. \/ CamelSolrField. instead of SolrParam. \/ SolrField.. For deployments that cannot upgrade immediately, strip the SolrParam.* and SolrField.* headers from any untrusted ingress before the solr: producer, and set the required Solr parameters and fields from a trusted source in the route.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48203.html", "components": [ - "camel-prefixed", "camel-solr" ] }, @@ -870,8 +846,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that drive GridFS operations or metadata via the raw header names must use CamelGridFsOperation \/ CamelGridFsObjectId \/ CamelGridFsMetadata \/ CamelGridFsChunkSize \/ CamelGridFsFileId instead of the gridfs.* names. For deployments that cannot upgrade immediately, set an explicit operation on the mongodb-gridfs: endpoint so the operation is not taken from a header, and strip the gridfs.* headers from any untrusted ingress before the producer.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48204.html", "components": [ - "camel-mongodb-gridfs", - "camel-prefixed" + "camel-mongodb-gridfs" ] }, { @@ -884,8 +859,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that drive DNS operations via the raw header names must use CamelDnsServer \/ CamelDnsName \/ CamelDnsDomain \/ CamelDnsType \/ CamelDnsClass \/ CamelDnsTerm instead of the dns.* \/ term names. For deployments that cannot upgrade immediately, strip the dns.* and term headers from any untrusted ingress before the dns: producer, and set the DNS server and lookup parameters from a trusted source in the route.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48205.html", "components": [ - "camel-dns", - "camel-prefixed" + "camel-dns" ] }, { @@ -898,8 +872,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that drive JIRA operations via the raw header names must use the CamelJira* names (for example CamelJiraIssueKey) instead of the old values. For deployments that cannot upgrade immediately, strip the camel-jira control headers from any untrusted ingress before the jira: producer (for example removing the IssueKey, ProjectKey, IssueTransitionId and related headers at the start of the route), and set the required JIRA operation parameters from a trusted source.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-48206.html", "components": [ - "camel-jira", - "camel-prefixed" + "camel-jira" ] }, { @@ -912,7 +885,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, only tool argument fields that match a declared parameter in the tool specification are set as Exchange headers. Tools defined without parameter declarations will have zero argument headers set from LLM tool calls - this is a breaking change for routes that rely on implicit argument passthrough; to restore argument flow, declare the expected parameters explicitly via the parameter.NAME=TYPE endpoint option. For deployments that cannot upgrade immediately, strip untrusted headers after the tool invocation (for example removeHeaders('Camel*') and removeHeaders('camel*') after the langchain4j-tools endpoint) and declare explicit parameter schemas for every tool so the LLM-returned arguments are constrained.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49042.html", "components": [ - "camel-internal", "camel-langchain4j-agent", "camel-langchain4j-tools", "camel-spring-ai-tools" @@ -941,8 +913,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set IRC headers via the raw header names must use the CamelIrc* names (for example CamelIrcSendTo) instead of the old irc.* values. For deployments that cannot upgrade immediately, strip the irc.* headers from any untrusted ingress before the irc: producer (for example removeHeaders('irc.*') at the start of the route), and set the IRC destination from a trusted source.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49097.html", "components": [ - "camel-irc", - "camel-prefixed" + "camel-irc" ] }, { @@ -955,8 +926,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set or read Kafka headers via the raw header names must use the CamelKafka* names (for example CamelKafkaOverrideTopic and CamelKafkaTopic) instead of the old kafka.* values. For deployments that cannot upgrade immediately, strip the kafka.* headers from any untrusted ingress before the kafka: producer (for example removeHeaders('kafka.*') at the start of the route), and set the target topic from a trusted source.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49098.html", "components": [ - "camel-kafka", - "camel-prefixed" + "camel-kafka" ] }, { @@ -969,7 +939,6 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. After upgrading, routes that set Salesforce operation parameters via the raw header names must use the CamelSalesforce* names (for example CamelSalesforceSObjectQuery and CamelSalesforceApexUrl) instead of the old sObject* \/ apex* values; the endpoint-option spelling is unchanged. For deployments that cannot upgrade immediately, strip the Salesforce control headers from any untrusted ingress before the salesforce: producer (for example removeHeaders('sObject*') and removeHeaders('apex*') at the start of the route), and set the query, SObject and Apex parameters from a trusted source.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-49099.html", "components": [ - "camel-prefixed", "camel-salesforce" ] }, @@ -1013,8 +982,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.14.x LTS releases stream, then they are suggested to upgrade to 4.14.8. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix makes the consumer apply the HeaderFilterStrategy it already inherits from the HTTP\/servlet stack, filtering the Camel header namespace case-insensitively on inbound mapping, so externally-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from the inbound message before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), require authentication on the WebSocket endpoint, and avoid bridging an untrusted consumer directly into an HTTP producer whose target URI can be driven from message headers.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-55993.html", "components": [ - "camel-atmosphere-websocket", - "camel-internal" + "camel-atmosphere-websocket" ] }, { @@ -1027,8 +995,7 @@ "mitigation": "Users are recommended to upgrade to version 4.21.0, which fixes the issue. If users are on the 4.18.x releases stream, then they are suggested to upgrade to 4.18.3. The fix adds a dedicated IggyHeaderFilterStrategy (and a headerFilterStrategy endpoint option) that filters the Camel header namespace case-insensitively on inbound mapping, so externally-supplied Camel* \/ camel* headers are no longer copied into the Exchange. For deployments that cannot upgrade immediately, strip the Camel control headers from the inbound message before they reach any downstream producer (for example removeHeaders('Camel*') and removeHeaders('camel*') at the start of the route), restrict who can publish to the consumed Iggy stream\/topic, and avoid bridging an untrusted consumer directly into an HTTP producer whose target URI can be driven from message headers.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-55994.html", "components": [ - "camel-iggy", - "camel-internal" + "camel-iggy" ] }, { @@ -1058,10 +1025,8 @@ "mitigation": "This is a defense-in-depth hardening change with no known exploit path in camel-aws2-sns, which is producer-only, so no urgent action or workaround is required. Users who want the aligned behaviour can upgrade to version 4.21.0, or to 4.14.8 on the 4.14.x LTS releases stream, or to 4.18.3 on the 4.18.x releases stream, which contain the change. As a general best practice, operators should continue to apply least-privilege IAM permissions on their SNS topics.", "url": "https:\/\/camel.apache.org\/security\/CVE-2026-56140.html", "components": [ - "camel-23506", "camel-aws2-sns", - "camel-aws2-sqs", - "camel-namespace" + "camel-aws2-sqs" ] } ] diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java index 2fb23d1150cf2..0b8cd79667df3 100644 --- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java +++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java @@ -668,6 +668,8 @@ default BaseModel model(Kind kind, String name) { * Load all published Camel CVE security advisories from catalog (the data behind * camel.apache.org/security, synced into the catalog when it was * built). + * + * @since 4.22 */ List camelSecurityAdvisories(); diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java index 68f2703ffbffd..454873b1942d0 100644 --- a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java +++ b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/AdvisoryTools.java @@ -53,8 +53,8 @@ public AdvisoriesResult camel_security_advisories( @ToolArg(description = "Component to filter by, e.g. kafka or camel-kafka (optional; best-effort match " + "against components named in the advisory text - older advisories may not name " + "components)") String component, - @ToolArg(description = "Severity to filter by as published, e.g. LOW, MEDIUM, MODERATE, IMPORTANT or " - + "CRITICAL (optional)") String severity) { + @ToolArg(description = "Severity to filter by: LOW, MEDIUM, HIGH, or CRITICAL " + + "(optional)") String severity) { try { List advisories = advisoryService.advisories(); List matches diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java index 28eb848b7df9f..16d3b64c3d52d 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojo.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -63,9 +64,20 @@ public class UpdateSecurityAdvisoriesMojo extends AbstractGeneratorMojo { private static final String WEBSITE_BASE_URL = "https://camel.apache.org"; private static final Pattern ADVISORY_FILE = Pattern.compile("CVE-\\d{4}-\\d{4,}\\.md"); - private static final Pattern COMPONENT_TOKEN = Pattern.compile("camel-[a-z0-9]+(?:-[a-z0-9]+)*"); + // the first segment must start with a letter so that lowercased JIRA ids ("camel-12444") never match + private static final Pattern COMPONENT_TOKEN = Pattern.compile("camel-[a-z][a-z0-9]+(?:-[a-z0-9]+)*"); private static final Pattern CVE_ID = Pattern.compile("CVE-(\\d{4})-(\\d+)"); + /** + * English prose that follows "Camel-" in advisory texts (e.g. "Camel-internal headers", "non-Camel-prefixed names") + * and therefore must not be mistaken for component artifact ids. Deliberately not validated against the current + * catalog instead: old advisories legitimately name components that have since been removed or renamed + * (camel-xstream, camel-hessian, camel-castor, camel-cxfrs, ...), which must remain filterable. + */ + private static final Set COMPONENT_TOKEN_DENYLIST = Set.of( + "camel-internal", "camel-prefixed", "camel-specific", "camel-side", "camel-namespace", + "camel-case", "camel-cased", "camel-based", "camel-related", "camel-style"); + /** * The output directory for the generated catalog advisories file */ @@ -201,7 +213,8 @@ static Map frontMatter(String content) { /** * The Camel components named by the advisory text, as {@code camel-*} tokens (best-effort: some older advisories do - * not name components at all). + * not name components at all). Lowercased JIRA ids and common English prose such as "Camel-internal" are filtered + * out. */ static List extractComponents(String... texts) { TreeSet found = new TreeSet<>(); @@ -211,7 +224,9 @@ static List extractComponents(String... texts) { } Matcher matcher = COMPONENT_TOKEN.matcher(text.toLowerCase(Locale.ROOT)); while (matcher.find()) { - found.add(matcher.group()); + if (!COMPONENT_TOKEN_DENYLIST.contains(matcher.group())) { + found.add(matcher.group()); + } } } return new ArrayList<>(found); diff --git a/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java index 425a45dbab4fc..4cf0d166f3bc4 100644 --- a/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java +++ b/tooling/maven/camel-package-maven-plugin/src/test/java/org/apache/camel/maven/packaging/UpdateSecurityAdvisoriesMojoTest.java @@ -98,6 +98,16 @@ void skipsDraftsAndNonAdvisories() { assertThat(UpdateSecurityAdvisoriesMojo.parseAdvisory(null)).isNull(); } + @Test + void componentExtractionSkipsJiraIdsAndProse() { + // lowercased JIRA ids and English prose following "Camel-" must not become component names + assertThat(UpdateSecurityAdvisoriesMojo.extractComponents( + "See CAMEL-12444 and CAMEL-23200 for the fix.", + "Camel-internal headers with non-Camel-prefixed names are Camel-specific.", + "The camel-side filter uses the Camel-namespace and camel-case naming on camel-kafka and camel-aws2-sqs.")) + .containsExactly("camel-aws2-sqs", "camel-kafka"); + } + @Test void modelRoundTripsThroughJsonMapper() throws Exception { SecurityAdvisoryModel model = UpdateSecurityAdvisoriesMojo.parseAdvisory(fixture("CVE-2025-27636.md"));