Use of Incorrectly-Resolved Name or Reference

Description

Use of Incorrectly-Resolved Name or Reference occurs when a product uses a name or reference to access a resource, but the name/reference resolves to a resource that is outside of the intended control sphere. This happens when attackers can manipulate how names or references are resolved, causing the application to load or access resources controlled by the attacker instead of the intended legitimate resources. Common manifestations include DLL/library hijacking, DNS rebinding, symlink attacks, relative path injection, and package dependency confusion.

Risk

Incorrectly-resolved name vulnerabilities enable attackers to inject malicious code or redirect application behavior. CVE-2025-58362 in Hono JavaScript framework (CVSS 7.5) allows path confusion through malformed Request-URIs, bypassing proxy ACLs and gaining access to protected resources like /admin. Apache Camel vulnerabilities allow attackers to inject headers that alter component behavior. The tj-actions supply chain attack in March 2025 modified repository tags to point to malicious commits, exposing secrets. These vulnerabilities can lead to remote code execution, authentication bypass, and complete system compromise.

Solution

Always use absolute, fully-qualified names for resources. Validate that resolved resources are within expected locations. Implement allowlists for acceptable resource locations. Use package lock files and verify package integrity with checksums. Pin specific versions rather than floating tags. Implement proper symlink handling that validates canonical paths. Use secure DNS settings and implement DNS pinning where applicable. For web applications, use strict URL parsing and validation. Employ code signing and signature verification for loaded libraries.

Common Consequences

ImpactDetails
Access ControlScope: Authentication Bypass

Incorrectly resolved names can bypass access controls when path confusion occurs.
IntegrityScope: Code Execution

Loading attacker-controlled libraries or code enables arbitrary code execution.
ConfidentialityScope: Information Disclosure

Name resolution attacks can redirect requests to capture sensitive data.

Example Code + Solution Code

Vulnerable Code

// VULNERABLE: Relative path resolution allows escape
public class FileService {
    private static final String BASE_DIR = "/app/data/";

    public File getFile(String filename) {
        // Attacker provides "../../etc/passwd" - escapes base directory!
        return new File(BASE_DIR + filename);
    }
}

// VULNERABLE: Library loaded by name, not absolute path
public class PluginLoader {
    public void loadPlugin(String pluginName) {
        // Searches PATH/LD_LIBRARY_PATH - attacker can inject malicious library
        System.loadLibrary(pluginName);
    }
}
# VULNERABLE: Dynamic import with user-controlled name
import importlib

def load_handler(handler_name):
    # Attacker provides "os" and calls system commands!
    module = importlib.import_module(handler_name)
    return module.handle()

# VULNERABLE: Package dependency confusion
# requirements.txt:
# company-internal-lib==1.0.0
#
# If attacker publishes "company-internal-lib" on PyPI with higher version,
# pip may install the malicious package instead
// VULNERABLE: Path traversal in URL parsing
const express = require('express');
const path = require('path');

app.get('/files/:filename', (req, res) => {
    const filepath = path.join(__dirname, 'files', req.params.filename);
    // req.params.filename = "../../../etc/passwd" escapes!
    res.sendFile(filepath);
});

// VULNERABLE: DNS rebinding susceptible code
async function fetchData(url) {
    const response = await fetch(url);
    // Initial DNS resolves to attacker server which returns 200
    // TTL expires, second request resolves to internal server
    const data = await response.json();
    // Attacker's JS now has access to internal server response
}

Fixed Code

// SAFE: Validate resolved path is within allowed directory
import java.nio.file.Path;
import java.nio.file.Paths;

public class SecureFileService {
    private static final Path BASE_DIR = Paths.get("/app/data/").toRealPath();

    public File getFileSafe(String filename) throws IOException {
        // Resolve and normalize the path
        Path requestedPath = BASE_DIR.resolve(filename).normalize();

        // Verify the resolved path is still within BASE_DIR
        if (!requestedPath.startsWith(BASE_DIR)) {
            throw new SecurityException("Path traversal attempt detected");
        }

        // Verify the file exists and is a regular file
        File file = requestedPath.toFile();
        if (!file.exists() || !file.isFile()) {
            throw new FileNotFoundException("File not found");
        }

        return file;
    }
}

// SAFE: Load library with absolute path verification
public class SecurePluginLoader {
    private static final Path PLUGIN_DIR = Paths.get("/app/plugins/").toRealPath();
    private static final Set<String> ALLOWED_PLUGINS = Set.of("auth", "logging", "cache");

    public void loadPluginSafe(String pluginName) throws Exception {
        // Validate plugin name against allowlist
        if (!ALLOWED_PLUGINS.contains(pluginName)) {
            throw new SecurityException("Unknown plugin: " + pluginName);
        }

        // Build absolute path
        Path pluginPath = PLUGIN_DIR.resolve("lib" + pluginName + ".so").toRealPath();

        // Verify path is within plugin directory
        if (!pluginPath.startsWith(PLUGIN_DIR)) {
            throw new SecurityException("Invalid plugin path");
        }

        // Verify signature before loading
        if (!verifySignature(pluginPath)) {
            throw new SecurityException("Plugin signature verification failed");
        }

        System.load(pluginPath.toString());
    }
}
# SAFE: Dynamic import from allowlist only
import importlib

ALLOWED_HANDLERS = {
    'email': 'handlers.email_handler',
    'sms': 'handlers.sms_handler',
    'push': 'handlers.push_handler'
}

def load_handler_safe(handler_name):
    if handler_name not in ALLOWED_HANDLERS:
        raise ValueError(f"Unknown handler: {handler_name}")

    module_path = ALLOWED_HANDLERS[handler_name]
    module = importlib.import_module(module_path)
    return module.Handler()

# SAFE: Package dependency with hash verification
# requirements.txt:
# company-internal-lib==1.0.0 --hash=sha256:abc123...
#
# pip.conf:
# [global]
# index-url = https://private.example.com/simple/
# extra-index-url = https://pypi.org/simple/
#
# Use scoped names: @company/internal-lib

# SAFE: Path resolution with validation
from pathlib import Path

BASE_DIR = Path('/app/data').resolve()

def get_file_safe(filename):
    # Resolve the full path
    requested = (BASE_DIR / filename).resolve()

    # Verify it's within the base directory
    if not str(requested).startswith(str(BASE_DIR)):
        raise SecurityError("Path traversal detected")

    if not requested.exists() or not requested.is_file():
        raise FileNotFoundError()

    return requested
// SAFE: Strict path validation
const express = require('express');
const path = require('path');

const FILES_DIR = path.resolve(__dirname, 'files');

app.get('/files/:filename', (req, res) => {
    const filename = path.basename(req.params.filename);  // Strip path components
    const filepath = path.resolve(FILES_DIR, filename);

    // Verify resolved path is within allowed directory
    if (!filepath.startsWith(FILES_DIR + path.sep)) {
        return res.status(403).json({ error: 'Access denied' });
    }

    // Check file exists
    if (!fs.existsSync(filepath)) {
        return res.status(404).json({ error: 'Not found' });
    }

    res.sendFile(filepath);
});

// SAFE: DNS rebinding protection
const ALLOWED_HOSTS = new Set(['api.example.com', 'internal.example.com']);

async function fetchDataSafe(url) {
    const parsed = new URL(url);

    // Validate hostname against allowlist
    if (!ALLOWED_HOSTS.has(parsed.hostname)) {
        throw new Error('Hostname not allowed');
    }

    // Pin the IP address for the duration of the request
    const addresses = await dns.promises.resolve4(parsed.hostname);
    const pinnedIp = addresses[0];

    // Validate IP is not internal
    if (isPrivateIP(pinnedIp)) {
        throw new Error('Cannot access private IP');
    }

    const response = await fetch(url, {
        headers: { 'Host': parsed.hostname }
    });

    return response.json();
}

Exploited in the Wild

Hono Framework Path Confusion (Hono, 2025)

CVE-2025-58362 in Hono 4.8.0-4.9.5 allows attackers to craft malformed Request-URIs that cause incorrect path extraction, bypassing proxy ACLs like Nginx location blocks and accessing protected endpoints like /admin without authentication (CVSS 7.5).

tj-actions Supply Chain Attack (GitHub, 2025)

The tj-actions/changed-files repository tags v1-v45.0.7 were modified by threat actors on March 14-15, 2025 to point to a malicious commit containing code that exposed secrets from action logs.

Apache Camel Header Injection (Apache, 2025)

Vulnerabilities in Apache Camel allow attackers to inject Camel-specific headers through HTTP requests, altering component behaviors such as camel-bean and camel-exec components.


Tools to test/exploit

  • Burp Suite — test path traversal and URL parsing issues.

  • DLL Hijack Auditor — identify name resolution attacks.

  • Snyk — detect dependency confusion vulnerabilities.


CVE Examples


References

  1. MITRE. "CWE-706: Use of Incorrectly-Resolved Name or Reference." https://cwe.mitre.org/data/definitions/706.html

  2. OWASP. "Path Traversal." https://owasp.org/www-community/attacks/Path_Traversal