Insecure deserialization is a quieter vulnerability than a leaked key, but it can be just as serious: when an app turns untrusted data back into objects without care, an attacker can craft input that manipulates the app's state or, with the wrong libraries, runs code. On mobile, the untrusted data arrives through the channels you already accept input from, the network, deep links, inter-app communication, and stored files, so the fix is to treat deserialization of any external data as a place to be careful. Here is what insecure deserialization is, where the untrusted data comes from, and how to deserialize safely.
Short answer
Insecure deserialization is when an app converts untrusted data back into objects without validation, which can let an attacker tamper with the app's state or, depending on the platform and libraries, trigger unexpected object creation or code execution. Per OWASP, the defense is to avoid deserializing untrusted data into complex objects, validate and constrain what you accept, and use safe APIs, such as secure coding on iOS that requires the expected class, and strict, schema-validated parsing rather than native object serialization. On mobile, untrusted serialized data arrives via the network, deep links, inter-app communication, and stored files, so treat all of those as untrusted input when deserializing.
What you should know
- Deserialization turns data into objects: doing it on untrusted data is risky.
- It can tamper with state or run code: depending on the platform and libraries.
- Untrusted data has many sources: network, deep links, IPC, stored files.
- Avoid native object serialization of untrusted input: prefer safe, validated formats.
- Use secure APIs: like secure coding that enforces the expected class.
What is insecure deserialization?
It is reconstructing objects from data that an attacker can influence, without controlling what gets created. Serialization turns objects into a byte stream or text for storage or transport, and deserialization reverses it, and the vulnerability arises when the input is untrusted and the deserialization is unconstrained: an attacker supplies crafted data that, when deserialized, produces objects you did not expect, sets fields to values that bypass your logic, or, with vulnerable libraries and gadget chains, leads to code execution. Even without full code execution, the ability to forge or tamper with deserialized objects can subvert authorization, integrity checks, or business logic, since the app trusts the reconstructed object. The root issue is treating serialized input as safe to materialize into objects when it came from outside your trust boundary.
Where does untrusted serialized data come from?
The same channels your app already accepts input from. The table lists them.
| Source | Why it is untrusted |
|---|---|
| Network responses | A server or interceptor can supply crafted data |
| Deep links and URLs | Anyone can craft the parameters |
| Inter-app communication | Data from another app, including a malicious one |
| Stored or cached files | Could be tampered with on a compromised device |
| Downloaded content | Controlled by whoever serves it |
The point is that serialized data crossing into your app from any of these is attacker-influenceable, so deserializing it into objects without validation is where the risk lives. Native object-serialization mechanisms are especially dangerous with untrusted input, because they can reconstruct arbitrary object graphs, while a strict, schema-validated parse of a simple format limits what can be produced. Treat any deserialization of external data as handling untrusted input.
How do you deserialize safely?
Constrain what you accept, validate it, and use safe APIs. Avoid deserializing untrusted data with native object-serialization mechanisms that can instantiate arbitrary types; prefer simple, well-defined formats like JSON parsed into known types with strict validation, so the input cannot conjure unexpected objects. On iOS, use secure coding that requires the expected class when unarchiving, rather than accepting any class, so a crafted archive cannot substitute a different type. Validate the deserialized result against what you expect, ranges, types, required fields, before acting on it, and never trust a reconstructed object to have made security decisions for you. Keep deserialization of external data minimal and well-bounded, and where you can, avoid round-tripping complex objects from untrusted sources at all. The principle is that data from outside your trust boundary should be parsed into known, validated shapes, not materialized blindly into objects.
What to watch out for
The first trap is using native object serialization to deserialize untrusted input, which can reconstruct arbitrary objects and, with gadget chains, run code; use safe, validated formats instead. The second is trusting a deserialized object to be well-formed or to have enforced your rules, when crafted input can forge it; validate after deserializing. The third is forgetting that deep links, IPC, and stored files are untrusted sources just like the network. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled binary against OWASP MASVS and assesses how your app handles input and data, which complements reviewing where you deserialize external data. The deserialization logic you make safe in your code.
What to take away
- Insecure deserialization is converting untrusted data into objects without validation, which can tamper with app state or, depending on libraries, run code.
- Untrusted serialized data reaches your app via the network, deep links, inter-app communication, and stored files, so treat all of those as untrusted input.
- Avoid native object serialization of untrusted input, prefer strict schema-validated formats, use secure coding that enforces the expected class, and validate the result.
- Use a pre-submission scan such as PTKD.com to assess how your app handles external input alongside reviewing your deserialization code.



