mutated × unstructured — blows up live on input you didn't expect
Config / Environment Drift Crash
An upgrade renames the config key the code still reads directly; the service boots fine and dies on the first request in the new environment.
01the recipe
In the wild
compound ofImpure FunctionsCWE-1108 Global RelianceVersion & Library MismanagementCWE-1104compoundCWE-248 Uncaught ExceptionCWE-754 Unchecked Condition
example.py
# SMELL: read a config key directly, assuming the deploy still provides it.
# (impure functions x library/version mismanagement)
TIMEOUT = os.environ["RPC_TIMEOUT_MS"] # renamed to RPC_TIMEOUT_S in v2 -> KeyError
def call():
client.invoke(timeout=int(TIMEOUT))
# RIGHT: read through validated config -- presence check + migration-aware error.
def get_timeout():
raw = os.environ.get("RPC_TIMEOUT_S")
if raw is None:
raise ConfigError("RPC_TIMEOUT_S required (was RPC_TIMEOUT_MS before v2)")
return float(raw)Reading os.environ by key couples the code to a contract the platform can change between versions. After an upgrade renames the key, the process imports fine and throws an uncaught KeyError on first use -- in the new environment only. Centralize config access with explicit presence checks and a migration-aware error.
// observed
drifted: KeyError: 'RPC_TIMEOUT_MS' on the first request after deploy right: a clear ConfigError naming the renamed key; no surprise mid-request
02weakness catalog
Mapped weaknesses (CWE)
On its own, this defect is catalogued by MITRE as one or more of these weaknesses. The exploitable vulnerability usually appears only when it chains or combines with another.