Skip to content

Crypto: Add Java cryptographic check queries - #20568

Closed
unprovable wants to merge 2 commits into
github:mainfrom
Santandersecurityresearch:java-crypto-check
Closed

Crypto: Add Java cryptographic check queries#20568
unprovable wants to merge 2 commits into
github:mainfrom
Santandersecurityresearch:java-crypto-check

Conversation

@unprovable

Copy link
Copy Markdown
Contributor

These are some example queries that check the cryptography present in output from a java source repo. Again, these build on the existing examples both in java and in other CBOM and cryptographic issue checking codeQL queries:

  • InsecureNonceGeneration.ql - as before
  • InsecureNonceSource.ql - as before
  • KnownWeakKDFIterationCount.ql - as before
  • NonAESGCMCipher.ql - detects non-AES in GCM mode ciphers. Can be updated to be 'non AES256 in GCM mode' but this gives more alerts on inferred key lengths.
  • NonceReuse.ql - as before
  • ReusedNonce.ql - as before
  • UnknownKDFIterationCount.ql - as before
  • WeakAsymmetric.ql - finds weak asymmetric RSA ciphers using key lengths < 2048
  • WeakBlockModes.ql - similar to NonAESGCM, this finds instances of known-bad block modes ECB, CFB, OFB, and CTR
  • WeakHashing.ql - finds potentially weak hashing instances using the whitelist of SHA256, SHA384, and SHA512 (though this is yet to be checked against SHA3 variants)
  • WeakKDFIterationCount.ql - as before
  • WeakKDFKeySize.ql - as before
  • WeakRSA.ql - an allternative method from WeakAsymmetric.ql, but functionally the same.
  • WeakSymmetricCiphers.ql - detects known-weak ciphers from a blocklist of DES, TripleDES, DoubleDES, RC2, RC4, IDEA, and Blowfish.

@unprovable
unprovable requested a review from a team as a code ownerOctober 1, 2025 11:58
@nicolaswill
nicolaswill self-requested a review October 1, 2025 12:03
* @description An AES cipher is in use without GCM
* @kind problem
* @problem.severity error
* @security.severity low

@bdrodesbdrodesOct 1, 2025

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.

Was there a reason for calling this security severity low? I think this might be one of those things that's too org-specific to put in the query general meta-data. This comment applies for all the queries in the PR.

@unprovableunprovableOct 1, 2025

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is in line with ASVSv5. Yes, this is quite specific and of course in the future it might be a 'high' issue for reasons we know not of yet. Removing any @security.severity might be useful.

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.

I'm inclined to remove all security.severity meta-data because of how specific it will be per org. Does that give you heartburn?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Not at all. See next commit in thread. :)

@unprovable

Copy link
Copy Markdown
ContributorAuthor

I've sanitised out the @security.severity ratings. We can maybe sub for @severity warning at some point if it's deemed that there needs to be some kind of "how bad is it?" metric. But I agree with @bdrodes that it's too subjective for now.

@nicolaswillnicolaswill 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.

Thank you for the contribution! I've left some minor comments mainly regarding name string vs type comparison and tags.

from Crypto::KeyOperationAlgorithmNode alg, string name, string msg
where
name = alg.getAlgorithmName() and
name in ["DES", "TripleDES", "DoubleDES", "RC2", "RC4", "IDEA", "Blowfish"] and

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.

Rather than comparing name strings, the standardized types in Crypto::KeyOpAlg should be compared against getAlgorithmType. Here is an example of that syntax: this.getAlgorithmType() = KeyOpAlg::TMac(KeyOpAlg::CMAC()). To avoid redundant typing of the module namespaces, the KeyOpAlg module could optionally also be imported as follows: import Crypto::KeyOpAlg as Alg.

from Crypto::HashAlgorithmNode alg, string name, string msg
where
name = alg.getAlgorithmName() and
not name in ["SHA256", "SHA384", "SHA512", "SHA-256", "SHA-384", "SHA-512"] and

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.

Like the comment on symmetric algorithms, the hash family and hash digest size should be used rather than string comparisons. The appropriate predicates/classes to use would be HashType (getHashFamily()) and getDigestLength().

Typing this out also makes me realize we need to standardize those predicate and class names...

class NonAESGCMAlgorithmNode extends Crypto::KeyOperationAlgorithmNode {
NonAESGCMAlgorithmNode() {
this.getAlgorithmType() = Crypto::KeyOpAlg::TSymmetricCipher(Crypto::KeyOpAlg::AES()) and
this.getModeOfOperation().getModeType() != Crypto::KeyOpAlg::GCM()

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.

Suggested change
this.getModeOfOperation().getModeType()!= Crypto::KeyOpAlg::GCM()
notthis.getModeOfOperation().getModeType()= Crypto::KeyOpAlg::GCM()

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.

That's not actually we want we want, chatting with @nicolaswill in a side channel, so disregard.

* @kind problem
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-327

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.

This needs quantum and experimental tags.

* @kind problem
* @problem.severity error
* @precision high
* @tags external/cwe/cwe-327

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.

This needs quantum and experimental tags.

CopilotAI 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.

Pull Request Overview

This PR adds comprehensive Java cryptographic security checks through CodeQL queries that identify various cryptographic vulnerabilities and weak configurations. The queries focus on detecting insecure cryptographic practices in Java codebases.

  • Adds 11 new CodeQL queries for detecting cryptographic security issues
  • Implements checks for weak ciphers, key sizes, hashing algorithms, and nonce handling
  • Covers symmetric/asymmetric encryption, key derivation functions, and block cipher modes

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
WeakSymmetricCiphers.qlDetects usage of weak symmetric cipher algorithms like DES, RC4, etc.
WeakRSA.qlIdentifies RSA implementations with key lengths below 2048 bits
WeakKDFKeySize.qlFinds key derivation functions with output lengths below 256 bits
WeakKDFIterationCount.qlDetects KDF operations with iteration counts below 100,000
WeakHashing.qlIdentifies non-approved hash algorithms (excludes SHA-256/384/512)
WeakBlockModes.qlFinds AES usage with insecure block modes (ECB, CFB, OFB, CTR)
WeakAsymmetric.qlDetects asymmetric ciphers with key sizes below 2048 bits
UnknownKDFIterationCount.qlRemoves severity warning metadata
NonceReuse.qlIdentifies reuse of cryptographic nonces
NonAESGCMCipher.qlDetects AES usage without GCM mode
InsecureNonceGeneration.qlFinds nonces generated from insecure sources

/**
* @name Weak known key derivation function output length
* @description Detects key derivation operations with a known weak output length
* @id java/quantum/weak-kdf-iteration-count

CopilotAIOct 2, 2025

Copy link

Choose a reason for hiding this comment

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

The @id should be 'java/quantum/weak-kdf-key-size' to match the query name and purpose, not 'weak-kdf-iteration-count'.

Suggested change
* @id java/quantum/weak-kdf-iteration-count
* @id java/quantum/weak-kdf-key-size

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,24 @@
/**
* @name Weak Asymetric Key Size

CopilotAIOct 2, 2025

Copy link

Choose a reason for hiding this comment

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

Corrected spelling of 'Asymetric' to 'Asymmetric'.

Suggested change
* @name Weak Asymetric Key Size
* @name Weak Asymmetric Key Size

Copilot uses AI. Check for mistakes.
// Can't be an elliptic curve
not Crypto::isEllipticCurveAlgorithmName(algName)
select op,
"Use of weak asymmetric key size (int bits)" + keySize.toString() + " for algorithm " +

CopilotAIOct 2, 2025

Copy link

Choose a reason for hiding this comment

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

The error message formatting is unclear. '(int bits)' should be '(' + keySize.toString() + ' bits)' for proper readability.

Suggested change
"Use of weak asymmetric key size (int bits)"+keySize.toString()+" for algorithm "+
"Use of weak asymmetric key size ("+keySize.toString()+" bits) for algorithm "+

Copilot uses AI. Check for mistakes.
@nicolaswill

Copy link
Copy Markdown
Contributor

There are also duplicate query IDs (potentially, duplicate queries, though I have not verified the contents):

Run python3 misc/scripts/check-query-ids.py
Query ID java/quantum/reused-nonce is used in multiple queries:
- java/ql/src/experimental/quantum/Analysis/NonceReuse.ql
- java/ql/src/experimental/quantum/Analysis/ReusedNonce.ql
Query ID java/quantum/insecure-nonce is used in multiple queries:
- java/ql/src/experimental/quantum/Analysis/InsecureNonceGeneration.ql
- java/ql/src/experimental/quantum/Analysis/InsecureNonceSource.ql
Query ID java/quantum/weak-kdf-iteration-count is used in multiple queries:
- java/ql/src/experimental/quantum/Analysis/WeakKDFKeySize.ql
- java/ql/src/experimental/quantum/Analysis/KnownWeakKDFIterationCount.ql
- java/ql/src/experimental/quantum/Analysis/WeakKDFIterationCount.ql
FAIL: duplicate query IDs found in src folders. Please assign these queries unique IDs.


import experimental.quantum.Language

class WeakRSAAlgorithmNode extends Crypto::KeyOperationAlgorithmNode {

Check warning

Code scanning / CodeQL

Acronyms should be PascalCase/camelCase. Warning

Acronyms in WeakRSAAlgorithmNode should be PascalCase/camelCase.
@nicolaswill

Copy link
Copy Markdown
Contributor

Lastly, could you please run codeql query format -i on all of the QL files? All contributions to this repo are validated against the auto-formatter. If you're using VS Code, you can also enable format-on-save for QL in the settings.

@nicolaswillnicolaswill changed the title Added java cryptographic check queriesCrypto: Add Java cryptographic check queriesOct 2, 2025
@bdrodes

Copy link
Copy Markdown
Contributor

@nicolaswill can you close this PR, I created my own PR based on this PR so we can make fast edits: See #20605

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@unprovable@nicolaswill@bdrodes@github-advanced-security