Function Call With Incorrectly Specified Argument Value
Description
Function Call With Incorrectly Specified Argument Value is a programming error where code calls a function with an argument containing a value that is incorrect for the function's intended purpose, even though the type may be correct. This differs from type mismatches—the argument has the right type but the wrong value. Common examples include passing 0 instead of 1 for boolean flags, using wrong constants, hardcoded values that should be dynamic, or inverted boolean logic. These errors can cause functions to behave opposite to the programmer's intent or skip critical processing.
Risk
Incorrect argument values create serious security risks when they affect security-critical functions. Authentication functions called with wrong flag values may not properly report failures. Authorization checks with inverted boolean arguments may grant access when they should deny it. Error handling functions that receive wrong error codes may take inappropriate action. The risk is compounded because these bugs often pass code review—the code looks syntactically correct and type-checks successfully. They typically only manifest in specific execution paths, making them difficult to detect through testing.
Solution
Use named constants or enums instead of magic numbers to make argument intent clear. Create wrapper functions with explicit names that indicate the operation being performed. Use named parameters where the language supports them. Implement thorough unit tests that verify function behavior with different argument values. Conduct code reviews with specific focus on argument values in security-critical functions. Use static analysis tools that can detect common incorrect value patterns. Consider using builder patterns or configuration objects for functions with many boolean or flag parameters.
Common Consequences
| Impact | Details |
|---|---|
| Other | Scope: Other Quality Degradation - Functions behave incorrectly when called with wrong values, producing unexpected results. |
| Access Control | Scope: Access Control Bypass Protection Mechanism - Security functions with wrong flag values may fail to enforce checks. |
| Integrity | Scope: Integrity Unexpected State - Systems enter inconsistent states when functions operate with incorrect parameters. |
Example Code
Vulnerable Code
# Vulnerable: Wrong boolean value for error handling flag
sub ReportAuth {
my ($username, $result, $die_on_error) = @_;
if ($result != 0) {
# Authentication failed
if ($die_on_error) {
die "Authentication failed for $username";
}
# Just log if not dying
log_failure($username);
}
}
# Vulnerable: Called with 0 instead of 1
sub authenticate_user {
my ($username, $password) = @_;
my $result = check_credentials($username, $password);
# Vulnerable: Should be 1 to die on failure, but 0 is passed
ReportAuth($username, $result, 0); # WRONG VALUE!
# Authentication failures are silently logged, not terminated
return $result == 0;
}
// Vulnerable: Wrong mode value for file operations
#include <fcntl.h>
#include <sys/stat.h>
void vulnerable_create_file(const char* path) {
// Vulnerable: Using wrong mode - 0 instead of proper permissions
int fd = open(path, O_CREAT | O_WRONLY, 0); // Mode 0 = no permissions!
// File created with no read/write/execute permissions for anyone
write(fd, "data", 4);
close(fd);
}
// Vulnerable: Wrong flag for socket options
#include <sys/socket.h>
int vulnerable_socket_setup(int sockfd) {
int optval = 0; // Should be 1 to enable option
// Vulnerable: optval=0 disables option instead of enabling
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
// SO_REUSEADDR not actually enabled!
return 0;
}
// Vulnerable: Inverted boolean logic
int vulnerable_is_valid(int error_code) {
// error_code 0 means success, non-zero means error
// Vulnerable: Logic is backwards
return error_code; // Returns true (non-zero) on ERROR
// Should be: return error_code == 0;
}
// Vulnerable: Wrong flag values
public class VulnerableFlags {
private static final int FLAG_SECURE = 1;
private static final int FLAG_INSECURE = 0;
public void processRequest(Request request) {
// Vulnerable: Wrong flag passed
validateInput(request.getData(), FLAG_INSECURE); // WRONG!
// Should be FLAG_SECURE for security-critical validation
}
public void validateInput(String data, int securityLevel) {
if (securityLevel == FLAG_SECURE) {
// Perform thorough validation
strictValidation(data);
} else {
// Minimal validation only
basicValidation(data); // Less secure path taken!
}
}
}
// Vulnerable: Wrong constant for comparison
public class VulnerableComparison {
public static final int STATUS_SUCCESS = 0;
public static final int STATUS_FAILURE = 1;
public static final int STATUS_PENDING = 2;
public boolean isOperationSuccessful(int status) {
// Vulnerable: Comparing against wrong constant
return status == STATUS_FAILURE; // WRONG! Should be STATUS_SUCCESS
// Returns true when operation failed!
}
}
# Vulnerable: Wrong default or hardcoded value
import ssl
def vulnerable_ssl_connection(host, port):
context = ssl.create_default_context()
# Vulnerable: Wrong value disables certificate verification
context.check_hostname = False # WRONG! Should be True
context.verify_mode = ssl.CERT_NONE # WRONG! Should be CERT_REQUIRED
# Connection proceeds without certificate verification
return context.wrap_socket(socket.socket(), server_hostname=host)
# Vulnerable: Wrong array index
def vulnerable_get_permission(permissions, user_type):
ADMIN_INDEX = 0
USER_INDEX = 1
GUEST_INDEX = 2
# Vulnerable: Using wrong index
if user_type == 'admin':
return permissions[USER_INDEX] # WRONG! Gets user permissions, not admin
elif user_type == 'user':
return permissions[ADMIN_INDEX] # WRONG! Gets admin permissions
return permissions[GUEST_INDEX]
Fixed Code
# Fixed: Use named constants and clear parameter names
use constant {
DIE_ON_ERROR => 1,
LOG_ONLY => 0,
};
sub ReportAuth {
my ($username, $result, $die_on_error) = @_;
if ($result != 0) {
if ($die_on_error) {
die "Authentication failed for $username";
}
log_failure($username);
}
}
# Fixed: Use named constant for clarity
sub authenticate_user {
my ($username, $password) = @_;
my $result = check_credentials($username, $password);
# Fixed: Clear intent with named constant
ReportAuth($username, $result, DIE_ON_ERROR);
return $result == 0;
}
# Alternative: Use wrapper functions
sub authenticate_or_die {
my ($username, $password) = @_;
my $result = check_credentials($username, $password);
ReportAuth($username, $result, 1); # Always die on failure
return $result == 0;
}
// Fixed: Use proper mode values with named constants
#include <fcntl.h>
#include <sys/stat.h>
#define SECURE_FILE_MODE (S_IRUSR | S_IWUSR) // Owner read/write only
void secure_create_file(const char* path) {
// Fixed: Proper permissions
int fd = open(path, O_CREAT | O_WRONLY, SECURE_FILE_MODE);
if (fd < 0) {
return; // Handle error
}
write(fd, "data", 4);
close(fd);
}
// Fixed: Correct option value
#include <sys/socket.h>
int secure_socket_setup(int sockfd) {
int optval = 1; // Fixed: 1 to enable option
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
&optval, sizeof(optval)) < 0) {
return -1;
}
return 0;
}
// Fixed: Correct boolean logic
int secure_is_valid(int error_code) {
// Fixed: 0 means success (valid), non-zero means error (invalid)
return error_code == 0;
}
// Alternative: Wrapper with clear name
int is_success(int result_code) {
return result_code == 0;
}
int is_error(int result_code) {
return result_code != 0;
}
// Fixed: Use enums for type-safe flags
public class SecureFlags {
public enum SecurityLevel {
INSECURE,
BASIC,
SECURE,
PARANOID
}
public void processRequest(Request request) {
// Fixed: Clear, type-safe flag
validateInput(request.getData(), SecurityLevel.SECURE);
}
public void validateInput(String data, SecurityLevel level) {
switch (level) {
case PARANOID:
case SECURE:
strictValidation(data);
break;
case BASIC:
basicValidation(data);
break;
case INSECURE:
// Minimal validation
break;
}
}
}
// Fixed: Correct constant comparison
public class SecureComparison {
public enum OperationStatus {
SUCCESS,
FAILURE,
PENDING
}
public boolean isOperationSuccessful(OperationStatus status) {
// Fixed: Compare against SUCCESS
return status == OperationStatus.SUCCESS;
}
}
# Fixed: Proper SSL configuration
import ssl
def secure_ssl_connection(host, port):
context = ssl.create_default_context()
# Fixed: Enable security features
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED
return context.wrap_socket(socket.socket(), server_hostname=host)
# Fixed: Correct array indices with explicit mapping
from enum import IntEnum
class UserType(IntEnum):
ADMIN = 0
USER = 1
GUEST = 2
def secure_get_permission(permissions, user_type: str):
# Fixed: Use enum for clear mapping
type_map = {
'admin': UserType.ADMIN,
'user': UserType.USER,
'guest': UserType.GUEST
}
index = type_map.get(user_type, UserType.GUEST)
return permissions[index]
# Alternative: Use dictionary for explicit mapping
def secure_get_permission_dict(user_type: str):
permissions = {
'admin': ['read', 'write', 'delete', 'admin'],
'user': ['read', 'write'],
'guest': ['read']
}
return permissions.get(user_type, permissions['guest'])
CVE Examples
- CVE-2008-2121: Incorrect argument value in security function allowing bypass of access controls.
- CVE-2006-4243: Wrong flag value passed to authentication function, weakening security.
References
- MITRE Corporation. "CWE-687: Function Call With Incorrectly Specified Argument Value." https://cwe.mitre.org/data/definitions/687.html
- CERT C Coding Standard. "DCL00-C. Const-qualify immutable objects."