Add cryptographic algorithm scanning and CycloneDX 1.7 CBOM output#1687
Add cryptographic algorithm scanning and CycloneDX 1.7 CBOM output#1687CortezFrazierJr wants to merge 18 commits intomasterfrom
Conversation
WalkthroughAdded a new Rust binary crate 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 19
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/features/crypto-scanning.md`:
- Around line 53-65: The docs claim "No source code content is sent to FOSSA"
but the finding model still includes matched_text / cryptoFindingMatchedText;
update the upload flow to strip/redact that field before emission or update the
docs to remove the absolute privacy claim. Specifically, in the code path that
serializes/uploads findings (the function that assembles the FOSSA payload / the
upload/sendToFossa/exportFindings routine), remove or replace
cryptoFindingMatchedText/matched_text with a redacted placeholder (or omit the
key entirely) prior to sending, and add a unit/integration test to assert the
payload lacks matched_text; alternatively, if you choose docs change, edit the
crypto-scanning.md text to state that matched snippets may be included unless
explicitly redacted.
In `@docs/references/subcommands/analyze.md`:
- Around line 182-183: Update the wording that currently reads "Crypto Scanning
detects cryptographic algorithm usage across 10 language ecosystems" to reflect
the implemented scope—either change it to "15+ language ecosystems" or a neutral
phrase like "multiple language ecosystems" so the docs match the PR scope;
ensure the same change is applied to the repeated instance later in the doc (the
other occurrence of the "10 ecosystems" sentence).
In `@extlib/cryptoscan/src/crypto_algorithm.rs`:
- Around line 35-46: Primitive::KeyWrap currently serializes to "key-wrap" which
doesn't match the Haskell decoder; update the Rust enum serialization for
Primitive::KeyWrap (in crypto_algorithm.rs) to the exact token expected by the
Haskell decoder in src/App/Fossa/CryptoScan/Types.hs (e.g., change the serde
rename from "key-wrap" to the Haskell-accepted string), ensuring the serde
attribute is applied to the KeyWrap variant so both sides are in lockstep; run a
quick round-trip test or fossa analyze to verify decoding succeeds.
In `@extlib/cryptoscan/src/cyclonedx.rs`:
- Around line 161-188: The current dedup logic using seen_locations,
seen_methods, and seen_ecosystems produces nondeterministic order; instead
collect unique values for each of those (e.g., build Vecs of file_path,
detection_method.as_str(), and ecosystem from the loop over group or use a
BTreeSet), sort the collections deterministically, then iterate the sorted lists
to push BomProperty entries (name: "fossa:detected-in",
"fossa:detection-method", "fossa:ecosystem") into properties; update references
to the variables seen_locations/seen_methods/seen_ecosystems (or replace them
with properly named collections) and remove HashSet from the imports.
In `@extlib/cryptoscan/src/fips.rs`:
- Around line 192-197: The DSA-specific branch that returns
FipsStatus::Deprecated currently checks lower.contains("dsa") before detecting
the SLH-DSA case, causing "slh-dsa" to be misclassified; move the SLH-DSA check
so it runs before the generic DSA rule (and apply the same reorder for the
similar case at lines 237-239) so the SLH-DSA-approved branch is matched first;
locate the conditional that uses lower.contains("dsa") and the SLH-DSA condition
and swap their order so SLH-DSA is evaluated prior to the generic DSA check.
- Around line 29-31: The FipsRemediation struct in fips.rs is annotated with
#[allow(dead_code)], which silences a real compiler warning; remove that
attribute and either delete FipsRemediation if it's not needed or make it
used/exported (e.g., remove the allow, add pub if intended public, and wire it
into the public model or create a unit test that constructs/uses
FipsRemediation) so the compiler no longer reports it as dead code; ensure any
serialization derives (Serialize, Deserialize) remain correct when you
reintroduce usage.
In `@extlib/cryptoscan/src/main.rs`:
- Around line 69-78: The code currently forwards a possibly invalid --path into
scanner::scan_project which masks WalkDir errors and yields an empty successful
result; fix by validating the scan root in main before calling
scanner::scan_project: check that cli.path exists and is a directory (e.g., use
std::path::Path::exists()/is_dir() or std::fs::metadata) and if the check fails,
print a clear error (eprintln! or process_logger.error) and exit with a non-zero
code; keep the existing call sites (scanner::detect_ecosystems and
scanner::scan_project) but do not call scanner::scan_project when the path is
invalid so the program fails fast with a visible error instead of producing
empty findings.
In `@extlib/cryptoscan/src/patterns.rs`:
- Around line 7-15: The CryptoPattern currently only has file_extensions which
causes manifest rules to overmatch; add a new field to the CryptoPattern struct
(e.g., file_names: Vec<&'static str> or file_globs: Vec<&'static str>) to allow
exact filename or glob constraints (examples: "package.json", "Cargo.toml",
"*.csproj"), populate those for manifest rules, and update
scanner::pattern_applies to first check the incoming file's basename (and run a
glob match if you chose globs) against the new file_names/file_globs list before
falling back to file_extensions; keep the existing extension-based behavior for
non-manifest rules and for extensionless files ensure pattern_applies still
handles them appropriately.
- Around line 64-68: The current pat(...) rules (e.g., the patterns calling pat
with DetectionMethod::ImportStatement and Confidence::High/Medium) treat
namespace imports as concrete algorithm usages (AES, SHA-256, HKDF); update
these patterns to capture the actual imported symbol (use capturing groups in
the regex, e.g., capture (\w+) or the specific group already present) and then
normalize the captured symbol to a concrete algorithm before emitting an
algorithm-level finding, otherwise emit a library-level finding or downgrade
confidence; specifically, modify the pat invocations that match
"cryptography.hazmat.primitives.ciphers", "hashes", and "kdf" so they either (1)
require and use the captured symbol to map to AES/SHA-256/HKDF when present, or
(2) when only the namespace is imported (no concrete symbol captured) produce a
generic/ library-level finding or lower the Confidence from High to Medium/Low
instead of attributing AES/SHA-256/HKDF directly.
In `@extlib/cryptoscan/src/scanner.rs`:
- Around line 322-325: The match arms in scanner.rs that map generic algorithm
labels ("RSA", "ECDSA", "ECDSA-P256", "ECDSA-P384", "ECDSA-P521", and the
similar arms at the other noted locations) currently populate concrete fields
(parameter_set, curve, and derived security level) for generic detections;
instead, when normalize_detected_algorithm did not extract explicit parameters,
leave those fields empty/None and avoid inventing defaults. Update the tuple
values returned by the affected arms (the tuples constructed with
Primitive::Pke/Primitive::Signature and the following elements) so parameter_set
and curve are None and the security level is None/empty for truly generic
matches rather than inserting "2048", "nist/P-256", Some(128), etc., and do the
same for the other similar arms referenced in the comment.
- Around line 389-406: The deduplication currently returns
HashMap::into_values() which yields non-deterministic iteration order; in
deduplicate_findings collect best.into_values() into a Vec<CryptoFinding> and
sort it deterministically (e.g., by the same composite key used for dedupe:
algorithm.name, file_path, line_number, and if needed tie-break by confidence or
algorithm.name) before returning; update the function to build that sorted Vec
so repeated runs produce stable output.
- Around line 21-25: The auto-detection currently limits WalkDir to three levels
via .max_depth(3), causing detect_ecosystems to miss nested services in
monorepos; remove the .max_depth(3) call from the WalkDir::new(project_path)
chain used by detect_ecosystems (and any related scan_project sampling) so the
directory walk covers the whole repo, keeping the existing .filter_entry(|e|
!should_skip_path(e.path())) and .filter_map(|e| e.ok()) and ensuring
pattern_applies can evaluate files at any depth.
In `@src/App/Fossa/Analyze.hs`:
- Around line 423-430: The CBOM write is performed outside the diagnostic
boundary so failures (e.g., missing parent directory or permission error) can
abort a successful scan; modify the block handling Success _ (Just bytes) so
that before calling BL.writeFile cbomPath bytes you either ensure the parent
directory exists (createDirectoryIfMissing True on the parent of cbomPath)
and/or perform the write inside Diag.errorBoundaryIO/diagToDebug to catch and
log IOExceptions (using Diag.context "crypto-cbom-output" and process the error
via Diag.flushLogs or logError) referencing maybeCbomBytes,
analyzeCryptoScanCBOM, cbomPath and BL.writeFile to locate the code to change.
In `@src/App/Fossa/Analyze/ScanSummary.hs`:
- Line 231: Remove the match guard that checks `| not (null findings) =` in the
crypto rendering code and replace it with a case expression on `findings` so
empty crypto scans are rendered explicitly (or render an empty placeholder)
rather than being silently omitted; keep `srcUnitToScanCount crypto` as-is so
counts remain consistent with displayed items, e.g. locate the branch that
renders `crypto` (it currently uses the guard on `findings`) and change it to
`case findings of [] -> ...; _ -> <existing rendering>` so empty findings are
not hidden.
In `@src/App/Fossa/CryptoScan/FipsReport.hs`:
- Around line 217-223: The mapping for 3DES is missing because the code only
checks for "3des-encrypt" but the scanner emits the canonical name "3DES";
update the conditional in FipsReport.hs (the branch that currently checks
["rc4", "rc2", "blowfish", "des", "3des-encrypt"]) to also include the canonical
"3DES" (and optionally "3des") so that matches return "AES-256" (same
remediation as the existing 3des-encrypt case).
In `@src/App/Fossa/CryptoScan/Types.hs`:
- Around line 13-24: Replace the unqualified imports with explicit, qualified
imports: import Data.Aeson as Aeson (FromJSON(parseJSON), ToJSON(toJSON),
Value(String), object, withObject, withText, (.:), (.:?), (.=)) and import
Data.Text as Text (Text); then update usages in this module to use the Aeson.
and Text. prefixes for the referenced symbols (e.g.,
Aeson.FromJSON/Aeson.parseJSON, Aeson.object, Aeson.(.:), and Text.Text) so the
module follows the repository guideline of explicit, fully-qualified Haskell
imports.
- Around line 188-240: The CryptoPrimitive type and its JSON instances are
missing the key-wrap variant; add a new constructor PrimitiveKeyWrap to the
CryptoPrimitive data declaration and update the FromJSON parseJSON handler to
map the text "key-wrap" -> Pure PrimitiveKeyWrap and the ToJSON toJSON function
to emit String "key-wrap" for PrimitiveKeyWrap so JSON decoding/encoding
recognizes that primitive (update the data type, the parseJSON case list, and
the toJSON match arm accordingly).
In `@test-fixtures/csharp-service/Service.csproj`:
- Line 9: The test fixture declares the Argon2 package as
Isopoh.Cryptography.Argon2 which the C# dependency manifest scanner does not
recognize; change the <PackageReference> in Service.csproj to
Konscious.Security.Cryptography (replacing Isopoh.Cryptography.Argon2) so the
detector emits the intended Argon2 signal, or alternatively update the C#
manifest scanner’s dependency pattern list to include
"Isopoh.Cryptography.Argon2" (whichever you prefer) — target the
PackageReference element in Service.csproj or the detector's dependency pattern
configuration/class to apply the change.
In `@test-fixtures/ruby-web-app/app.rb`:
- Around line 8-40: The cipher name literals passed to OpenSSL::Cipher.new in
the encryption helpers cause low-confidence scanner matches because they use
lowercase or noncanonical names; update the string literals in the methods (the
OpenSSL::Cipher.new(...) calls inside the AES-GCM helper, encrypt_aes_cbc,
encrypt_chacha, and encrypt_3des) to the scanner's expected canonical uppercase
names (e.g. use "AES-256-GCM" for the AES-GCM helper, "AES-128-CBC" in
encrypt_aes_cbc, "ChaCha20" in encrypt_chacha, and "DES-EDE3-CBC" in
encrypt_3des) so the high-confidence Ruby patterns match.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0d61159a-88c6-4ce8-9968-87c2959ad545
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockextlib/cryptoscan/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (43)
Cargo.tomlMakefiledocs/features/crypto-scanning.mddocs/references/experimental/crypto-scanning/README.mddocs/references/subcommands/analyze.mdextlib/cryptoscan/Cargo.tomlextlib/cryptoscan/src/crypto_algorithm.rsextlib/cryptoscan/src/cyclonedx.rsextlib/cryptoscan/src/fips.rsextlib/cryptoscan/src/main.rsextlib/cryptoscan/src/patterns.rsextlib/cryptoscan/src/scanner.rsextlib/cryptoscan/tests/integration_test.rsspectrometer.cabalsrc/App/Fossa/Analyze.hssrc/App/Fossa/Analyze/ScanSummary.hssrc/App/Fossa/Analyze/Types.hssrc/App/Fossa/Config/Analyze.hssrc/App/Fossa/CryptoScan/Analyze.hssrc/App/Fossa/CryptoScan/FipsReport.hssrc/App/Fossa/CryptoScan/Types.hssrc/App/Fossa/EmbeddedBinary.hstest-fixtures/csharp-service/CryptoService.cstest-fixtures/csharp-service/Service.csprojtest-fixtures/elixir-phoenix-app/crypto.extest-fixtures/elixir-phoenix-app/mix.exstest-fixtures/go-api-server/go.modtest-fixtures/go-api-server/main.gotest-fixtures/java-microservice/pom.xmltest-fixtures/java-microservice/src/main/java/com/example/CryptoService.javatest-fixtures/node-auth-service/auth.jstest-fixtures/node-auth-service/package.jsontest-fixtures/php-api/composer.jsontest-fixtures/php-api/crypto.phptest-fixtures/python-web-app/app.pytest-fixtures/python-web-app/requirements.txttest-fixtures/ruby-web-app/Gemfiletest-fixtures/ruby-web-app/app.rbtest-fixtures/rust-crypto-tool/Cargo.tomltest-fixtures/rust-crypto-tool/src/main.rstest-fixtures/swift-ios-app/CryptoManager.swifttest-fixtures/swift-ios-app/Podfiletest/App/Fossa/CryptoScan/FipsReportSpec.hs
Introduce a new experimental feature (--x-crypto-scan) that detects cryptographic algorithm usage across 10 ecosystems (Python, Java, Go, Node, Rust, Ruby, C#, PHP, Swift, Elixir) and produces CycloneDX 1.7 CBOM output for FIPS compliance assessment. Key features: - Rust-based crypto detection engine (extlib/cryptoscan) with pattern matching for imports, API calls, dependency manifests, and config files - Auto-detection of ecosystems present in the project - FIPS 140-3 compliance classification (approved/deprecated/not-approved) - CycloneDX 1.7 CBOM file output (--crypto-cbom-output) - Detailed FIPS compliance report (--crypto-fips-report) with remediation recommendations and key-size warnings - Crypto scan results displayed in the analysis scan summary - 56 passing integration tests covering all 10 ecosystems Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…aggregation, parse error handling, and doc wording - scanner.rs: Add normalize_detected_algorithm() to use matched text for refining generic pattern names into specific algorithm variants (e.g., AES -> AES-256-GCM based on matched code context) - cyclonedx.rs: Aggregate detection contexts (detected-in, detection-method, ecosystem) from all findings per algorithm instead of only keeping the first - Analyze.hs: Use fatalText instead of warn+Nothing for JSON parse failures so scanner output-contract regressions surface as hard errors - crypto-scanning.md: Fix wording that implied non-ECB AES modes are deprecated Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ng, add doc entries - FipsReport.hs: Convert all match guards to if/then/else per style guide (compliancePercentage, coloredPercentage, suggestAlternative, catWarnings, rsaWarning). Remove unused matchesAny function. - scanner.rs: Use filter_entry() to prune skipped directories during WalkDir traversal instead of filtering after entry. Replace brittle slash-based path matching with file_name() segment comparison for cross-platform correctness. - analyze.md: Add --crypto-cbom-output and --crypto-fips-report to the experimental flags table for discoverability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, regression test, clock safety - cyclonedx.rs: Sort unique_algos for deterministic BOM output across runs. Use unwrap_or_default() for SystemTime to avoid panic on clock anomalies. - FipsReport.hs: Replace quadratic nubBy with Map-based deduplicateFindings for O(n log n) deduplication. Reuse single dedupe pass in both computeFipsStats and renderFipsReport. - FipsReportSpec.hs: Add regression test verifying RSA-1024 and RSA-2048 are counted as separate algorithm variants (different parameter sets). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…em detection, variable shadowing - Don't guess AES key sizes from mode-only detections (AES-GCM → None, not 256) - Add AES-192 variants for GCM and CBC modes - Add RSA-<bits> dynamic matching in resolve_algorithm fallthrough - Rewrite detect_ecosystems with filter_entry pruning and source extension detection - Fix foldl→foldr in categorizeFindings for proper ordering - Fix variable shadowing in keySizeWarning (name→algoName, name/paramSet→n/ps) - Change debug logging to show finding count instead of full payload - Separate FIPS status from algorithmProperties in CBOM docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lder, smoke tests - Declare rust-version = "1.70" in Cargo.toml for is_some_and compatibility - Add Primitive::as_str() to avoid serde round-trip for string conversion - Reuse bom_ref computation instead of computing twice per loop iteration - Use BTreeSet for combined dedup+sort in CycloneDX dependency generation - Replace defensive month=12 fallback with debug_assert - Fix double deduplication in renderFipsReport (dedupe once, pass to stats) - Extract mkCryptoScanCommand to reduce command builder duplication - Remove redundant double deserialization in integration test - Add renderFipsReport smoke tests for empty and mixed results Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pin dependency versions to match millhone for workspace consistency - Add DetectionMethod::as_str() for parity with Primitive::as_str() - Replace serde round-trip for DetectionMethod in cyclonedx.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ed libs, algorithmFamily validation - Add KeyWrap variant to Primitive enum per CycloneDX 1.7 schema - Scope library identity by (ecosystem, library_name) to prevent cross-ecosystem collisions - Validate algorithmFamily against CycloneDX 1.7 registry, emit None for unknown values Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ithmFamily - Replace HashMap with BTreeMap for algo_findings and library_algorithms to ensure deterministic component/dependency ordering in CBOM output - Replace custom KNOWN_FAMILIES with official CycloneDX 1.7 algorithmFamily enum (78 canonical entries) and return canonical case via .find() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve hlint warnings: use isJust, foldl', guards, eta-reduce, toString. Run fourmolu, cabal-fmt, rustfmt on all changed files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0b01d05 to
9110190
Compare
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ordering, key-wrap sync, docs accuracy - Replace HashSet with BTreeSet in cyclonedx.rs for deterministic property order - Move SLH-DSA/ML-DSA checks before generic DSA rule to prevent misclassification - Remove dead FipsRemediation struct from fips.rs - Add scan root validation in main.rs - Remove depth-3 cap from ecosystem auto-detection - Use BTreeMap for deterministic deduplicated findings output - Stop inventing key sizes for generic algorithm detections - Add PrimitiveKeyWrap to Haskell CryptoPrimitive with key-wrap mapping - Qualify Data.Aeson imports in Types.hs per repo style guide - Guard CBOM file write with fatalOnIOException - Add 3DES to FipsReport remediation mapping - Fix ecosystem count wording in docs (10 -> multiple) - Soften privacy claim in crypto-scanning docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…confidence, test fixtures - Add file_names field to CryptoPattern for dependency-manifest filename scoping - Lower confidence for generic Python namespace import patterns (High -> Medium) - Replace match guard with case expression in ScanSummary crypto rendering - Fix C# test fixture: use Konscious.Security.Cryptography for Argon2 - Fix Ruby test fixture: use canonical uppercase cipher names Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
App.Fossa.Config.Crypto and App.Fossa.Crypto were listed but never created. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Master added cmdEnvVars to Command type; set to mempty for crypto scan. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
logInfo expects Doc AnsiStyle, not Text — remove unnecessary renderIt. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Master's AnalyzeConfig gained xCryptoScan, cryptoCbomOutput, cryptoFipsReport. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 10
♻️ Duplicate comments (1)
src/App/Fossa/CryptoScan/Types.hs (1)
13-23:⚠️ Potential issue | 🟠 MajorQualify all Haskell imports (and corresponding usages) consistently.
This module still uses unqualified
Data.Aeson/Data.Textimports (FromJSON,ToJSON,Text,(.:),(.=), etc.), which conflicts with the repo’s Haskell import rule.Suggested direction
-import Data.Aeson ( - FromJSON (parseJSON), - ToJSON (toJSON), - Value (String), - (.:), - (.:?), - (.=), - ) -import Data.Aeson qualified as Aeson -import Data.Text (Text) +import Data.Aeson qualified as Aeson +import Data.Text qualified as Text-instance FromJSON CryptoFinding where +instance Aeson.FromJSON CryptoFinding where parseJSON = Aeson.withObject "CryptoFinding" $ \o -> CryptoFinding - <$> o .: "algorithm" + <$> o Aeson..: "algorithm"As per coding guidelines, "Use explicit imports in Haskell, qualified with full names".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/App/Fossa/CryptoScan/Types.hs` around lines 13 - 23, This module uses unqualified imports from Data.Aeson and Data.Text (e.g. FromJSON, ToJSON, Value(String), (.:), (.:?), (.=), Text) which violates the repo rule to use explicit qualified imports; change the imports to import Data.Aeson qualified as Aeson and Data.Text qualified as Text (or similar consistent qualifiers) and update all usages in this file to use those qualifiers (e.g. Aeson.FromJSON/Aeson.parseJSON, Aeson.ToJSON/Aeson.toJSON, Aeson.Value(Aeson.String), Aeson.(.:)/Aeson.(.:?)/Aeson.(.=), and Text.Text) so imports are explicit and consistent with the coding guidelines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/references/experimental/crypto-scanning/README.md`:
- Line 13: Update the sentence "Ten ecosystems are supported: Python, Java, Go,
Rust, Node.js, Ruby, C#/.NET, PHP, Swift, and Elixir." to reflect the PR's claim
of "15+ ecosystems"—either change the numeric wording to "15+ ecosystems are
supported" or enumerate the full set of 15+ ecosystems to match the PR; ensure
the sentence and any adjacent summary text consistently state "15+" instead of
"ten" so user-facing docs align with the PR.
In `@extlib/cryptoscan/src/cyclonedx.rs`:
- Around line 397-408: The month calculation currently initializes month = 0 and
relies on the loop invariant plus a debug_assert; make it defensive by computing
month using an iterator and unwrapping to a safe default instead of leaving
month possibly zero. Replace the manual for-loop over months_days with a call
like months_days.iter().position(|&md| days < md).map(|i| i +
1).unwrap_or(months_days.len()) (or equivalent) to set month, and keep the final
debug_assert or replace it with a runtime panic/explicit error if you prefer;
update references to the month variable accordingly (symbols: months_days,
month, debug_assert).
In `@extlib/cryptoscan/src/fips.rs`:
- Around line 159-177: The current logic in the RSA/ECDSA/ECDH/DH branches
returns FipsStatus::Approved for bare algorithm name matches even when no
parameters (key size, curve, domain params) were extracted; update the branches
around the `lower.contains("rsa")` check and the `lower.contains("ecdsa")` /
ECDH / DH checks so that approval is only returned when the required parameters
were actually parsed: for RSA, only return FipsStatus::Approved when `key_size`
is Some(bits) and bits >= 2048, otherwise return NotApproved (or a manual-review
status) if key_size is None or <2048; for ECDSA/ECDH/DH do not return Approved
unconditionally — require explicit curve/domain parameters to be parsed before
returning Approved and otherwise return NotApproved/manual-review. Keep
references to the existing symbols (`lower`, `key_size`, `FipsStatus`) and
adjust the matching branches accordingly.
In `@src/App/Fossa/CryptoScan/FipsReport.hs`:
- Around line 269-300: The SHA-related branches in keySizeWarning (inside
catWarnings) use substring matching on algoName so composite names like
"HMAC-SHA1" trigger hash deprecation warnings; update catWarnings to only emit
SHA warnings for standalone hash primitives—either by checking the algorithm
type/primitive from cryptoFindingAlgorithm (if available) or by matching
exact/bounded names (e.g., exact "sha-1"/"sha1" or regex word-boundary matches)
and explicitly skip names prefixed with "hmac-" or other MAC/combination
prefixes; keep rsaWarning behavior the same and use cryptoAlgorithmName and
cryptoAlgorithmParameterSet to locate and gate the change.
In `@test-fixtures/java-microservice/pom.xml`:
- Around line 8-12: The pom dependency for org.bouncycastle:bcprov-jdk18on
currently pins version 1.78 which is vulnerable (CVE-2025-8916 and other fixes
missing); update the <version> for the dependency with artifactId bcprov-jdk18on
(groupId org.bouncycastle) to a fixed release (preferably 1.79, or at minimum
1.78.1 if you must remain on the 1.78 line), then run a build to verify no
compatibility issues and update any dependency management or BOM entries if they
override this version.
In
`@test-fixtures/java-microservice/src/main/java/com/example/CryptoService.java`:
- Around line 14-16: Update the class Javadoc for CryptoService to explicitly
state this is test-fixture-only and not for production use; add a short guidance
sentence mentioning that the class intentionally contains insecure/deprecated
crypto patterns for detection/testing and must not be reused in production, so
reviewers/readers of the CryptoService class (and its methods) are warned
against copy/paste.
- Around line 99-103: The PBEKeySpec in deriveKeyPbkdf2 holds sensitive password
data and must be cleared; modify deriveKeyPbkdf2 to create the PBEKeySpec,
perform SecretKeyFactory.getInstance(...).generateSecret(spec).getEncoded()
inside a try block, and in a finally block call spec.clearPassword() (and null
out spec if desired) so the password chars are wiped even on exceptions;
reference PBEKeySpec spec, SecretKeyFactory factory, and deriveKeyPbkdf2 when
applying the change.
In `@test-fixtures/php-api/crypto.php`:
- Around line 3-4: Remove the unused phpseclib3 imports (use
phpseclib3\Crypt\AES and use phpseclib3\Crypt\RSA) from crypto.php or, if they
are intentionally present for import-pattern detection, replace them with a
short clarifying comment above the import block explaining they are deliberately
unused; update the file so the actual implementations only reference openssl_*
and sodium_* functions to avoid scanners falsely reporting phpseclib usage.
In `@test-fixtures/rust-crypto-tool/src/main.rs`:
- Around line 56-64: The build fails because feature-gated APIs are used in
generate_ed25519_key (SigningKey::generate requires ed25519-dalek's rand_core)
and x25519_key_exchange (EphemeralSecret::random requires x25519-dalek's
getrandom); update your Cargo.toml dependency declarations to enable these
features by setting ed25519-dalek to include the "rand_core" feature and
x25519-dalek to include the "getrandom" feature so those methods are available
at compile time.
In `@test-fixtures/swift-ios-app/CryptoManager.swift`:
- Around line 81-95: The deriveKeyPbkdf2 function currently force-unwraps
baseAddress in derivedKey.withUnsafeMutableBytes and salt.withUnsafeBytes and
ignores CCKeyDerivationPBKDF's return code; update deriveKeyPbkdf2 to safely
unwrap the pointers (use guard let on derivedBytes.baseAddress and
saltBytes.baseAddress within derivedKey.withUnsafeMutableBytes /
salt.withUnsafeBytes closures) and capture the Int32 status returned by
CCKeyDerivationPBKDF; if status is not kCCSuccess, handle it deterministically
(e.g., throw an error or call fatalError with a descriptive message) so failures
are surfaced instead of silently ignored. Ensure you reference deriveKeyPbkdf2,
CCKeyDerivationPBKDF, derivedKey.withUnsafeMutableBytes and salt.withUnsafeBytes
when making the changes.
---
Duplicate comments:
In `@src/App/Fossa/CryptoScan/Types.hs`:
- Around line 13-23: This module uses unqualified imports from Data.Aeson and
Data.Text (e.g. FromJSON, ToJSON, Value(String), (.:), (.:?), (.=), Text) which
violates the repo rule to use explicit qualified imports; change the imports to
import Data.Aeson qualified as Aeson and Data.Text qualified as Text (or similar
consistent qualifiers) and update all usages in this file to use those
qualifiers (e.g. Aeson.FromJSON/Aeson.parseJSON, Aeson.ToJSON/Aeson.toJSON,
Aeson.Value(Aeson.String), Aeson.(.:)/Aeson.(.:?)/Aeson.(.=), and Text.Text) so
imports are explicit and consistent with the coding guidelines.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: 07eb1abc-ea85-4f13-a07d-ecace7c67940
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockextlib/cryptoscan/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (44)
Cargo.tomlMakefiledocs/features/crypto-scanning.mddocs/references/experimental/crypto-scanning/README.mddocs/references/subcommands/analyze.mdextlib/cryptoscan/Cargo.tomlextlib/cryptoscan/src/crypto_algorithm.rsextlib/cryptoscan/src/cyclonedx.rsextlib/cryptoscan/src/fips.rsextlib/cryptoscan/src/main.rsextlib/cryptoscan/src/patterns.rsextlib/cryptoscan/src/scanner.rsextlib/cryptoscan/tests/integration_test.rsspectrometer.cabalsrc/App/Fossa/Analyze.hssrc/App/Fossa/Analyze/ScanSummary.hssrc/App/Fossa/Analyze/Types.hssrc/App/Fossa/Config/Analyze.hssrc/App/Fossa/CryptoScan/Analyze.hssrc/App/Fossa/CryptoScan/FipsReport.hssrc/App/Fossa/CryptoScan/Types.hssrc/App/Fossa/EmbeddedBinary.hstest-fixtures/csharp-service/CryptoService.cstest-fixtures/csharp-service/Service.csprojtest-fixtures/elixir-phoenix-app/crypto.extest-fixtures/elixir-phoenix-app/mix.exstest-fixtures/go-api-server/go.modtest-fixtures/go-api-server/main.gotest-fixtures/java-microservice/pom.xmltest-fixtures/java-microservice/src/main/java/com/example/CryptoService.javatest-fixtures/node-auth-service/auth.jstest-fixtures/node-auth-service/package.jsontest-fixtures/php-api/composer.jsontest-fixtures/php-api/crypto.phptest-fixtures/python-web-app/app.pytest-fixtures/python-web-app/requirements.txttest-fixtures/ruby-web-app/Gemfiletest-fixtures/ruby-web-app/app.rbtest-fixtures/rust-crypto-tool/Cargo.tomltest-fixtures/rust-crypto-tool/src/main.rstest-fixtures/swift-ios-app/CryptoManager.swifttest-fixtures/swift-ios-app/Podfiletest/App/Fossa/CryptoScan/FipsReportSpec.hstest/Test/Fixtures.hs
… warnings, fixture fixes - Parameterless RSA/ECDSA/ECDH/DH now return Deprecated with manual-review note - Gate SHA-1/SHA-224 deprecation warnings on hash primitives to avoid HMAC-SHA1 - Fix x25519-dalek v2 API (EphemeralSecret::random_from_rng) - Add test fixture safety comments (Java, PHP, Swift) - Add clearPassword() call for PBEKeySpec in Java fixture - Reconcile ecosystem count in experimental docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Add CBOM (Cryptographic Bill of Materials) support to fossa-cli:
fossa cbomcommand for standalone crypto scanningfossa analyzeworkflowMigration from fork-based PR
This PR replaces #1656 which was opened from a personal fork (
CortezFrazierJr/fossa-cli). Tests couldn't run on the fork-based PR (per Zach's feedback). This PR is from a branch on the org repo so CI will run.All 7 rounds of CodeRabbit review feedback from #1656 have been addressed in this branch. The commit history is preserved.
Previous PR: #1656
Test plan
fossa cbomcommand🤖 Generated with Claude Code