Main Content

CWE Rule 494

Download of Code Without Integrity Check

Since R2026a

Description

Download of Code Without Integrity Check

Polyspace Implementation

The rule checker checks for Code from tainted source used without sanitizing

Examples

expand all

Issue

This issue occurs when these events occur in sequence:

  1. Code or script is obtained from a tainted source.

  2. Obtained code is saved into memory.

  3. The code is passed to a sensitive function without sanitizing it first.

To use this coding rule checker, specify these in a Datalog file:

  • Source of taint — You can either use the default taint sources or you can specify a function as the taint source. To use the default taint sources, add this line of code:

    Custom_CWE_494.useDefaultTaintSources().
    To specify a function foo() as the taint source:
    Custom_CWE_494.Basic.taintSource("foo", $OutReturnDeref(), "Taint source").
    Sources of taint are identified in the event list and the specified string is the event message.

  • Functions that allocate memory — This code specifies that the function foo() allocates memory:

    Alias.Basic.allocates("foo", $OutReturnValue()).
    If you do not specify the memory allocation function, Polyspace® assumes that the code is not saved in memory and does not report a violation.

  • The sensitive function that executes the obtained code — This code specifies the function foo() as the sensitive function:

    Custom_CWE_494.Basic.sensitive("foo", $InParameterDeref(0), "Sensitive function invoked with tainted input!").
    The password setting function is identified in the event list and the specified string is the event message.

Risk

Executing scripts or code without verifying the origin or integrity of the code allows an attacker to execute malicious code.

Fix

Before executing code or script obtained from a tainted source, validate or sanitize the code by calling a sanitizer function. This Datalog code specifies the function foo() as the sanitizing function:

Custom_CWE_494.Basic.sanitizing("foo()", $OutParameterDeref(0)).
The password checking function is identified in the event list and the specified string is the event message.

Example

In this code, the function dlopen() obtains a script from a tainted path and then executes the code in the sensitive function dlsym(). Polyspace reports a violation.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
typedef void (*FunctionType)();
extern int sanitizer(const char *path, unsigned char *output);

int main() {
	const char *libPath = "./libmylibrary.so";
	unsigned char actualHash[32];

	void *handle = dlopen(libPath, RTLD_LAZY);
	if(!handle) {
		printf("Cannot open library: %s", dlerror());
		return 1;
	}
	dlerror(); // Reset errors

	FunctionType func = (FunctionType) dlsym(handle, "loadMe"); // Noncompliant
	const char *dlsym_error = dlerror();
	if(dlsym_error) {
		printf("Cannot load symbol 'loadMe':  %s", dlsym_error);
		dlclose(handle);
		return 1;
	}
	func();
	dlclose(handle);
	return 0;
}
To detect the violation, specify the taint source and the sensitive function using this Datalog code as an input to -code-behavior-specification
Custom_CWE_494.Basic.taintSource("dlopen", $OutReturnDeref(), "Getting a remote dynamic library!").
Alias.Basic.allocates("dlopen", $OutReturnValue()).
Custom_CWE_494.Basic.sensitive("dlsym", $InParameterDeref(0), "Using a remote dynamic library handle!").

Correction

To fix this violation, call a sanitizing function after you obtain the code from a tainted source.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
typedef void (*FunctionType)();
extern int sanitizer(void*);

int main() {
	const char *libPath = "./libmylibrary.so";
	void *handle = dlopen(libPath, RTLD_LAZY);
	if(!handle) {
		printf("Cannot open library: %s", dlerror());
		return 1;
	}
	dlerror(); // Reset errors
    
    // Sanitize obtained code
    if(0 != sanitizer(handle)){
        return -1;
    }
	FunctionType func = (FunctionType) dlsym(handle, "loadMe"); // Compliant
	const char *dlsym_error = dlerror();
	if(dlsym_error) {
		printf("Cannot load symbol 'loadMe':  %s", dlsym_error);
		dlclose(handle);
		return 1;
	}
	func();
	dlclose(handle);
	return 0;
}
To specify the violation, specify the function sanitizer() as the sanitizer function, use this Datalog code:
Custom_CWE_494.Basic.taintSource("dlopen", $OutReturnDeref(), "Getting a remote dynamic library!").
Alias.Basic.allocates("dlopen", $OutReturnValue()).
Custom_CWE_494.Basic.sensitive("dlsym", $InParameterDeref(0), "Using a remote dynamic library handle!").
Custom_CWE_494.Basic.sanitizing("sanitizer", $OutParameterDeref(0)).

Check Information

Category: Data Integrity Issues
PQL Name: std.cwe_native.R494

Version History

Introduced in R2026a