Use of Prohibited Code
Description
Use of Prohibited Code occurs when a product uses a function, library, or third-party component that has been explicitly prohibited, whether by the developer or the customer. Organizations may prohibit certain code for various reasons: known security vulnerabilities, difficulty implementing securely, export control or licensing constraints, obsolete or deprecated status, or scheduled removal. Maintaining and enforcing lists of banned functions helps reduce vulnerability risk, though this practice requires ongoing maintenance and awareness.
Risk
Using prohibited code has significant security implications. Known-vulnerable functions may be exploited. Banned functions often have safer alternatives available. Compliance requirements may mandate avoiding certain code. Deprecated functions may be removed in future versions. Export control violations may have legal consequences. Audit findings may result from prohibited code usage. Security certifications may be jeopardized. Legacy code may have unpatched vulnerabilities.
Solution
Maintain a list of prohibited functions and libraries. Use static analysis tools to detect prohibited code. Configure compiler warnings for deprecated functions. Implement pre-commit hooks to block prohibited code. Train developers on secure alternatives. Document why each function is prohibited. Regularly update the prohibited list. Use approved libraries with active security maintenance. Consider using safe wrapper functions. Establish a process for exceptions with security review.
Common Consequences
| Impact | Details |
|---|---|
| Other | Scope: Other Reduce Maintainability - Using prohibited code makes maintenance harder and may cause issues when code is eventually removed or breaks. |
| Confidentiality/Integrity/Availability | Scope: All Security Vulnerabilities - Prohibited functions are often banned due to known security issues like buffer overflows. |
Example Code
Vulnerable Code
// Vulnerable: Using banned C functions
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// BANNED: gets() - no buffer size limit, always unsafe
void read_input() {
char buffer[100];
printf("Enter name: ");
gets(buffer); // PROHIBITED: Use fgets() instead
printf("Hello, %s\n", buffer);
}
// BANNED: strcpy() - no bounds checking
void copy_string(char *dest, const char *src) {
strcpy(dest, src); // PROHIBITED: Use strncpy() or strlcpy()
}
// BANNED: strcat() - no bounds checking
void append_string(char *dest, const char *src) {
strcat(dest, src); // PROHIBITED: Use strncat() or strlcat()
}
// BANNED: sprintf() - no buffer size limit
void format_message(char *buffer, const char *name, int id) {
sprintf(buffer, "User: %s, ID: %d", name, id); // PROHIBITED: Use snprintf()
}
// BANNED: scanf() with %s - no length limit
void read_username() {
char username[50];
scanf("%s", username); // PROHIBITED: Use fgets() or scanf with width specifier
}
// BANNED: atoi() - no error checking
int parse_number(const char *str) {
return atoi(str); // PROHIBITED: Use strtol() with error checking
}
// BANNED: rand() for security purposes
void generate_token(char *token, int length) {
for (int i = 0; i < length; i++) {
token[i] = 'A' + (rand() % 26); // PROHIBITED: Not cryptographically secure
}
}
// Vulnerable: Using deprecated/unsafe Windows APIs
#include <windows.h>
// BANNED: lstrcpy() - no bounds checking
void copy_win_string(LPTSTR dest, LPCTSTR src) {
lstrcpy(dest, src); // PROHIBITED: Use StringCchCopy()
}
// BANNED: wsprintf() - no buffer limit
void format_win_message(LPWSTR buffer, LPCWSTR format, ...) {
va_list args;
va_start(args, format);
wvsprintf(buffer, format, args); // PROHIBITED: Use StringCchPrintf()
va_end(args);
}
// BANNED: GetVersion() - deprecated
void check_version() {
DWORD version = GetVersion(); // PROHIBITED: Use VerifyVersionInfo() or
// Version Helper APIs
}
# Vulnerable: Using prohibited Python functions/patterns
import pickle
import yaml
import os
# BANNED: pickle.loads() on untrusted data - arbitrary code execution
def deserialize_data(data):
return pickle.loads(data) # PROHIBITED: Use JSON or safe alternatives
# BANNED: yaml.load() without Loader - arbitrary code execution
def load_yaml_config(yaml_string):
return yaml.load(yaml_string) # PROHIBITED: Use yaml.safe_load()
# BANNED: eval() - arbitrary code execution
def calculate(expression):
return eval(expression) # PROHIBITED: Use ast.literal_eval() or safe parser
# BANNED: exec() with user input
def run_user_code(code):
exec(code) # PROHIBITED: Never execute untrusted code
# BANNED: input() in Python 2 - executes code (Python 2 only)
# name = input("Name: ") # PROHIBITED in Py2: Use raw_input()
# BANNED: shell=True with untrusted input
def run_command(user_command):
os.system(user_command) # PROHIBITED: Use subprocess with shell=False
// Vulnerable: Using prohibited Java methods
import java.util.Random;
import java.security.MessageDigest;
public class ProhibitedExamples {
// BANNED: Math.random() for security purposes
public String generateToken() {
StringBuilder token = new StringBuilder();
for (int i = 0; i < 32; i++) {
token.append((char) ('A' + Math.random() * 26));
// PROHIBITED: Use SecureRandom
}
return token.toString();
}
// BANNED: MD5 for password hashing
public String hashPassword(String password) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
// PROHIBITED: MD5 is cryptographically broken
// Use bcrypt, scrypt, or Argon2
byte[] hash = md.digest(password.getBytes());
return bytesToHex(hash);
}
// BANNED: SHA-1 for security purposes
public String sha1Hash(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-1");
// PROHIBITED: SHA-1 has known weaknesses
// Use SHA-256 or better
return bytesToHex(md.digest(data.getBytes()));
}
// BANNED: Runtime.exec() with string command
public void runCommand(String command) throws Exception {
Runtime.getRuntime().exec(command);
// PROHIBITED: Command injection risk
// Use ProcessBuilder with array of arguments
}
// BANNED: Using java.util.Random for security
private Random random = new Random();
public int generateSecurityCode() {
return random.nextInt(1000000);
// PROHIBITED: Use SecureRandom for security-sensitive values
}
}
Fixed Code
// Fixed: Using safe alternatives to banned functions
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
// Using arc4random or /dev/urandom for cryptographic random
#ifdef __linux__
#include <sys/random.h>
#endif
// Safe: fgets() instead of gets()
void read_input() {
char buffer[100];
printf("Enter name: ");
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
// Remove newline if present
buffer[strcspn(buffer, "\n")] = '\0';
printf("Hello, %s\n", buffer);
}
}
// Safe: strncpy() with explicit null termination
void copy_string(char *dest, size_t dest_size, const char *src) {
if (dest_size == 0) return;
strncpy(dest, src, dest_size - 1);
dest[dest_size - 1] = '\0'; // Ensure null termination
}
// Safe: strncat() with size calculation
void append_string(char *dest, size_t dest_size, const char *src) {
size_t dest_len = strlen(dest);
if (dest_len >= dest_size - 1) return;
strncat(dest, src, dest_size - dest_len - 1);
}
// Safe: snprintf() with buffer size
void format_message(char *buffer, size_t buffer_size, const char *name, int id) {
snprintf(buffer, buffer_size, "User: %s, ID: %d", name, id);
}
// Safe: fgets() instead of scanf %s
void read_username(char *username, size_t size) {
if (fgets(username, size, stdin) != NULL) {
username[strcspn(username, "\n")] = '\0';
}
}
// Safe: strtol() with error checking
int parse_number(const char *str, int *error) {
char *endptr;
errno = 0;
long value = strtol(str, &endptr, 10);
if (errno != 0 || endptr == str || *endptr != '\0') {
*error = 1;
return 0;
}
if (value > INT_MAX || value < INT_MIN) {
*error = 1;
return 0;
}
*error = 0;
return (int)value;
}
// Safe: Cryptographically secure random
void generate_token(char *token, int length) {
#ifdef __linux__
unsigned char random_bytes[length];
getrandom(random_bytes, length, 0);
for (int i = 0; i < length; i++) {
token[i] = 'A' + (random_bytes[i] % 26);
}
#else
// Use arc4random on BSD/macOS
for (int i = 0; i < length; i++) {
token[i] = 'A' + (arc4random_uniform(26));
}
#endif
token[length] = '\0';
}
# Fixed: Using safe alternatives in Python
import json
import yaml
import subprocess
import secrets
import ast
from pathlib import Path
# Safe: JSON instead of pickle for untrusted data
def deserialize_data(json_string):
return json.loads(json_string)
# Safe: yaml.safe_load() for YAML
def load_yaml_config(yaml_string):
return yaml.safe_load(yaml_string)
# Safe: ast.literal_eval() for safe literal parsing
def parse_literal(expression):
"""Safely evaluate a literal expression."""
try:
return ast.literal_eval(expression)
except (ValueError, SyntaxError) as e:
raise ValueError(f"Invalid expression: {e}")
# Safe: Use proper parser for calculations
def calculate(expression):
"""Use a safe expression parser (example using a library)."""
# Use a safe math expression parser like 'numexpr' or 'simpleeval'
# Or implement your own with whitelist of operations
import simpleeval
return simpleeval.simple_eval(expression)
# Safe: subprocess with shell=False and argument list
def run_command(command, args):
"""Run command safely without shell interpretation."""
result = subprocess.run(
[command] + args,
shell=False, # Never use shell=True with user input
capture_output=True,
text=True,
check=True
)
return result.stdout
# Safe: secrets module for cryptographic random
def generate_token(length=32):
"""Generate cryptographically secure token."""
return secrets.token_urlsafe(length)
def generate_numeric_code(digits=6):
"""Generate secure numeric code."""
return ''.join(str(secrets.randbelow(10)) for _ in range(digits))
// Fixed: Using safe alternatives in Java
import java.security.SecureRandom;
import java.security.MessageDigest;
import java.util.Base64;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
public class SafeExamples {
private static final SecureRandom secureRandom = new SecureRandom();
// Safe: SecureRandom for security-sensitive values
public String generateToken() {
byte[] bytes = new byte[32];
secureRandom.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
// Safe: bcrypt/PBKDF2 for password hashing
public String hashPassword(String password) throws Exception {
byte[] salt = new byte[16];
secureRandom.nextBytes(salt);
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
salt,
100000, // iterations
256 // key length
);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] hash = factory.generateSecret(spec).getEncoded();
// Combine salt and hash for storage
byte[] combined = new byte[salt.length + hash.length];
System.arraycopy(salt, 0, combined, 0, salt.length);
System.arraycopy(hash, 0, combined, salt.length, hash.length);
return Base64.getEncoder().encodeToString(combined);
}
// Safe: SHA-256 for integrity checking
public String sha256Hash(String data) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(data.getBytes("UTF-8"));
return bytesToHex(hash);
}
// Safe: ProcessBuilder with explicit arguments
public String runCommand(String[] command) throws Exception {
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process = pb.start();
String output = new String(process.getInputStream().readAllBytes());
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new RuntimeException("Command failed: " + exitCode);
}
return output;
}
// Safe: SecureRandom for security codes
public int generateSecurityCode() {
return secureRandom.nextInt(1000000);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
CVE Examples
Numerous CVEs result from using prohibited functions. Examples include:
- Buffer overflow CVEs from gets(), strcpy(), sprintf() usage
- Arbitrary code execution from pickle.loads(), eval(), yaml.load()
- Weak cryptography CVEs from MD5/SHA-1 usage
Related CWEs
- CWE-710: Improper Adherence to Coding Standards (parent)
- CWE-242: Use of Inherently Dangerous Function (child)
- CWE-676: Use of Potentially Dangerous Function (child)
- CWE-327: Use of a Broken or Risky Cryptographic Algorithm (related)
References
- MITRE Corporation. "CWE-1177: Use of Prohibited Code." https://cwe.mitre.org/data/definitions/1177.html
- Microsoft SDL Banned Function List
- CERT C Coding Standard - Banned Functions
- OWASP - Unsafe Functions