CWE-153 is about input that carries characters a downstream component reads as substitution characters. When the component sees one, it replaces it with other content. If an outsider supplied the character, an outsider steers the replacement.
Shells, template systems, and anything with placeholder syntax have substitution rules. Developers building text for those components from external input should care.
How it happens
The upstream component accepts a value and passes it along without neutralizing special elements. The downstream component treats a symbol in it as a request to substitute.
The one observed example in the record is CVE-2002-0770, a server that trusts the client to expand macros. Macro characters could be expanded to trigger information exposure. It is the same example attached to the macro weakness CWE-152, because the line between a macro symbol and a substitution character is thin. Both are markers that mean replace me.
What an attacker gains
The record lists integrity impact as unexpected state. When the replaced content comes from the server, the example shows that information can leak.
How to find it
MITRE gives no detection methods, so test and read.
- List where your code hands text to a component with substitution syntax.
- Send known substitution markers for that component and look at the output.
- Check that escaping happens at the boundary, once, for the right destination.
How to fix it
- Anticipate that substitution characters will be injected, removed or manipulated.
- Use an allowlist of valid input and reject the rest.
- Escape or encode any remaining value for the destination syntax, and prefer APIs that take data separately from templates.
Quick check
How is this different from macro symbol handling?
The mechanics are close. Macro symbols trigger expansion of defined macros, while substitution characters trigger replacement more broadly. Fixes are the same: treat input as literal and neutralize at the boundary.