Skip to content

Instantly share code, notes, and snippets.

@kiang
Created August 23, 2023 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiang/e90f5076812c44ca99872b12818ba5ad to your computer and use it in GitHub Desktop.
Save kiang/e90f5076812c44ca99872b12818ba5ad to your computer and use it in GitHub Desktop.
a script to convert CycloneDX sbom to another one with cpe inside
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"serialNumber": "urn:uuid:0de0d81f-ec39-4e9a-8413-5db8ed56fa8d",
"version": 1,
"metadata": {
"timestamp": "2023-07-24T13:54:33.087Z",
"tools": [
{
"vendor": "cyclonedx",
"name": "cdxgen",
"version": "8.4.13"
}
],
"authors": [
{
"name": "Prabhu Subramanian",
"email": "prabhu@appthreat.com"
}
]
},
"components": [
{
"publisher": "",
"group": "",
"name": "bootstrap",
"version": "5.1.0",
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"scope": "optional",
"licenses": [
{
"license": {
"id": "MIT",
"url": "https://opensource.org/licenses/MIT"
}
}
],
"purl": "pkg:npm/bootstrap@5.1.0",
"externalReferences": [
{
"type": "website",
"url": "https://getbootstrap.com/"
},
{
"type": "vcs",
"url": "git+https://github.com/twbs/bootstrap.git"
}
],
"type": "library",
"bom-ref": "pkg:npm/bootstrap@5.1.0",
"properties": [
{
"name": "SrcFile",
"value": "/home/kiang/public_html/sbom/src/aad-twfido/src/Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js"
}
],
"cpe": "cpe:2.3:a:getbootstrap:bootstrap:5.1.0:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "BouncyCastle.Cryptography",
"version": "2.0.0",
"description": "",
"licenses": [],
"purl": "pkg:nuget/BouncyCastle.Cryptography@2.0.0",
"type": "library",
"bom-ref": "pkg:nuget/BouncyCastle.Cryptography@2.0.0",
"cpe": "cpe:2.3:a:bouncycastle:cryptography:2.0.0:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "ITfoxtec.Identity.Saml2.MvcCore",
"version": "4.8.6",
"description": "ASP.NET MVC Core is supportet by the ITfoxtec Identity SAML2 MVC Core package which helps to integrate the ITfoxtec SAML 2.0 package and add support for SAML-P and SAML 2.0 tokens.\n\n Support .NET Core 2.1, 2.2, 3.0 and 3.1\n Support .NET Framework 4.6.2 and 4.7.2",
"licenses": [
{
"license": {
"id": "BSD-3-Clause",
"url": "https://opensource.org/licenses/BSD-3-Clause"
}
}
],
"purl": "pkg:nuget/ITfoxtec.Identity.Saml2.MvcCore@4.8.6",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/ITfoxtec.Identity.Saml2.MvcCore/4.8.6/"
},
{
"type": "vcs",
"url": "https://itfoxtec.com/IdentitySaml2"
}
],
"type": "library",
"bom-ref": "pkg:nuget/ITfoxtec.Identity.Saml2.MvcCore@4.8.6",
"cpe": "cpe:2.3:a:itfoxtec:identity-saml-mvccore:4.8.6:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "LigerShark.WebOptimizer.Core",
"version": "3.0.378",
"description": "A runtime bundler and minifier for ASP.NET Core",
"licenses": [
{
"license": {
"name": "CUSTOM",
"url": "https://github.com/ligershark/WebOptimizer/blob/master/LICENSE.txt"
}
}
],
"purl": "pkg:nuget/LigerShark.WebOptimizer.Core@3.0.378",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/LigerShark.WebOptimizer.Core/3.0.378/"
},
{
"type": "vcs",
"url": "https://github.com/ligershark/WebOptimizer"
}
],
"type": "library",
"bom-ref": "pkg:nuget/LigerShark.WebOptimizer.Core@3.0.378",
"cpe": "cpe:2.3:a:ligershark:weboptimizer:3.0.378:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Microsoft.VisualStudio.Azure.Containers.Tools.Targets",
"version": "1.17.0",
"description": "Targets files to enable the Visual Studio Tools for Containers.",
"licenses": [
{
"license": {
"name": "CUSTOM",
"url": "https://www.nuget.org/packages/Microsoft.VisualStudio.Azure.Containers.Tools.Targets/1.10.6/license"
}
}
],
"purl": "pkg:nuget/Microsoft.VisualStudio.Azure.Containers.Tools.Targets@1.17.0",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Microsoft.VisualStudio.Azure.Containers.Tools.Targets/1.17.0/"
},
{
"type": "vcs",
"url": "https://aka.ms/vscontainertools"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Microsoft.VisualStudio.Azure.Containers.Tools.Targets@1.17.0",
"cpe": "cpe:2.3:a:microsoft:visualstudio-azure-containers-tools-targets:1.17.0:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Net.Codecrete.QrCodeGenerator",
"version": "2.0.3",
"description": "QR Code Generator for .NET \u2013 simple, compact and well. Derived from tried and tested implementation by project Nayuki.\n\nCore features:\n- Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard\n- Output formats: Raw modules/pixels of the QR symbol, SVG XML string, raster bitmap\n- Encodes numeric and special-alphanumeric text in less space than general text\n- Open source code under the permissive MIT License\n- Significantly shorter code but more documentation compared to competing libraries\n- Built for .NET Standard 2.0 and therefore runs on most modern .NET platforms (.NET Core, .NET Framework, Mono etc.).\n\nManual parameters:\n- You can specify the minimum and maximum version number allowed, and the library will automatically choose the smallest version in the range that fits the data.\n- You can specify the mask pattern manually, otherwise library will automatically evaluate all 8 masks and select the optimal one.\n- You can specify an error correction level, or optionally allow the library to boost it if it doesn't increase the version number.\n- You can create a list of data segments manually and add ECI segments.\n\nOptional advanced features:\n- Encodes Japanese Unicode text in Kanji mode to save a lot of space compared to UTF-8 bytes\n- Computes optimal segment mode switching for text with mixed numeric/alphanumeric/general/kanji parts",
"licenses": [
{
"license": {
"url": "https://opensource.org/licenses/MIT"
}
}
],
"purl": "pkg:nuget/Net.Codecrete.QrCodeGenerator@2.0.3",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Net.Codecrete.QrCodeGenerator/2.0.3/"
},
{
"type": "vcs",
"url": "https://github.com/manuelbl/QrCodeGenerator"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Net.Codecrete.QrCodeGenerator@2.0.3",
"cpe": "cpe:2.3:a:manuelbl:qrcodegenerator:2.0.3:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Newtonsoft.Json",
"version": "13.0.3",
"description": "Json.NET is a popular high-performance JSON framework for .NET",
"licenses": [
{
"license": {
"id": "MIT",
"url": "https://opensource.org/licenses/MIT"
}
}
],
"purl": "pkg:nuget/Newtonsoft.Json@13.0.3",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Newtonsoft.Json/13.0.3/"
},
{
"type": "vcs",
"url": "https://www.newtonsoft.com/json"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Newtonsoft.Json@13.0.3",
"cpe": "cpe:2.3:a:newtonsoft:json:13.0.3:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Polly",
"version": "7.2.3",
"description": "Polly is a library that allows developers to express resilience and transient fault handling policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.",
"licenses": [
{
"license": {
"id": "BSD-3-Clause",
"url": "https://opensource.org/licenses/BSD-3-Clause"
}
}
],
"purl": "pkg:nuget/Polly@7.2.3",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Polly/7.2.3/"
},
{
"type": "vcs",
"url": "https://github.com/App-vNext/Polly"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Polly@7.2.3",
"cpe": "cpe:2.3:a:app-vnext:polly:7.2.3:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "BenchmarkDotNet",
"version": "0.13.5",
"description": "Powerful .NET library for benchmarking",
"licenses": [
{
"license": {
"id": "MIT",
"url": "https://opensource.org/licenses/MIT"
}
}
],
"purl": "pkg:nuget/BenchmarkDotNet@0.13.5",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/BenchmarkDotNet/0.13.5/"
},
{
"type": "vcs",
"url": "https://github.com/dotnet/BenchmarkDotNet"
}
],
"type": "library",
"bom-ref": "pkg:nuget/BenchmarkDotNet@0.13.5",
"cpe": "cpe:2.3:a:dotnet:benchmarkdotnet:0.13.5:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Moq",
"version": "4.18.4",
"description": "Moq is the most popular and friendly mocking framework for .NET",
"licenses": [
{
"license": {
"name": "CUSTOM",
"url": "https://raw.githubusercontent.com/moq/moq4/master/License.txt"
}
}
],
"purl": "pkg:nuget/Moq@4.18.4",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Moq/4.18.4/"
},
{
"type": "vcs",
"url": "https://github.com/moq/moq4"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Moq@4.18.4",
"cpe": "cpe:2.3:a:moq:moq-:4.18.4:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Microsoft.AspNetCore.TestHost",
"version": "6.0.13",
"description": "ASP.NET Core web server for writing and running tests.\n\nThis package was built from the source code at https://github.com/aspnet/AspNetCore/tree/e276c8174b8bfdeb70efceafa81c75f8badbc8db",
"licenses": [
{
"license": {
"id": "Apache-2.0",
"url": "https://opensource.org/licenses/Apache-2.0"
}
}
],
"purl": "pkg:nuget/Microsoft.AspNetCore.TestHost@6.0.13",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Microsoft.AspNetCore.TestHost/6.0.13/"
},
{
"type": "vcs",
"url": "https://asp.net/"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Microsoft.AspNetCore.TestHost@6.0.13",
"cpe": "cpe:2.3:a:microsoft:aspnetcore-testhost:6.0.13:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Microsoft.Extensions.Logging.Abstractions",
"version": "6.0.3",
"description": "Logging abstractions for Microsoft.Extensions.Logging.\nCommonly used types:\nMicrosoft.Extensions.Logging.ILogger\nMicrosoft.Extensions.Logging.ILoggerFactory\nMicrosoft.Extensions.Logging.ILogger<TCategoryName>\nMicrosoft.Extensions.Logging.LogLevel\nMicrosoft.Extensions.Logging.Logger<T>\nMicrosoft.Extensions.Logging.LoggerMessage\nMicrosoft.Extensions.Logging.Abstractions.NullLogger",
"licenses": [
{
"license": {
"id": "Apache-2.0",
"url": "https://opensource.org/licenses/Apache-2.0"
}
}
],
"purl": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.3",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Microsoft.Extensions.Logging.Abstractions/6.0.3/"
},
{
"type": "vcs",
"url": "https://asp.net/"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.3",
"cpe": "cpe:2.3:a:microsoft:extensions-logging-abstractions:6.0.3:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "Microsoft.NET.Test.Sdk",
"version": "17.3.2",
"description": "The MSbuild targets and properties for building .NET test projects.",
"licenses": [
{
"license": {
"name": "CUSTOM",
"url": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm"
}
}
],
"purl": "pkg:nuget/Microsoft.NET.Test.Sdk@17.3.2",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/Microsoft.NET.Test.Sdk/17.3.2/"
},
{
"type": "vcs",
"url": "https://github.com/microsoft/vstest/"
}
],
"type": "library",
"bom-ref": "pkg:nuget/Microsoft.NET.Test.Sdk@17.3.2",
"cpe": "cpe:2.3:a:microsoft:net-test-sdk:17.3.2:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "xunit",
"version": "2.4.2",
"description": "xUnit.net is a developer testing framework, built to support Test Driven Development, with a design goal of extreme simplicity and alignment with framework features.\n\nInstalling this package installs xunit.core, xunit.assert, and xunit.analyzers.",
"licenses": [
{
"license": {
"name": "CUSTOM",
"url": "https://raw.githubusercontent.com/xunit/xunit/master/license.txt"
}
}
],
"purl": "pkg:nuget/xunit@2.4.2",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/xunit/2.4.2/"
},
{
"type": "vcs",
"url": "https://github.com/xunit/xunit"
}
],
"type": "library",
"bom-ref": "pkg:nuget/xunit@2.4.2",
"cpe": "cpe:2.3:a:xunit:xunit:2.4.2:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "xunit.runner.visualstudio",
"version": "2.4.5",
"description": "Visual Studio 2012+ Test Explorer runner for the xUnit.net framework. Capable of running xUnit.net v1.9.2 and v2.0+ tests. Supports .NET 2.0 or later, .NET Core 1.0 or later, and Universal Windows 10.0 or later.",
"licenses": [
{
"license": {
"name": "CUSTOM",
"url": "https://raw.githubusercontent.com/xunit/xunit/master/license.txt"
}
}
],
"purl": "pkg:nuget/xunit.runner.visualstudio@2.4.5",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/xunit.runner.visualstudio/2.4.5/"
},
{
"type": "vcs",
"url": "https://github.com/xunit/xunit"
}
],
"type": "library",
"bom-ref": "pkg:nuget/xunit.runner.visualstudio@2.4.5",
"cpe": "cpe:2.3:a:xunit:xunit:2.4.5:*:*:*:*:*:*:*"
},
{
"publisher": "",
"group": "",
"name": "coverlet.collector",
"version": "3.1.2",
"description": "Coverlet is a cross platform code coverage library for .NET, with support for line, branch and method coverage.",
"licenses": [
{
"license": {
"id": "MIT",
"url": "https://opensource.org/licenses/MIT"
}
}
],
"purl": "pkg:nuget/coverlet.collector@3.1.2",
"externalReferences": [
{
"type": "website",
"url": "https://www.nuget.org/packages/coverlet.collector/3.1.2/"
},
{
"type": "vcs",
"url": "http://github.com/tonerdo/coverlet"
}
],
"type": "library",
"bom-ref": "pkg:nuget/coverlet.collector@3.1.2",
"cpe": "cpe:2.3:a:tonerdo:coverlet:3.1.2:*:*:*:*:*:*:*"
}
],
"services": [],
"dependencies": []
}
<?php
$basePath = dirname(__DIR__);
$text = file_get_contents(__DIR__ . '/purl2cpe.csv');
foreach (glob($basePath . '/docs/*/bom.json') as $jsonFile) {
$json = json_decode(file_get_contents($jsonFile), true);
foreach ($json['components'] as $k => $v) {
$parts = explode('@', $v['purl']);
$pos = strpos($text, $parts[0] . ',');
if (false !== $pos) {
$pos = strpos($text, ',', $pos) + 1;
$posEnd = strpos($text, "\n", $pos);
$cpe = explode(':', substr($text, $pos, $posEnd - $pos));
$cpe[5] = $v['version'];
$json['components'][$k]['cpe'] = implode(':', $cpe);
} else {
$cpe = [
'cpe',
'2.3',
'part' => 'a',
'vendor' => '',
'product' => '',
'version' => $parts[1],
'update' => '*',
'edition' => '*',
'language' => '*',
'sw_edition' => '*',
'target_sw' => '*',
'target_hw' => '*',
'other' => '*',
];
if (!empty($v['externalReferences'])) {
foreach ($v['externalReferences'] as $ref) {
if ($ref['type'] === 'vcs') {
$pos = strpos($ref['url'], 'github.com');
if (false !== $pos) {
$pos += 11;
$nameParts = explode('/', substr($ref['url'], $pos));
if (count($nameParts) === 2) {
foreach ($nameParts as $i => $j) {
$nameParts[$i] = strtolower($j);
}
$cpe['vendor'] = $nameParts[0];
$cpe['product'] = $nameParts[1];
$cpe['product'] = str_replace('.git', '', $cpe['product']);
$cpe['product'] = implode('-', preg_split('/[^a-z]+/i', $cpe['product']));
$json['components'][$k]['cpe'] = implode(':', $cpe);
}
}
}
}
}
if (empty($cpe['product'])) {
$pos = strpos($parts[0], '/');
if (false !== $pos) {
$pos += 1;
$nameParts = preg_split('/[^a-z]+/i', substr($parts[0], $pos));
foreach ($nameParts as $i => $j) {
$nameParts[$i] = strtolower($j);
}
if (count($nameParts) === 1) {
$cpe['vendor'] = $nameParts[0];
$cpe['product'] = $nameParts[0];
} else {
$cpe['vendor'] = array_shift($nameParts);
$cpe['product'] = implode('-', $nameParts);
}
$json['components'][$k]['cpe'] = implode(':', $cpe);
}
}
}
}
$p = pathinfo($jsonFile);
file_put_contents($p['dirname'] . '/' . $p['filename'] . '.cpe.json', json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment