Skip to content

CWE-830: Inclusion of Functionality from Untrusted Control Sphere

Overview

Inclusion of functionality from untrusted control sphere occurs when an application loads code, libraries, modules, or resources from sources that can be manipulated by attackers, without proper verification of integrity or authenticity. This vulnerability manifests in several forms: dynamic code loading from user-controlled paths, including remote scripts without integrity checks (Subresource Integrity), loading plugins/extensions from untrusted sources, or using package managers with compromised repositories. Unlike CWE-829 (inclusion from untrusted zone), this CWE focuses on the control sphere concept where the attacker can influence which functionality gets loaded. Successful exploitation leads to arbitrary code execution, backdoor installation, or complete application compromise.

OWASP Classification

A08:2025 - Software and Data Integrity Failures

Risk

Critical: Direct code execution in application context, potential for complete system compromise, backdoor installation, data theft, and supply chain attacks. Especially dangerous in build systems, CI/CD pipelines, and production deployments.

Remediation Steps

Core principle: Load code and resources only from trusted, verified sources; implement integrity checks using cryptographic hashes; never allow user input to control code inclusion paths.

Use Subresource Integrity (SRI) for External Scripts

VULNERABLE - No integrity check:

<!-- CDN compromise allows arbitrary code injection -->
<script src="https://cdn.example.com/library.js"></script>
<link rel="stylesheet" href="https://cdn.example.com/styles.css">

SECURE - SRI with integrity hash:

<!-- Browser verifies hash before execution -->
<script 
    src="https://cdn.example.com/library.js"
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux1nXVqBz8K0mI2P9E8FHdYHGQ4eCo7"
    crossorigin="anonymous">
</script>

<link 
    rel="stylesheet" 
    href="https://cdn.example.com/styles.css"
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
    crossorigin="anonymous">

Generate SRI hash:

# Generate integrity hash
cat library.js | openssl dgst -sha384 -binary | openssl base64 -A

Prevent Dynamic Code Inclusion from User Input

VULNERABLE - User-controlled include:

// PHP - file inclusion from user input
$module = $_GET['module'];
include("/var/www/modules/" . $module . ".php");  // Path traversal + arbitrary include
# Python - dynamic import from user input
module_name = request.args.get('module')
module = __import__(module_name)  # Arbitrary module loading

SECURE - Whitelist allowed modules:

// PHP - whitelist approach
$allowedModules = ['dashboard', 'profile', 'settings'];
$module = $_GET['module'];

if (in_array($module, $allowedModules, true)) {
    include("/var/www/modules/" . $module . ".php");
} else {
    http_response_code(400);
    exit('Invalid module');
}
# Python - explicit mapping
ALLOWED_MODULES = {
    'dashboard': 'app.modules.dashboard',
    'profile': 'app.modules.profile',
    'settings': 'app.modules.settings'
}

module_key = request.args.get('module')
if module_key in ALLOWED_MODULES:
    module = importlib.import_module(ALLOWED_MODULES[module_key])
else:
    abort(400, 'Invalid module')

Verify Package Integrity in Dependency Management

VULNERABLE - No integrity check:

package.json
// version ranges allow updates
{
    "dependencies": {
        "express": "^4.18.0"  // ^ allows 4.x.x updates
    }
}

SECURE - Lock file with integrity hashes:

package-lock.json
// (generated by npm install)
{
    "dependencies": {
        "express": {
            "version": "4.18.2",
            "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
            "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ=="
        }
    }
}
# requirements.txt - pin exact versions
Flask==2.3.2 --hash=sha256:8a4cf32d904cf5621db9f0c9fbcd7efabf3003f22a04e4d0ce790c7137ec5264

# Or use poetry with lock file
# pyproject.toml + poetry.lock ensures integrity

Implement Content Security Policy (CSP)

Prevent loading scripts from untrusted origins:

<!-- SECURE - CSP header in meta tag -->
<meta http-equiv="Content-Security-Policy" 
      content="script-src 'self' https://trusted-cdn.example.com; 
               style-src 'self' https://trusted-cdn.example.com;
               object-src 'none';
               base-uri 'self';">
# Flask - set CSP header
@app.after_request
def set_csp(response):
    response.headers['Content-Security-Policy'] = (
        "default-src 'self'; "
        "script-src 'self' https://trusted-cdn.example.com; "
        "style-src 'self' https://trusted-cdn.example.com; "
        "img-src 'self' data: https:; "
        "font-src 'self' data:; "
        "connect-src 'self'; "
        "frame-ancestors 'none';"
    )
    return response

Secure Plugin/Extension Loading

VULNERABLE - Arbitrary plugin loading:

// Node.js - load plugin from user directory
const pluginPath = path.join('/var/plugins', req.body.pluginName);
const plugin = require(pluginPath);  // Arbitrary code execution
plugin.execute();

SECURE - Signed plugin verification:

const crypto = require('crypto');
const fs = require('fs');

async function loadPlugin(pluginName) {
    // Whitelist allowed plugins
    const allowedPlugins = ['auth', 'logging', 'cache'];
    if (!allowedPlugins.includes(pluginName)) {
        throw new Error('Plugin not allowed');
    }

    const pluginPath = path.join('/var/plugins', pluginName, 'index.js');
    const signaturePath = path.join('/var/plugins', pluginName, 'signature.sig');

    // Verify signature
    const pluginContent = fs.readFileSync(pluginPath);
    const signature = fs.readFileSync(signaturePath);
    const publicKey = fs.readFileSync('/etc/app/plugin-verification-key.pem');

    const verify = crypto.createVerify('SHA256');
    verify.update(pluginContent);

    if (!verify.verify(publicKey, signature)) {
        throw new Error('Plugin signature verification failed');
    }

    return require(pluginPath);
}

Use Trusted Package Repositories

Configure package managers to use trusted sources:

# pip - .pip/pip.conf
[global]
index-url = https://internal-pypi.company.com/simple
trusted-host = internal-pypi.company.com
.npmrc
# npm - .npmrc
registry=https://internal-npm.company.com/
always-auth=true
settings.xml
<!-- Maven -->
<mirrors>
    <mirror>
        <id>internal-repo</id>
        <url>https://nexus.company.com/repository/maven-public/</url>
        <mirrorOf>*</mirrorOf>
    </mirror>
</mirrors>

Implement Code Signing for Internal Modules

# Python - verify module signature before import
import hashlib
import hmac

EXPECTED_HASHES = {
    'internal_auth': 'a3c5f7e9b2d1...',
    'internal_billing': 'b4d6f8e0c3d2...'
}

def secure_import(module_name):
    if module_name not in EXPECTED_HASHES:
        raise ImportError(f'Module {module_name} not in whitelist')

    # Calculate hash of module file
    module_path = f'/var/app/modules/{module_name}.py'
    with open(module_path, 'rb') as f:
        actual_hash = hashlib.sha256(f.read()).hexdigest()

    if actual_hash != EXPECTED_HASHES[module_name]:
        raise ImportError(f'Module {module_name} integrity check failed')

    return importlib.import_module(f'modules.{module_name}')

Dynamic Scan Guidance

For guidance on remediating this CWE when detected by dynamic (DAST) scanners:

Additional Resources