IBM / sonar-cryptography

This repository contains a SonarQube Plugin that detects cryptographic assets in source code and generates CBOM.
Apache License 2.0
23 stars 4 forks source link

BouncyCastle implicit limitation in depending rules #17

Open n1ckl0sk0rtge opened 3 months ago

n1ckl0sk0rtge commented 3 months ago

Example

Take for example CBCBlockCipher which implements the interface BlockCipher. To instantiate such an object, one can use the static method CBCModeCipher.newInstance(BlockCipher cipher). Relevant information is contained into the cipher parameter, and we aim to capture it using depending detection rules.

However, because the cipher parameter is of type BlockCipher, nothings prevents the developer from having a call CBCModeCipher.newInstance(CBCModeCipher.newInstance(CBCModeCipher.newInstance(...))) with un unbounded succession of calls. When writing the rules, this means that if we add all the BlockCipher rules as depending detection rules for the parameter of CBCModeCipher.newInstance, we will include the CBCModeCipher.newInstance rule, which will create an infinite chain of depending detection rules.

Looking deeper into how these classes are supposed to be used, it looks like all classes implementing BlockCipher are divided into two categories: ___Engine (taking no parameters to instantiate) and ___BlockCipher (taking a BlockCipher parameter to instantiate) classes, and that ___Engine classes are supposed to be the only one used as parameter of ___BlockCipher classes. For example, CBCBlockCipher cipher = CBCBlockCipher.newInstance(DESEngine.newInstance()).

Generalisation

This case seems more general than just the BlockCipher interface, for example it also happens with the AsymmetricBlockCipher interface, and seems to be a recurring pattern in how BouncyCastle is coded.

Why this matters

Therefore, to avoid the case of infinite chains of rules described in the example, we assume in our rules that only ___Engine classes are used as parameter of the other classes of the same interface. This assumption seems to be confirmed by code examples, in which I always observed these kinds of instantiations.