Skip to content

Add experimental crypto behavior taxonomy with contextual auth evidence#494

Draft
n1ckl0sk0rtge wants to merge 56 commits into
mainfrom
feature/crypto-behavior-taxonomy
Draft

Add experimental crypto behavior taxonomy with contextual auth evidence#494
n1ckl0sk0rtge wants to merge 56 commits into
mainfrom
feature/crypto-behavior-taxonomy

Conversation

@n1ckl0sk0rtge

Copy link
Copy Markdown
Contributor

Summary

Adds an experimental crypto behavior dimension to the CBOM output: each scan now derives what the analyzed application does cryptographically (encryptsData, signsData, validatesToken, …) from the CycloneDX 2.0-dev threat-modeling taxonomy (security:cryptography:*), emitted as a single namespaced property on bom.metadata.component:

  • cbomkit:crypto:behavior = deduped, sorted, comma-joined behavior ids (experimental, non-standard; nothing is emitted when no behaviors are found)

What's included

Behavior derivation (output module) — a self-contained com.ibm.output.behavior subsystem:

  • CryptoBehaviorMapper: per-asset, declarative operation/fallback mapping tables (operation-first, primitive-kind fallback)
  • BehaviorCollector + BehaviorSignals + ordered IBehaviorRule registry (CryptoBehaviorRule, AuthInterfaceRule); new evidence families plug in via one signal field + one rule + one observe branch
  • BehaviorMetadataWriter: the only CycloneDX-specific part (property formatting)
  • Taxonomy snapshot crypto-behavior-taxonomy.json with an enum↔JSON sync test

Contextual auth evidence (engine + java modules) — application-level behaviors are gated on detected auth interfaces, so crypto alone never asserts them (a bare MAC no longer implies authenticates):

  • New AuthContext detection context (JWT, OAUTH, SAML, PRINCIPAL, API_KEY, MTLS)
  • AST detection rules for jjwt/Nimbus/Spring Security/OpenSAML/servlet-principal and friends (with test jars)
  • ContextualEvidence mapper node carrying non-crypto signals through the node stream without polluting the crypto inventory
  • Gating: authenticates ⟺ auth primary present; JWT/OAUTH/SAML also yield validatesToken; PRINCIPAL/MTLS also yield usesIdentity

Curated PRNG detectionSecureRandom detection incl. no-arg new SecureRandom() (note: this is broad by design and will emit a PRNG component + generatesRandomValue for most projects using it).

Design docs

Specs and task-by-task plans are under docs/superpowers/specs/ and docs/superpowers/plans/ (2026-07-03 … 2026-07-13).

Test plan

  • Full multi-module mvn test green (output module 70/70, incl. CBOM regression anchor CryptoBehaviorMetadataTest)
  • mvn checkstyle:check / mvn spotless:check clean
  • Behavior unit coverage: mapper tables, auth gating rules, collector totality (unknown evidence identifiers, NONE kind, non-asset nodes)
  • Detection tests per auth rule family; integration test proving auth signals never appear as CBOM components

Note: the branch contains one merge commit (db1dc94e, main back-merge) — squash-merge recommended given the "no merge commits" rule on main.

Signed-off-by: Nicklas Körtge <Nicklas.Koertge1@ibm.com>
…olish

FIX 1: Move behaviour accumulation from add() forEach into createAlgorithmComponent()
so TLS/cipher-suite constituent algorithms (reached via direct calls) now contribute
their behaviours to metadata.component; add regression test (RED→GREEN).
FIX 2: Relocate CryptoBehaviorTaxonomyTest to correctly-spelled cyclonedx package
(git mv); add CryptoBehavior import now required from different package.
FIX 3: Extend CryptoBehaviorMapperTest with 11 new cases covering Decrypt/Verify/
Digest/Tag/KeyGeneration operations, GenericKDF, AE/PKE/KEM/PRNG fallbacks, and
non-Algorithm empty-return.
FIX 4: Reference CryptoBehaviorMapper.BEHAVIOR_PROPERTY_NAME constant instead of
inline string literal in CryptoBehaviorMetadataTest.
FIX 5: Document METADATA_COMPONENT_NAME intentional simplification (spec §4.4).
…unwrap-test comments

- Add CryptoBehaviorMapperTest.decapsulateOnKeyWrapCipherYieldsWrapsKey() to verify Decapsulate
  functionality yields wrapsKey behavior on KeyWrap ciphers
- Add clarifying comment on SECURE_RANDOM_NO_ARG probe key indirection (maps to generic PRNG)
- Add comment on JcaCipherUnwrapTest scope noting end-to-end behavior validated elsewhere
The SecureRandom key-generation scaffolding removed from detection tests
in this branch is restored, now that new SecureRandom()/getInstance is
itself detected as a PRNG asset.

Each restored construct is annotated with the expected PRNG finding, and
every affected asserts() gains a PRNGContext guard so the extra finding
is accounted for without disturbing the existing cipher assertions.
findingId-keyed tests are renumbered for the interleaved PRNG findings.

All 25 affected tests pass; full java suite green (162 tests, 7 skipped).
Follow the BouncyCastleJars convention: hand the analyzer a curated,
version-pinned set of API jars from src/test/resources/test-jars via
AuthInterfaceJars, instead of reflecting the whole JUnit runtime
classpath. Type resolution is now deterministic and self-contained.
The pom test deps are retained solely for IDE linting of the detection
test files.
Emit crypto behaviors as a plain, comma-joined list of ids instead of a
confidence-suffixed one. BehaviorInferenceEngine.infer now returns a
Set<CryptoBehavior> rather than Map<CryptoBehavior, Confidence>, and the
cbomkit:crypto:behavior property value drops the =high/=medium suffix.

The two-tier gating model is unchanged: a MAC alone still does not assert
authenticates, and auth-interface primaries still unlock authenticates/
validatesToken/usesIdentity.

Delete the Confidence enum and its test; update the design docs and plans
to match.
The BouncyCastle detection rules expand into a ~520k-object in-memory
graph, which can exhaust the forked Scanner Engine heap during rule
construction (OutOfMemoryError in MethodMatcher.<init>). Document the
-Dsonar.scanner.javaOpts=-Xmx2g workaround in the scan guide.

Permanent fix (rule-graph memoization) tracked in #476.
The mvn sonar:sonar path runs the scanner engine inside the Maven JVM,
so -Dsonar.scanner.javaOpts / SONAR_SCANNER_JAVA_OPTS are ignored (those
only affect the standalone sonar-scanner CLI). Set MAVEN_OPTS=-Xmx4g
instead; document both knobs and bump to 4g for headroom.
…ven 5.0+

Scanner-for-Maven 5.0+ (bundled with recent SonarQube) forks the Scanner
Engine into its own JVM (ScannerMain), whose heap is set by
SONAR_SCANNER_JAVA_OPTS, not MAVEN_OPTS. MAVEN_OPTS only applied to
scanner <= 4.x where the engine ran in-process. Prior commit had this
backwards.
…est`

Signed-off-by: Nicklas Körtge <Nicklas.Koertge1@ibm.com>
…or-taxonomy

# Conflicts:
#	java/src/main/java/com/ibm/plugin/rules/detection/jca/cipher/JcaCipherWrap.java
#	java/src/main/java/com/ibm/plugin/rules/detection/random/SecureRandomGetInstance.java
…d rule variants

Extend AuthInterfaceTestFile with a bare Jwts.parser().build() (must not be
detected) plus the previously unexercised variants: parseClaimsJws,
JWSObject.verify, ReactiveJwtDecoder.decode, SSLSession.getPeerCertificates,
and pac4j ParameterClient. Strengthen AuthInterfaceDetectionTest from
kind-was-seen to exact per-kind finding counts so the parser-construction
negative is actually asserted.
@n1ckl0sk0rtge
n1ckl0sk0rtge requested a review from a team as a code owner July 14, 2026 06:10
@n1ckl0sk0rtge n1ckl0sk0rtge self-assigned this Jul 14, 2026
@n1ckl0sk0rtge
n1ckl0sk0rtge marked this pull request as draft July 14, 2026 14:28
@n1ckl0sk0rtge n1ckl0sk0rtge added the enhancement New feature or request label Jul 14, 2026

@san-zrl san-zrl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @n1ckl0sk0rtge,

The build fails due to a failing test RuleMemoizationEnforcementTest.everyStaticRulesMethodIsMemoized. The CI log is blurred with lots of log messages like

11:09:13.386 [main] INFO com.ibm.engine.language.java.JavaDetectionEngine -- Detected constructor definition has more then one argument to resolve. Redefine the rule to explicitly define the param to resolve

so it's hard to find. Is this still work in progress or is it ready merging?

[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR]   RuleMemoizationEnforcementTest.everyStaticRulesMethodIsMemoized:119 [detection-rule classes whose static rules() is not memoized — wrap the body with Memoize.of(...) so shared subtrees are built once (see #476)]
Expecting empty but was: ["com.ibm.plugin.rules.detection.auth.PrincipalAuthRules",
    "com.ibm.plugin.rules.detection.auth.JwtAuthRules",
    "com.ibm.plugin.rules.detection.auth.MtlsAuthRules",
    "com.ibm.plugin.rules.detection.auth.AuthDetectionRules",
    "com.ibm.plugin.rules.detection.auth.SamlAuthRules",
    "com.ibm.plugin.rules.detection.auth.ApiKeyAuthRules",
    "com.ibm.plugin.rules.detection.auth.OAuthAuthRules"]
[INFO]
[ERROR] Tests run: 165, Failures: 1, Errors: 0, Skipped: 7
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for sonar-cryptography 2.0.0-SNAPSHOT:
[INFO]
[INFO] sonar-cryptography ................................. SUCCESS [  0.646 s]
[INFO] common ............................................. SUCCESS [  1.696 s]
[INFO] engine ............................................. SUCCESS [  5.281 s]
[INFO] mapper ............................................. SUCCESS [  6.105 s]
[INFO] output ............................................. SUCCESS [  1.609 s]
[INFO] enricher ........................................... SUCCESS [  0.999 s]
[INFO] rules .............................................. SUCCESS [  0.545 s]
[INFO] java ............................................... FAILURE [ 10.387 s]
[INFO] python ............................................. SKIPPED
[INFO] go ................................................. SKIPPED
[INFO] sonar-cryptography-plugin .......................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  27.490 s
[INFO] Finished at: 2026-07-20T11:09:14+02:00
[INFO] ------------------------------------------------------------------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants