CS.SV.TAINTED.DESERIALIZATION
Use of Unvalidated Integer during deserialization in object creation
Whenever input is accepted from the user or the outside environment, it should be validated for type, length, format, and range before it is used. Until properly validated, the data is said to be tainted. The CS.SV.TAINTED family of checkers looks for the use of tainted data in code.
The CS.SV.TAINTED.DESERIALIZATION checker flags code where unvalidated data is passed as an argument to an object constructor call, inside which it is used for any internal members assignment. Such usage constitutes tainted data deserialization and is reported by the checker as potentially dangerous.
Vulnerability and risk
When input to code isn't validated properly, an attacker can craft the input in a form that isn't expected by the application. The receipt of unintended input can result in altered control flow, arbitrary resource control, and arbitrary code execution. With this sort of opportunity, an attacker could
- provide unexpected values and cause a program crash
- cause excessive resource consumption
- read confidential data
- use malicious input to modify data or alter control flow
- execute arbitrary commands
An object constructed with tainted data can manifest unexpected behaviors that can be especially dangerous for instantiations of classes defined in third party code. Constructing such objects opens the possibility for exploiting weaknesses. Even in the cases when source code is available, constructing objects with untrusted data is dangerous, because developers might assume that any such object is valid and safe to use in potentially dangerous contexts.
Vulnerable code example
using System;
using System.IO;
namespace TaintedResource {
class TestTaintedResource {
const string fileName = "File.dat";
public static void TaintedResourceExample1() {
int taintedIntValue = Console.Read();
SimpleVariableTest test1 = new SimpleVariableTest(taintedIntValue); // CS.SV.TAINTED.DESERIALIZATION
}
}
class SimpleVariableTest
{
public SimpleVariableTest(int value) {
setIntValue = value;
}
private int setIntValue;
}
}
Klocwork produces an issue report at line 9, indicating that, “Unvalidated integer value 'taintedIntValue' that is received from 'Read' at line 8 is used during deserialization of data via a call to 'constructor' at line 9.” In this case, potentially tainted data is sent as an argument while calling constructor to create an object, which actually will assign the value of the argument to the field member of the constructor class, which could be exploited by a malicious user.
Fixed code example
using System;
using System.IO;
namespace TaintedResource {
class TestTaintedResource {
const string fileName = "File.dat";
public static void TaintedResourceExample1() {
int taintedIntValue = Console.Read();
if (taintedIntValue > MAX_VALUE || taintedIntValue < MIN_VALUE)
{
return;
}
SimpleVariableTest test1 = new SimpleVariableTest(taintedIntValue);
}
}
class SimpleVariableTest
{
public SimpleVariableTest(int value) {
setIntValue = value;
}
private int setIntValue;
}
}
In this example, Klocwork no longer reports a defect because the integer 'num' is checked at line 9 before it is used in the constructor call.
Related checkers
- CS.RESOURCE.LOOP
- CS.SV.TAINTED.ALLOC_SIZE
- CS.SV.TAINTED.BINOP
- CS.SV.TAINTED.CALL.BINOP
- CS.SV.TAINTED.CALL.GLOBAL
- CS.SV.TAINTED.CALL.INDEX_ACCESS
- CS.SV.TAINTED.CALL.LOOP_BOUND
- CS.SV.TAINTED.CALL.LOOP_BOUND.RESOURCE
- CS.SV.TAINTED.GLOBAL
- CS.SV.TAINTED.INDEX_ACCESS
- CS.SV.TAINTED.LOOP_BOUND
- CS.SV.TAINTED.LOOP_BOUND.RESOURCE
External guidance
Security training
Application security training materials provided by Secure Code Warrior.