|
1 | 1 | # type_cosplay
|
2 | 2 |
|
3 |
| -**What it does:** |
| 3 | +**What it does:** Checks that all deserialized types have a proper discriminant so that |
| 4 | +all types are guaranteed to deserialize differently. |
4 | 5 |
|
5 |
| -**Why is this bad?** |
6 |
| - |
7 |
| -**Known problems:** When only one enum is serialized, may miss certain edge cases. |
8 |
| - |
9 |
| -**Example:** |
| 6 | +Instead of searching for equivalent types and checking to make sure those specific |
| 7 | +types have a discriminant, this lint takes a more strict approach and instead enforces |
| 8 | +all deserialized types it collects, to have a discriminant, regardless of whether the |
| 9 | +types are equivalent or not. |
10 | 10 |
|
11 |
| -```rust |
12 |
| -// example code where a warning is issued |
13 |
| -``` |
| 11 | +We define a proper discriminant as an enum with as many variants as there are struct |
| 12 | +types in the program. Further, the discriminant should be the first field of every |
| 13 | +struct in order to avoid overwrite by arbitrary length fields, like vectors. |
14 | 14 |
|
15 |
| -Use instead: |
| 15 | +A second case of a proper discriminant is when a single enum contains as variants all the struct |
| 16 | +types that will be deserialized. This "umbrella" enum essentially has a built-in |
| 17 | +discriminant. If it is the only type that is deserialized, then all struct types |
| 18 | +are guaranteed to be unique since the program will have to match a specific variant. |
16 | 19 |
|
17 |
| -```rust |
18 |
| -// example code that does not raise a warning |
19 |
| -``` |
20 |
| - |
21 |
| -Returns true if the `adt` has a field that is an enum and the number of variants of that enum is at least the number of deserialized struct types collected. |
| 20 | +**Why is this bad?** |
| 21 | +The type cosplay issue is when one account type can be substituted for another account type. |
| 22 | +This occurs when a type deserializes exactly the same as another type, such that you can't |
| 23 | +tell the difference between deserialized type `X` and deserialized type `Y`. This allows a |
| 24 | +malicious user to substitute `X` for `Y` or vice versa, and the code may perform unauthorized |
| 25 | +actions with the bytes. |
| 26 | + |
| 27 | +**Known problems:** In the case when only one enum is deserialized, this lint by default |
| 28 | +regards that as secure. However, this is not always the case. For example, if the program |
| 29 | +defines another enum and serializes, but never deserializes it, a user could create this enum, |
| 30 | +and, if it deserializes the same as the first enum, then this may be a possible vulnerability. |
| 31 | + |
| 32 | +Furthermore, one may have alternative definitions of a discriminant, such as using a bool, |
| 33 | +or u8, and not an enum. This will flag a false positive. |
0 commit comments