CWE-843, Access of Resource Using Incompatible Type, known as type confusion, happens when a product allocates or initializes a resource such as a pointer, object or variable as one type, then later accesses it as an incompatible type. It is best known from C and C++, but MITRE is clear that it is not unique to them.
If you write parsers, file format readers, browsers, document viewers or anything that handles untrusted structured data, this one is for you.
How it happens
The resource does not have the properties the code expects, so logic breaks. In languages without memory safety, the damage is worse. When a memory buffer is accessed using the wrong type, the code can read or write beyond the bounds of the buffer if the allocated buffer is smaller than the type it is now treated as.
MITRE notes the weakness is frequently associated with unions when parsing data with many embedded object types in C. Any application that can interpret the same variable or memory location in more than one way can have it.
Here is a deliberately small C illustration of the pattern.
struct small { int kind; int id; };
struct big { int kind; char name[64]; void (*cb)(void); };
void handle(void *obj, int kind_from_input) {
if (kind_from_input == 1) {
struct big *b = (struct big *)obj; /* attacker said it is big */
b->cb(); /* but it was allocated as small */
}
}
The type tag comes from input, not from how the object was created. That is the whole bug.
It is not only memory unsafe languages. MITRE points out that PHP applications can be triggered by providing array parameters when scalars are expected, or the reverse, and that Perl, which converts values automatically when used as another type, can have these issues too.
The observed CVE list covers the range:
- CVE-2025-32352 (details): type confusion in a PHP app allowed authentication bypass when users had passwords whose MD5 hashes could be interpreted as numbers.
- CVE-2010-4577: type confusion in a CSS sequence led to an out-of-bounds read.
- CVE-2011-0611: a size inconsistency allowed code execution and was first discovered being actively exploited in the wild.
- CVE-2010-0258: an improperly parsed file containing records of different types led to code execution when a memory location was interpreted as a different object than intended.
What an attacker gains
MITRE lists impact across availability, integrity and confidentiality: reading memory, modifying memory, executing unauthorized code or commands, and crashing or restarting the program. The record notes that out-of-bounds read or write is possible when the buffer is smaller than the type now applied to it.
The PHP example shows the logical side: no memory corruption at all, just an authentication check that compares values loosely and says yes.
How to find it
MITRE notes that static analysis, commonly called SAST, can find some instances by modeling data flow and control flow and looking for vulnerable patterns that connect sources of input with sinks, and rates this as high effectiveness. Beyond tooling:
- Grep for unions and for casts from void pointers or base types to derived types, and check what proves the cast is valid.
- In PHP, search for loose comparisons on values that come from a request or a hash.
- Fuzz parsers with files whose type fields disagree with their contents.
- Compile with sanitizers in test builds so a bad access fails loudly.
How to fix it
The MITRE record has no formal mitigation list for this entry, so these are practical steps that follow from the cause:
- Tie the type to the object, not to the input. Store the type at allocation time and check that stored tag before every cast.
- Validate sizes before use. If the type needs more bytes than the buffer holds, reject it.
- In C++, prefer checked casts and variant types over raw unions.
- In PHP, use strict comparison so values are not converted silently, and check parameter types before use.
// Loose comparison can treat some strings as numbers
if (md5($input) == $stored) { ... }
// Strict comparison, and a constant-time check for hashes
if (hash_equals($stored, md5($input))) { ... }
The second form removes the type juggling. For real password storage, use a proper password hash, which is covered in the CWE-916 post.
- Keep parsing libraries current. Several of the examples above are bugs in widely used parsers, so a dependency scan is part of the defense. You can run the free in-browser dependency scan on a manifest without logging in. The file stays on your machine, and it handles up to 100 dependencies.
Quick check
Is type confusion only a C and C++ problem?
No. MITRE says it can appear in any application that interprets a value in multiple ways, and cites PHP array versus scalar parameters and Perl automatic conversion.
Where does the bad type usually come from?
Often from input. A type field in a file or request is trusted over how the object was actually created.
What does a loose comparison have to do with it?
In the PHP example, a hash that looks like a number is compared as a number. Using strict comparison keeps the types honest.