[WIP] CycloneDX v2.0 Specification - #652
Conversation
| // Pattern for markdown links at the end | ||
| const markdownLinkPattern = /\]\([^)]+\)$/; | ||
|
|
||
| return urlPattern.test(text) || markdownLinkPattern.test(text); |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
| // Pattern for markdown links at the end | ||
| const markdownLinkPattern = /\]\([^)]+\)$/; | ||
|
|
||
| return urlPattern.test(text) || markdownLinkPattern.test(text); |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
To fix this safely without changing intended bundling behavior, validate both CLI paths against a strict policy before any filesystem access. For this script, the least disruptive policy is: only allow paths that resolve under the current working directory (process.cwd()), after normalization.
Best implementation in tools/src/main/js/bundler/bundle-schemas.js:
- Add a helper that:
- resolves the user path with
path.resolve, - computes
path.relative(baseDir, resolvedPath), - rejects if the result is absolute or starts with
..(meaning outside base).
- resolves the user path with
- Use this helper inside
bundleSchemasfor bothmodelsDirectoryandrootSchemaPathinstead of directpath.resolve(...). - Keep all existing behavior otherwise (same flow, same
fs.access, same outputs), only adding early validation error on unsafe paths.
No external dependencies are needed; Node’s built-in path is sufficient.
| @@ -16,6 +16,18 @@ | ||
| return typeof value === 'object' && value !== null; | ||
| } | ||
|
|
||
| function resolvePathWithinBase(baseDir, userProvidedPath, argName) { | ||
| const absoluteBaseDir = path.resolve(baseDir); | ||
| const resolvedPath = path.resolve(userProvidedPath); | ||
| const relativePath = path.relative(absoluteBaseDir, resolvedPath); | ||
|
|
||
| if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) { | ||
| throw new Error(`Invalid ${argName}: path must be within ${absoluteBaseDir}`); | ||
| } | ||
|
|
||
| return resolvedPath; | ||
| } | ||
|
|
||
| /** | ||
| * Resolve a JSON Pointer (RFC6901) against an object. Returns { ok: boolean, value?: any, error?: string } | ||
| */ | ||
| @@ -179,8 +191,9 @@ | ||
|
|
||
| async function bundleSchemas(modelsDirectory, rootSchemaPath, options = {}) { | ||
| try { | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
| const baseDir = process.cwd(); | ||
| const absoluteModelsDir = resolvePathWithinBase(baseDir, modelsDirectory, 'modelsDirectory'); | ||
| const absoluteRootPath = resolvePathWithinBase(baseDir, rootSchemaPath, 'rootSchemaPath'); | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); |
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
To fix this without changing intended functionality, validate that the user-provided rootSchemaPath resolves to a file within the provided modelsDirectory tree before using it in filesystem operations. The safest approach here is:
- Resolve both inputs to absolute paths.
- Compute
path.relative(absoluteModelsDir, absoluteRootPath). - Reject if the relative path is empty? (empty is fine if same path), absolute, or starts with
..(meaning outside base directory). - Optionally keep existence checks after boundary validation.
In tools/src/main/js/bundler/bundle-schemas.js, update bundleSchemas right after lines 182–183 to enforce this containment rule and throw a clear error when violated. No new dependencies are required; use built-in path.
| @@ -182,6 +182,11 @@ | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
|
|
||
| const relativeRootPath = path.relative(absoluteModelsDir, absoluteRootPath); | ||
| if (relativeRootPath.startsWith('..') || path.isAbsolute(relativeRootPath)) { | ||
| throw new Error(`Root schema path must be within models directory: ${absoluteModelsDir}`); | ||
| } | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); |
| console.log(`Output (minified): ${minifiedPath}\n`); | ||
|
|
||
| // Read all schema files in the models directory | ||
| const files = await fs.readdir(absoluteModelsDir); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
To fix this safely without changing intended behavior, validate both CLI-supplied paths (modelsDirectory and rootSchemaPath) against a trusted base directory before using them in filesystem operations. The best approach here is:
- Define a trusted base directory for this script execution (for example,
process.cwd()). - Resolve user inputs relative to that base.
- Enforce containment: ensure each resolved path is either exactly the base directory or starts with
base + path.sep. - Reject invalid/outside paths before any
fs.access,fs.readdir, or file reads.
In tools/src/main/js/bundler/bundle-schemas.js, add a helper like resolvePathWithinBase(baseDir, userPath, label) near existing utility functions, and replace direct path.resolve(...) usage in bundleSchemas with this checked resolver. No new package dependency is needed; Node’s built-in path is sufficient.
| @@ -16,6 +16,15 @@ | ||
| return typeof value === 'object' && value !== null; | ||
| } | ||
|
|
||
| function resolvePathWithinBase(baseDir, userPath, label) { | ||
| const absoluteBase = path.resolve(baseDir); | ||
| const absolutePath = path.resolve(absoluteBase, userPath); | ||
| if (absolutePath !== absoluteBase && !absolutePath.startsWith(absoluteBase + path.sep)) { | ||
| throw new Error(`Invalid ${label}: path must be within ${absoluteBase}`); | ||
| } | ||
| return absolutePath; | ||
| } | ||
|
|
||
| /** | ||
| * Resolve a JSON Pointer (RFC6901) against an object. Returns { ok: boolean, value?: any, error?: string } | ||
| */ | ||
| @@ -179,8 +188,9 @@ | ||
|
|
||
| async function bundleSchemas(modelsDirectory, rootSchemaPath, options = {}) { | ||
| try { | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
| const baseDir = process.cwd(); | ||
| const absoluteModelsDir = resolvePathWithinBase(baseDir, modelsDirectory, 'models directory'); | ||
| const absoluteRootPath = resolvePathWithinBase(baseDir, rootSchemaPath, 'root schema path'); | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); |
| const schemaPath = path.join(absoluteModelsDir, file); | ||
| console.log(` Reading ${file}...`); | ||
|
|
||
| const content = await fs.readFile(schemaPath, 'utf8'); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
The best fix is to canonicalize and constrain both user-provided paths to an approved root directory before any file operations.
For this script, the least disruptive approach is:
- Define a trusted root (for example,
process.cwd()for CLI usage). - Resolve user inputs relative to that root.
- Canonicalize with
fs.realpath(after existence checks). - Enforce containment with
path.relativechecks (!rel.startsWith('..') && !path.isAbsolute(rel)). - Use only the validated canonical paths afterward.
This preserves existing behavior for normal relative invocations (like ./schema/...) while preventing directory traversal or arbitrary absolute path targeting outside the project working tree.
Edit region: tools/src/main/js/bundler/bundle-schemas.js, inside bundleSchemas where absoluteModelsDir / absoluteRootPath are computed and checked (lines ~182–187 in the snippet). No new dependency is needed.
| @@ -179,13 +179,27 @@ | ||
|
|
||
| async function bundleSchemas(modelsDirectory, rootSchemaPath, options = {}) { | ||
| try { | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
| const trustedRoot = await fs.realpath(process.cwd()); | ||
| const candidateModelsDir = path.resolve(trustedRoot, modelsDirectory); | ||
| const candidateRootPath = path.resolve(trustedRoot, rootSchemaPath); | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); | ||
| // Verify paths exist before canonicalization | ||
| await fs.access(candidateModelsDir); | ||
| await fs.access(candidateRootPath); | ||
|
|
||
| const absoluteModelsDir = await fs.realpath(candidateModelsDir); | ||
| const absoluteRootPath = await fs.realpath(candidateRootPath); | ||
|
|
||
| // Ensure both user-supplied paths are contained within trusted root | ||
| const modelsDirRelative = path.relative(trustedRoot, absoluteModelsDir); | ||
| const rootPathRelative = path.relative(trustedRoot, absoluteRootPath); | ||
| const modelsDirInRoot = modelsDirRelative && !modelsDirRelative.startsWith('..') && !path.isAbsolute(modelsDirRelative); | ||
| const rootPathInRoot = rootPathRelative && !rootPathRelative.startsWith('..') && !path.isAbsolute(rootPathRelative); | ||
|
|
||
| if (!modelsDirInRoot || !rootPathInRoot) { | ||
| throw new Error('Input paths must be within the current working directory'); | ||
| } | ||
|
|
||
| const rootSchemaFilename = path.basename(absoluteRootPath); | ||
| const rootSchemaDir = path.dirname(absoluteRootPath); | ||
|
|
|
|
||
| // Read the root schema | ||
| console.log(`\nReading root schema...`); | ||
| const rootContent = await fs.readFile(absoluteRootPath, 'utf8'); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
General fix: validate user-controlled paths against an explicit trusted root before using them in filesystem operations. Normalization alone is insufficient; enforce containment (candidate must stay under safeRoot) after resolving absolute paths.
Best fix here (without changing intended functionality too much): in bundleSchemas, derive a safeRootDir from process.cwd() (or options.safeRootDir if provided), resolve both modelsDirectory and rootSchemaPath, and reject execution if either resolved path is outside the safe root. This keeps current CLI behavior for normal in-repo usage while preventing arbitrary absolute/parent traversal paths.
Changes needed in tools/src/main/js/bundler/bundle-schemas.js:
- Add a small helper function to check whether a target path is inside a base directory.
- In
bundleSchemas(around lines 180–184), computesafeRootDir. - After computing
absoluteModelsDirandabsoluteRootPath, validate both with the helper and throw an error on violation. - No new dependencies required.
| @@ -16,6 +16,11 @@ | ||
| return typeof value === 'object' && value !== null; | ||
| } | ||
|
|
||
| function isPathInside(basePath, targetPath) { | ||
| const relative = path.relative(basePath, targetPath); | ||
| return relative && !relative.startsWith('..') && !path.isAbsolute(relative); | ||
| } | ||
|
|
||
| /** | ||
| * Resolve a JSON Pointer (RFC6901) against an object. Returns { ok: boolean, value?: any, error?: string } | ||
| */ | ||
| @@ -179,9 +184,14 @@ | ||
|
|
||
| async function bundleSchemas(modelsDirectory, rootSchemaPath, options = {}) { | ||
| try { | ||
| const safeRootDir = path.resolve(options.safeRootDir || process.cwd()); | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
|
|
||
| if (!isPathInside(safeRootDir, absoluteModelsDir) || !isPathInside(safeRootDir, absoluteRootPath)) { | ||
| throw new Error(`Input paths must be within safe root: ${safeRootDir}`); | ||
| } | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); |
| // Write bundled (pretty) version | ||
| console.log('\nWriting bundled schema...'); | ||
| const prettyJson = JSON.stringify(finalSchema, null, 2); | ||
| await fs.writeFile(bundledPath, prettyJson); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
To fix this without changing intended functionality, validate that the computed output paths stay within a safe, expected root directory before writing files. Since outputs are derived from rootSchemaPath, the natural safe root is absoluteModelsDir (the provided models directory). After resolving/normalizing paths, ensure:
absoluteRootPathis insideabsoluteModelsDirbundledPathandminifiedPathare insideabsoluteModelsDir
Use path.relative(root, candidate) and reject when result is absolute or starts with .. (or equals ..). This is a robust containment check and avoids prefix tricks. Implement a small helper in tools/src/main/js/bundler/bundle-schemas.js and call it in bundleSchemas immediately after path resolution and before writes.
| @@ -16,6 +16,11 @@ | ||
| return typeof value === 'object' && value !== null; | ||
| } | ||
|
|
||
| function isPathWithinDirectory(parentDir, targetPath) { | ||
| const relative = path.relative(parentDir, targetPath); | ||
| return relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative); | ||
| } | ||
|
|
||
| /** | ||
| * Resolve a JSON Pointer (RFC6901) against an object. Returns { ok: boolean, value?: any, error?: string } | ||
| */ | ||
| @@ -186,6 +191,10 @@ | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); | ||
|
|
||
| if (!isPathWithinDirectory(absoluteModelsDir, absoluteRootPath)) { | ||
| throw new Error(`Root schema path must be within models directory: ${absoluteModelsDir}`); | ||
| } | ||
|
|
||
| const rootSchemaFilename = path.basename(absoluteRootPath); | ||
| const rootSchemaDir = path.dirname(absoluteRootPath); | ||
|
|
||
| @@ -200,6 +209,10 @@ | ||
| const bundledPath = path.join(rootSchemaDir, bundledFilename); | ||
| const minifiedPath = path.join(rootSchemaDir, minifiedFilename); | ||
|
|
||
| if (!isPathWithinDirectory(absoluteModelsDir, bundledPath) || !isPathWithinDirectory(absoluteModelsDir, minifiedPath)) { | ||
| throw new Error(`Output paths must be within models directory: ${absoluteModelsDir}`); | ||
| } | ||
|
|
||
| console.log(`Output (bundled): ${bundledPath}`); | ||
| console.log(`Output (minified): ${minifiedPath}\n`); | ||
|
|
| console.log('\nWriting bundled schema...'); | ||
| const prettyJson = JSON.stringify(finalSchema, null, 2); | ||
| await fs.writeFile(bundledPath, prettyJson); | ||
| const bundledStats = await fs.stat(bundledPath); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
To fix this, validate and constrain user-provided paths before they are used to derive output file locations. In general, normalize untrusted paths (path.resolve) and enforce containment within a trusted root directory. This preserves current functionality for valid inputs while preventing arbitrary filesystem access.
Best single fix here: in bundleSchemas (around lines 182–183), resolve both modelsDirectory and rootSchemaPath, then verify both are inside a trusted base (use process.cwd() for CLI-compatible behavior). Add a helper that checks targetPath is equal to the base or starts with base + path.sep after normalization. Throw an error if validation fails. This prevents rootSchemaDir (and thus bundledPath/minifiedPath) from pointing outside the allowed workspace.
Changes needed in tools/src/main/js/bundler/bundle-schemas.js:
- Add a small helper function (no new dependency) for containment check.
- In
bundleSchemas, defineallowedBaseDir = path.resolve(process.cwd()). - Validate
absoluteModelsDirandabsoluteRootPathagainstallowedBaseDirbefore file access/writes.
| @@ -16,6 +16,12 @@ | ||
| return typeof value === 'object' && value !== null; | ||
| } | ||
|
|
||
| function isPathWithinBase(basePath, targetPath) { | ||
| const normalizedBase = path.resolve(basePath); | ||
| const normalizedTarget = path.resolve(targetPath); | ||
| return normalizedTarget === normalizedBase || normalizedTarget.startsWith(normalizedBase + path.sep); | ||
| } | ||
|
|
||
| /** | ||
| * Resolve a JSON Pointer (RFC6901) against an object. Returns { ok: boolean, value?: any, error?: string } | ||
| */ | ||
| @@ -181,7 +187,15 @@ | ||
| try { | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
| const allowedBaseDir = path.resolve(process.cwd()); | ||
|
|
||
| if (!isPathWithinBase(allowedBaseDir, absoluteModelsDir)) { | ||
| throw new Error(`Models directory must be within ${allowedBaseDir}`); | ||
| } | ||
| if (!isPathWithinBase(allowedBaseDir, absoluteRootPath)) { | ||
| throw new Error(`Root schema path must be within ${allowedBaseDir}`); | ||
| } | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); |
| const lineCount = minifiedJson.split('\n').length; | ||
| console.log(` Minified JSON is on ${lineCount} line(s)`); | ||
|
|
||
| await fs.writeFile(minifiedPath, minifiedJson); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
To fix this without changing intended behavior, validate that all filesystem operations remain within a trusted base directory. The best fit here is to derive a safe base from the provided models directory (already a required input), normalize/resolve all relevant paths, and reject any path that escapes that base.
In tools/src/main/js/bundler/bundle-schemas.js, inside bundleSchemas right after computing absoluteModelsDir/absoluteRootPath, add a helper that verifies targetPath is inside baseDir using path.relative (robust across platforms). Then:
- Validate
absoluteRootPathis withinabsoluteModelsDir. - Validate generated outputs
bundledPathandminifiedPathare withinabsoluteModelsDir.
If validation fails, throw an error before any write. This preserves current functionality for normal valid inputs while preventing arbitrary path writes.
No new imports or dependencies are required.
| @@ -182,6 +182,15 @@ | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
|
|
||
| function assertPathWithinBase(baseDir, targetPath, label) { | ||
| const relative = path.relative(baseDir, targetPath); | ||
| if (relative.startsWith('..') || path.isAbsolute(relative)) { | ||
| throw new Error(`${label} must be within models directory: ${baseDir}`); | ||
| } | ||
| } | ||
|
|
||
| assertPathWithinBase(absoluteModelsDir, absoluteRootPath, 'Root schema path'); | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); | ||
| @@ -200,6 +209,9 @@ | ||
| const bundledPath = path.join(rootSchemaDir, bundledFilename); | ||
| const minifiedPath = path.join(rootSchemaDir, minifiedFilename); | ||
|
|
||
| assertPathWithinBase(absoluteModelsDir, bundledPath, 'Bundled output path'); | ||
| assertPathWithinBase(absoluteModelsDir, minifiedPath, 'Minified output path'); | ||
|
|
||
| console.log(`Output (bundled): ${bundledPath}`); | ||
| console.log(`Output (minified): ${minifiedPath}\n`); | ||
|
|
| console.log(` Minified JSON is on ${lineCount} line(s)`); | ||
|
|
||
| await fs.writeFile(minifiedPath, minifiedJson); | ||
| const minifiedStats = await fs.stat(minifiedPath); |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
General fix: enforce that all filesystem operations using user-influenced paths are confined to an approved root directory. Normalize with path.resolve, then verify resulting paths stay inside that root.
Best fix here (without changing core functionality): in bundleSchemas, define a trusted base directory (current working directory), then reject modelsDirectory and rootSchemaPath if they resolve outside it. Additionally, verify computed output paths (bundledPath, minifiedPath) are still inside the same trusted base. This preserves existing behavior for normal in-repo usage while preventing arbitrary filesystem targets.
Changes needed in tools/src/main/js/bundler/bundle-schemas.js:
- Add helper
isPathInside(parentDir, targetPath). - In
bundleSchemas, after resolving inputs, validate:absoluteModelsDirinside trusted rootabsoluteRootPathinside trusted root
- After generating output paths, validate:
bundledPathinside trusted rootminifiedPathinside trusted root
No new dependencies required.
| @@ -16,6 +16,11 @@ | ||
| return typeof value === 'object' && value !== null; | ||
| } | ||
|
|
||
| function isPathInside(parentDir, targetPath) { | ||
| const relative = path.relative(parentDir, targetPath); | ||
| return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative)); | ||
| } | ||
|
|
||
| /** | ||
| * Resolve a JSON Pointer (RFC6901) against an object. Returns { ok: boolean, value?: any, error?: string } | ||
| */ | ||
| @@ -179,9 +184,18 @@ | ||
|
|
||
| async function bundleSchemas(modelsDirectory, rootSchemaPath, options = {}) { | ||
| try { | ||
| const trustedRootDir = path.resolve(process.cwd()); | ||
| const absoluteModelsDir = path.resolve(modelsDirectory); | ||
| const absoluteRootPath = path.resolve(rootSchemaPath); | ||
|
|
||
| if (!isPathInside(trustedRootDir, absoluteModelsDir)) { | ||
| throw new Error(`Models directory must be within project directory: ${trustedRootDir}`); | ||
| } | ||
|
|
||
| if (!isPathInside(trustedRootDir, absoluteRootPath)) { | ||
| throw new Error(`Root schema path must be within project directory: ${trustedRootDir}`); | ||
| } | ||
|
|
||
| // Verify paths exist | ||
| await fs.access(absoluteModelsDir); | ||
| await fs.access(absoluteRootPath); | ||
| @@ -200,6 +211,10 @@ | ||
| const bundledPath = path.join(rootSchemaDir, bundledFilename); | ||
| const minifiedPath = path.join(rootSchemaDir, minifiedFilename); | ||
|
|
||
| if (!isPathInside(trustedRootDir, bundledPath) || !isPathInside(trustedRootDir, minifiedPath)) { | ||
| throw new Error(`Output paths must be within project directory: ${trustedRootDir}`); | ||
| } | ||
|
|
||
| console.log(`Output (bundled): ${bundledPath}`); | ||
| console.log(`Output (minified): ${minifiedPath}\n`); | ||
|
|
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
…ment patterns. Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
6baf15b to
4e77988
Compare
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
23cff3e to
7f3c089
Compare
Signed-off-by: Steve Springett <steve@springett.us>
e4d7b78 to
4456b54
Compare
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Steve Springett <steve@springett.us>
Co-authored-by: Jan Kowalleck <jan.kowalleck@owasp.org> Signed-off-by: Steve Springett <steve@springett.us>
Co-authored-by: Jan Kowalleck <jan.kowalleck@owasp.org> Signed-off-by: Steve Springett <steve@springett.us>
…commended in https://github.com/CycloneDX/specification/pull/980/changes#r3784287089 Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Steve Springett <steve@springett.us>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
…ts (#1042) Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
Important
WORK IN PROGRESS
see Milestone for progress: https://github.com/CycloneDX/specification/milestone/2
BREAKING Changes
To be explained further.
Reasoning: Downstream spec users may build ontop of JSON schema.
To be explained further.
... TBC ...
Added
... TBD ...
Chaned
... TBD ...
Removed
... TBD ...
Misc
... TBD ...