public inbox for buildroot@busybox.net
 help / color / mirror / Atom feed
* [Buildroot] [PATCH 1/1] support/scripts/cve-check: Fix vulnerability timestamp to RFC 3339
@ 2026-02-24 14:56 Fabien Lehoussel via buildroot
  2026-02-27  9:15 ` Thomas Perale via buildroot
  0 siblings, 1 reply; 2+ messages in thread
From: Fabien Lehoussel via buildroot @ 2026-02-24 14:56 UTC (permalink / raw)
  To: buildroot; +Cc: Thomas Perale, Fabien Lehoussel

Normalize vulnerability timestamps to RFC 3339 format with explicit UTC
timezone suffix for CycloneDX 1.6 compliance.
This fixes validation errors in sbom-utility and makes the generated
SBOM with vulnerabilities compatible with DependencyTrack VEX parsers.

The NVD JSON data feeds provide timestamps in ISO 8601 format without timezone
information (e.g., "1999-01-01T05:00:00.000"), but CycloneDX 1.6 requires
RFC 3339 format with explicit timezone designation (e.g.,
"1999-01-01T05:00:00.000Z").

Add nvd_datetime_to_rfc3339() helper function to convert timestamps before
serialization.

Validation results:

Before fix:
  $ sbom-utility validate -i cve/cve_report_current.json
  [INFO] BOM valid against JSON schema: 'false'
  [INFO] (234) schema errors detected.

  Error example:
  {
    "type": "format",
    "field": "vulnerabilities.0.updated",
    "context": "(root).vulnerabilities.0.updated",
    "description": "Does not match format 'date-time'",
    "value": "2025-04-03T01:03:51.193"
  }

After fix:
  $ sbom-utility validate -i cve/cve_report_update.json
  [INFO] BOM valid against JSON schema: 'true'

Tested-with: sbom-utility v0.18.1
Signed-off-by: Fabien Lehoussel <fabien.lehoussel@smile.fr>
---
 support/scripts/cve-check | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/support/scripts/cve-check b/support/scripts/cve-check
index ff14e4b238..932c67bd12 100755
--- a/support/scripts/cve-check
+++ b/support/scripts/cve-check
@@ -15,6 +15,7 @@ from typing import TypedDict
 import argparse
 import sys
 import json
+import datetime
 
 import cve as cvecheck
 
@@ -118,6 +119,25 @@ def nvd_cve_references_to_cdx(references):
     return advisories
 
 
+def nvd_datetime_to_rfc3339(dt_string):
+    """
+    Normalize datetime string to RFC 3339 format with Z suffix.
+    NVD dates are already in ISO format, just need to add the Z suffix.
+    
+    Input:  "1999-01-01T05:00:00.000"
+    Output: "1999-01-01T05:00:00.000Z"
+    """
+    if not dt_string:
+        return None
+    
+    # If already has Z or timezone offset, return as is
+    if dt_string.endswith('Z') or '+' in dt_string or dt_string.endswith('-00:00'):
+        return dt_string
+    
+    # Otherwise just append Z
+    return dt_string + 'Z'
+
+
 def nvd_cve_to_cdx_vulnerability(nvd_cve):
     """
     Turns the CVE object fetched from the NVD API into a CycloneDX
@@ -134,10 +154,10 @@ def nvd_cve_to_cdx_vulnerability(nvd_cve):
             "url": "https://nvd.nist.gov/"
         },
         **({
-            "published": nvd_cve["published"],
+            "published": nvd_datetime_to_rfc3339(nvd_cve["published"]),
         } if "published" in nvd_cve else {}),
         **({
-            "updated": nvd_cve["lastModified"],
+            "updated": nvd_datetime_to_rfc3339(nvd_cve["lastModified"]),
         } if "lastModified" in nvd_cve else {}),
         **({
             "cwes": nvd_cve_weaknesses_to_cdx(nvd_cve["weaknesses"]),
-- 
2.43.0

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Buildroot] [PATCH 1/1] support/scripts/cve-check: Fix vulnerability timestamp to RFC 3339
  2026-02-24 14:56 [Buildroot] [PATCH 1/1] support/scripts/cve-check: Fix vulnerability timestamp to RFC 3339 Fabien Lehoussel via buildroot
@ 2026-02-27  9:15 ` Thomas Perale via buildroot
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Perale via buildroot @ 2026-02-27  9:15 UTC (permalink / raw)
  To: Fabien Lehoussel; +Cc: Thomas Perale, buildroot

Hi Fabien,

Good catch, thanks for taking the time looking at this.

I have some comments:

In reply of:
> Normalize vulnerability timestamps to RFC 3339 format with explicit UTC
> timezone suffix for CycloneDX 1.6 compliance.
> This fixes validation errors in sbom-utility and makes the generated
> SBOM with vulnerabilities compatible with DependencyTrack VEX parsers.

I took a look at the spec and if I'm not mistaking I didn't found reference
RFC3339 in the CDX Spec. It looks like this come from the JSON Schema
`date-time` data type that the CDX Spec use
https://json-schema.org/understanding-json-schema/reference/type#dates-and-times
https://datatracker.ietf.org/doc/html/rfc3339#section-5.6

I would include this information in the commit message and the docstring.

> The NVD JSON data feeds provide timestamps in ISO 8601 format without timezone
> information (e.g., "1999-01-01T05:00:00.000"), but CycloneDX 1.6 requires
> RFC 3339 format with explicit timezone designation (e.g.,
> "1999-01-01T05:00:00.000Z").
> 
> Add nvd_datetime_to_rfc3339() helper function to convert timestamps before
> serialization.
> 
> Validation results:
> 
> Before fix:
>   $ sbom-utility validate -i cve/cve_report_current.json
>   [INFO] BOM valid against JSON schema: 'false'
>   [INFO] (234) schema errors detected.
> 
>   Error example:
>   {
>     "type": "format",
>     "field": "vulnerabilities.0.updated",
>     "context": "(root).vulnerabilities.0.updated",
>     "description": "Does not match format 'date-time'",
>     "value": "2025-04-03T01:03:51.193"
>   }
> 
> After fix:
>   $ sbom-utility validate -i cve/cve_report_update.json
>   [INFO] BOM valid against JSON schema: 'true'
> 
> Tested-with: sbom-utility v0.18.1
> Signed-off-by: Fabien Lehoussel <fabien.lehoussel@smile.fr>

> ---
>  support/scripts/cve-check | 24 ++++++++++++++++++++++--
>  1 file changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/support/scripts/cve-check b/support/scripts/cve-check
> index ff14e4b238..932c67bd12 100755
> --- a/support/scripts/cve-check
> +++ b/support/scripts/cve-check
> @@ -15,6 +15,7 @@ from typing import TypedDict
>  import argparse
>  import sys
>  import json
> +import datetime

This import ended up not being used in your implementation.

>  
>  import cve as cvecheck
>  
> @@ -118,6 +119,25 @@ def nvd_cve_references_to_cdx(references):
>      return advisories
>  
>  
> +def nvd_datetime_to_rfc3339(dt_string):
> +    """
> +    Normalize datetime string to RFC 3339 format with Z suffix.
> +    NVD dates are already in ISO format, just need to add the Z suffix.
> +    
> +    Input:  "1999-01-01T05:00:00.000"
> +    Output: "1999-01-01T05:00:00.000Z"
> +    """

I would include the reference to the JSON Schema spec.

https://json-schema.org/understanding-json-schema/reference/type#dates-and-times
https://datatracker.ietf.org/doc/html/rfc3339#section-5.6

> +    if not dt_string:
> +        return None
> +    
> +    # If already has Z or timezone offset, return as is
> +    if dt_string.endswith('Z') or '+' in dt_string or dt_string.endswith('-00:00'):
> +        return dt_string
> +    
> +    # Otherwise just append Z
> +    return dt_string + 'Z'
> +
> +

I propose a more generic implementation with python datetime utils so we can
cover any edge case that we might not know of yet and normalize the output data.
As your other series uses the CVEList db which has another format for date this
might be useful.

https://docs.python.org/3/library/datetime.html#datetime.date.fromisoformat

```python
from datetime import datetime, timezone

def datetime_to_rfc3339(dt_string):
    dt = datetime.fromisoformat(dt_string.replace('Z', '+00:00'))
    
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    else:
        dt = dt.astimezone(timezone.utc)
        
    return dt.isoformat().replace('+00:00', 'Z')

if __name__ == "__main__":
    print(datetime_to_rfc3339("2010-10-20T00:00:00.000Z"))
    print(datetime_to_rfc3339("2025-08-02T12:15:28.050"))
    print(datetime_to_rfc3339("2025-08-02T12:15:28+02:00"))
    print(datetime_to_rfc3339("1999-01-01T05:00:00.000"))
```

But maybe this is overkill ?

>  def nvd_cve_to_cdx_vulnerability(nvd_cve):
>      """
>      Turns the CVE object fetched from the NVD API into a CycloneDX
> @@ -134,10 +154,10 @@ def nvd_cve_to_cdx_vulnerability(nvd_cve):
>              "url": "https://nvd.nist.gov/"
>          },
>          **({
> -            "published": nvd_cve["published"],
> +            "published": nvd_datetime_to_rfc3339(nvd_cve["published"]),
>          } if "published" in nvd_cve else {}),
>          **({
> -            "updated": nvd_cve["lastModified"],
> +            "updated": nvd_datetime_to_rfc3339(nvd_cve["lastModified"]),
>          } if "lastModified" in nvd_cve else {}),
>          **({
>              "cwes": nvd_cve_weaknesses_to_cdx(nvd_cve["weaknesses"]),
> -- 
> 2.43.0
> 
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-02-27  9:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-24 14:56 [Buildroot] [PATCH 1/1] support/scripts/cve-check: Fix vulnerability timestamp to RFC 3339 Fabien Lehoussel via buildroot
2026-02-27  9:15 ` Thomas Perale via buildroot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox