Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,55 @@ All notable changes to QRAMM CryptoDeps will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.0] - 2026-07-27

Fixes both open community issues, plus a silent false negative found while
reproducing them.

### Fixed

- **`requirements-*.txt` files were skipped**
([#1](https://github.com/csnp/cryptodeps/issues/1)). Manifest discovery
matched the exact filename `requirements.txt`, so the
`requirements-dev.txt` and `requirements-prod.txt` split that most Python
projects use was never scanned. The `requirements*.txt` family and the
`requirements/*.txt` directory layout are now discovered and parsed.
- **CBOM did not identify which dependency an algorithm came from**
([#2](https://github.com/csnp/cryptodeps/issues/2)). Output emitted only the
algorithm, carrying the dependency's version but never its name, so a
component reading `{"name": "RSA", "version": "1.3.2"}` was unattributable.
Each dependency is now emitted as its own `library` component with a
`bom-ref`, and the CycloneDX `dependencies` graph links each algorithm to the
library that provides it.
- **`pyproject.toml` and `Pipfile` produced fabricated dependencies.** Both were
advertised as supported, but parsing fell through to the `requirements.txt`
line parser behind a `TODO`. A `pyproject.toml` yielded entries named after
TOML keys (`name`, `dependencies`, `requires-python`), and because the real
packages were never identified, a project depending on `cryptography` reported
"No cryptographic usage detected". Both formats now have real TOML parsers
covering PEP 621, Poetry, and Pipfile layouts.
- **Every CBOM shared one serial number.** `generateUUID` returned a hardcoded
all-zero UUID, which also failed the CycloneDX `urn:uuid` pattern. Serial
numbers are now random version 4 UUIDs.
- **Unresolved build properties were emitted as versions.** A Maven dependency
declared as `${java-jwt.version}` appeared in the CBOM with that literal as
its version. Version ranges such as `>=2.0` were likewise emitted where
CycloneDX expects a concrete version. Only pinned versions are now reported as
versions; the declared constraint is preserved in the component description.
- **CBOM `primitive` values were outside the CycloneDX enum**, which failed
schema validation for the whole document. Categories now map onto the
permitted enum, resolving `encryption` by algorithm where possible.

### Added

- Regression tests for manifest discovery, the three Python formats, PEP 508
requirement parsing, CBOM dependency attribution, version resolution, serial
number uniqueness, and primitive enum conformance.

### Dependencies

- Added `github.com/BurntSushi/toml` for pyproject.toml and Pipfile parsing.

## [1.2.1] - 2025-12-27

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ CryptoDeps goes beyond simple dependency scanning by analyzing your code's call
|-----------|----------------|
| Go | `go.mod`, `go.sum` |
| npm | `package.json`, `package-lock.json` |
| Python | `requirements.txt`, `pyproject.toml`, `Pipfile` |
| Python | `requirements.txt` and the `requirements-*.txt` family, `requirements/*.txt`, `pyproject.toml` (PEP 621 and Poetry), `Pipfile` |
| Maven | `pom.xml` |

### Workspace & Monorepo Support
Expand Down
55 changes: 55 additions & 0 deletions docs/testing/release-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Release Smoke Test: qramm-cryptodeps

Manual pre-release walkthrough. Run this before every deploy or publish.
Use real keyboard and mouse input, not synthetic events. Record the actual
output, not a summary.

## 1. Build and start clean

- [ ] Fresh install succeeds (`npm ci` or equivalent) with no errors.
- [ ] Build succeeds (`npm run build`).
- [ ] App starts locally (`npm run dev`) with no console errors.

## 2. Core user paths

List the three most important things a real visitor does on this site or
with this tool, then walk each one by hand.

- [ ] Path 1:
- [ ] Path 2:
- [ ] Path 3:

## 3. Accessibility and audience fit

CSNP serves non-technical and vulnerable users. Verify the experience holds
for them.

- [ ] Plain language: no unexplained jargon in user-facing copy.
- [ ] Keyboard navigable: every interactive element reachable by Tab.
- [ ] Screen-reader labels present on buttons, links, and form fields.
- [ ] Color contrast meets WCAG AA.

## 4. Responsive parity

- [ ] Mobile (375px): nav, menus, and layout all work.
- [ ] Desktop (1280px): no overflow or broken grids.
- [ ] Dark mode (if supported) renders correctly.

## 5. Data and links

- [ ] Every download link resolves (no 404s).
- [ ] Any displayed number or statistic traces to a real source.
- [ ] No placeholder or fabricated content shipped.

## 6. Security

- [ ] No secrets in the bundle or committed files.
- [ ] `.env` and credential files are gitignored and excluded.
- [ ] Forms validate and sanitize input.

## Result

- Date:
- Tester:
- Verdict: PASS / FAIL
- Notes:
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/csnp/qramm-cryptodeps
go 1.21

require (
github.com/BurntSushi/toml v1.6.0
github.com/spf13/cobra v1.8.0
gopkg.in/yaml.v3 v3.0.1
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
Expand Down
27 changes: 24 additions & 3 deletions internal/manifest/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,30 @@ func getParser(filename string) (Parser, error) {
return &PythonParser{}, nil
case "pom.xml":
return &MavenParser{}, nil
default:
return nil, fmt.Errorf("unsupported manifest file: %s", filename)
}

// The requirements.txt family carries no fixed name. Matching only the exact
// filename silently skipped requirements-dev.txt, requirements-prod.txt and
// the requirements/*.txt layout.
if isRequirementsFile(filename) {
return &PythonParser{}, nil
}

return nil, fmt.Errorf("unsupported manifest file: %s", filename)
}

// getParserForPath selects a parser using the whole path, so that layouts whose
// meaning depends on the parent directory resolve correctly. A pip requirements
// file at requirements/base.txt is named base.txt and is indistinguishable from
// any other text file by name alone.
func getParserForPath(path string) (Parser, error) {
if parser, err := getParser(filepath.Base(path)); err == nil {
return parser, nil
}
if isManifestPath(path) && strings.EqualFold(filepath.Ext(path), ".txt") {
return &PythonParser{}, nil
}
return nil, fmt.Errorf("unsupported manifest file: %s", path)
}

// SupportedManifests returns a list of supported manifest filenames.
Expand Down Expand Up @@ -152,7 +173,7 @@ func DetectAndParseAll(path string) ([]*Manifest, error) {
var parseErrors []string

for _, manifestPath := range manifestPaths {
parser, err := getParser(filepath.Base(manifestPath))
parser, err := getParserForPath(manifestPath)
if err != nil {
// Skip unsupported files silently (they might have been picked up by glob)
continue
Expand Down
Loading
Loading