CWE-1106 is the weakness of using literal constants that may need to change over time, instead of symbolic constants. The classic name is the magic number: a bare 4096 or 30 in the middle of a function with no hint about what it means.
MITRE classes it as a quality issue with no direct security implications and prohibits using it to map real vulnerabilities. Its relevance is indirect, and it helps to be clear about how.
How it happens
A developer needs a buffer size, a timeout, a retry limit or a port. Typing the number is faster than naming it. The same number then gets typed again in a second file. Later the value has to change, and someone updates four of the five places.
What an attacker gains
Nothing directly. MITRE says the issue makes the product harder to maintain, which indirectly affects security by making it more time-consuming to find and fix vulnerabilities, and might make it easier to introduce them. The risk case is easy to picture: a size limit is raised in the code that allocates memory but not in the code that checks input length.
How to find it
Static analysis can find some instances, according to the record. Many linters have a magic number rule you can switch on. A quick manual pass is to grep for numeric literals other than 0 and 1 in logic code and ask what each one represents.
How to fix it
Give each meaningful value one name and define it once.
# Before: the same literal in two places
if len(payload) > 4096:
reject()
buf = bytearray(4096)
# After: one named constant
MAX_PAYLOAD_BYTES = 4096
if len(payload) > MAX_PAYLOAD_BYTES:
reject()
buf = bytearray(MAX_PAYLOAD_BYTES)
Now a change to the limit happens in one line, and the check and the allocation cannot drift apart.
Quick check
Should every number become a constant?
No. Values like 0 or 1 in an obvious loop are fine. Name the ones that carry meaning or might change.