Module A needs module B, and module B needs module A. It builds today, and every change after that is harder than it should be.
CWE-1047 is the weakness where the product contains modules in which one module has references that cycle back to itself. MITRE lists it as a Base weakness in any language, and gives Java as an example, where the cycles are between packages.
How it happens
Cycles form gradually. A utility module starts calling back into the module that uses it. A shared class gets moved to the wrong package. A convenience import is added late in a release cycle.
orders -> billing -> customers -> orders
The result is that none of these modules can be understood, built or tested without the others.
MITRE's consequence is reduced maintainability, with an indirect security effect: it is harder and slower to find and fix vulnerabilities because modularity is insufficient. MITRE adds that it can also prevent the product from running reliably, and that if the relevant code is reachable by an attacker, the reliability problem might introduce a vulnerability. No CVEs are observed.
Think about a security patch. If a fix in one module forces changes across a ring of dependent modules, it takes longer to ship and is more likely to miss something.
How to find it
MITRE lists no detection methods. Dependency analysis tools for your language can detect cycles between packages and modules. Add a check to CI so new cycles fail the build.
How to fix it
MITRE lists no formal mitigations. Reasonable steps:
- Map the cycle and pick the dependency that is least justified.
- Extract the shared part into a new module both sides depend on.
- Invert the dependency with an interface owned by the lower level module.
- Enforce a one way dependency rule and test it in CI.
- Keep modules small enough that their purpose is clear.
Quick check
How do cycles affect security work?
They make code harder to maintain, so vulnerabilities take longer to find and fix, and changes risk side effects in other modules.