Re: [OE-core][PATCH v8 6/7] cve_check: Escape special characters in CPE 2.3 strings

2026-03-11 Thread Joshua Watt via lists.openembedded.org
On Mon, Mar 9, 2026 at 7:29 AM  wrote:
>
> From: Stefano Tondo 
>
> CPE 2.3 formatted string binding (cpe:2.3:...) requires
> backslash escaping for special meta-characters per NISTIR 7695.
> Characters like '++' and ':' in product names must be escaped.
>
> The CPE 2.3 specification defines two bindings:
> - URI binding (cpe:/...) uses percent-encoding
> - Formatted string (cpe:2.3:...) uses backslash escaping
>
> Escape the required meta-characters with backslash:
> - Backslash (\) -> \\
> - Question mark (?) -> \?
> - Asterisk (*) -> \*
> - Colon (:) -> \:
> - Plus (+) -> \+
>
> All other characters are kept as-is without encoding.
>
> Example CPE identifiers:
> - cpe:2.3:*:*:crow:1.0\+x:*:*:*:*:*:*:*
> - cpe:2.3:*:*:sdbus-c\+\+:2.2.1:*:*:*:*:*:*:*
>
> Signed-off-by: Stefano Tondo 

LGTM

Reviewed-by: Joshua Watt 

Note: This can be merged without needing to wait for the preceding
changes in this patch series

> ---
>  meta/lib/oe/cve_check.py | 38 +-
>  1 file changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
> index ae194f27cf..6555743514 100644
> --- a/meta/lib/oe/cve_check.py
> +++ b/meta/lib/oe/cve_check.py
> @@ -205,6 +205,35 @@ def get_patched_cves(d):
>  return patched_cves
>
>
> +def cpe_escape(value):
> +r"""
> +Escape special characters for CPE 2.3 formatted string binding.
> +
> +CPE 2.3 formatted string binding (cpe:2.3:...) uses backslash escaping
> +for special meta-characters, NOT percent-encoding. Percent-encoding is
> +only used in the URI binding (cpe:/...).
> +
> +According to NISTIR 7695, these characters need escaping:
> +- Backslash (\) -> \\
> +- Question mark (?) -> \?
> +- Asterisk (*) -> \*
> +- Colon (:) -> \:
> +- Plus (+) -> \+ (required by some SBOM validators)
> +"""
> +if not value:
> +return value
> +
> +# Escape special meta-characters for CPE 2.3 formatted string binding
> +# Order matters: escape backslash first to avoid double-escaping
> +result = value.replace('\\', '')
> +result = result.replace('?', '\\?')
> +result = result.replace('*', '\\*')
> +result = result.replace(':', '\\:')
> +result = result.replace('+', '\\+')
> +
> +return result
> +
> +
>  def get_cpe_ids(cve_product, version):
>  """
>  Get list of CPE identifiers for the given product and version
> @@ -221,7 +250,14 @@ def get_cpe_ids(cve_product, version):
>  else:
>  vendor = "*"
>
> -cpe_id = 'cpe:2.3:*:{}:{}:{}:*:*:*:*:*:*:*'.format(vendor, product, 
> version)
> +# Encode special characters per CPE 2.3 specification
> +encoded_vendor = cpe_escape(vendor) if vendor != "*" else vendor
> +encoded_product = cpe_escape(product)
> +encoded_version = cpe_escape(version)
> +
> +cpe_id = 'cpe:2.3:*:{}:{}:{}:*:*:*:*:*:*:*'.format(
> +encoded_vendor, encoded_product, encoded_version
> +)
>  cpe_ids.append(cpe_id)
>
>  return cpe_ids
> --
> 2.53.0
>

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#232912): 
https://lists.openembedded.org/g/openembedded-core/message/232912
Mute This Topic: https://lists.openembedded.org/mt/118221143/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-



[OE-core][PATCH v8 6/7] cve_check: Escape special characters in CPE 2.3 strings

2026-03-09 Thread Stefano Tondo via lists.openembedded.org
From: Stefano Tondo 

CPE 2.3 formatted string binding (cpe:2.3:...) requires
backslash escaping for special meta-characters per NISTIR 7695.
Characters like '++' and ':' in product names must be escaped.

The CPE 2.3 specification defines two bindings:
- URI binding (cpe:/...) uses percent-encoding
- Formatted string (cpe:2.3:...) uses backslash escaping

Escape the required meta-characters with backslash:
- Backslash (\) -> \\
- Question mark (?) -> \?
- Asterisk (*) -> \*
- Colon (:) -> \:
- Plus (+) -> \+

All other characters are kept as-is without encoding.

Example CPE identifiers:
- cpe:2.3:*:*:crow:1.0\+x:*:*:*:*:*:*:*
- cpe:2.3:*:*:sdbus-c\+\+:2.2.1:*:*:*:*:*:*:*

Signed-off-by: Stefano Tondo 
---
 meta/lib/oe/cve_check.py | 38 +-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
index ae194f27cf..6555743514 100644
--- a/meta/lib/oe/cve_check.py
+++ b/meta/lib/oe/cve_check.py
@@ -205,6 +205,35 @@ def get_patched_cves(d):
 return patched_cves
 
 
+def cpe_escape(value):
+r"""
+Escape special characters for CPE 2.3 formatted string binding.
+
+CPE 2.3 formatted string binding (cpe:2.3:...) uses backslash escaping
+for special meta-characters, NOT percent-encoding. Percent-encoding is
+only used in the URI binding (cpe:/...).
+
+According to NISTIR 7695, these characters need escaping:
+- Backslash (\) -> \\
+- Question mark (?) -> \?
+- Asterisk (*) -> \*
+- Colon (:) -> \:
+- Plus (+) -> \+ (required by some SBOM validators)
+"""
+if not value:
+return value
+
+# Escape special meta-characters for CPE 2.3 formatted string binding
+# Order matters: escape backslash first to avoid double-escaping
+result = value.replace('\\', '')
+result = result.replace('?', '\\?')
+result = result.replace('*', '\\*')
+result = result.replace(':', '\\:')
+result = result.replace('+', '\\+')
+
+return result
+
+
 def get_cpe_ids(cve_product, version):
 """
 Get list of CPE identifiers for the given product and version
@@ -221,7 +250,14 @@ def get_cpe_ids(cve_product, version):
 else:
 vendor = "*"
 
-cpe_id = 'cpe:2.3:*:{}:{}:{}:*:*:*:*:*:*:*'.format(vendor, product, 
version)
+# Encode special characters per CPE 2.3 specification
+encoded_vendor = cpe_escape(vendor) if vendor != "*" else vendor
+encoded_product = cpe_escape(product)
+encoded_version = cpe_escape(version)
+
+cpe_id = 'cpe:2.3:*:{}:{}:{}:*:*:*:*:*:*:*'.format(
+encoded_vendor, encoded_product, encoded_version
+)
 cpe_ids.append(cpe_id)
 
 return cpe_ids
-- 
2.53.0


-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#232715): 
https://lists.openembedded.org/g/openembedded-core/message/232715
Mute This Topic: https://lists.openembedded.org/mt/118221143/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-