CWE-441, Unintended Proxy or Intermediary, also known as the Confused Deputy, is a weakness in how a product forwards things. It receives a request, message or directive from an upstream component, then passes it to an external actor without preserving who the original sender was. The product ends up looking like the source of the request.
It matters for anything that relays traffic or commands on someone's behalf: FTP servers, RPC services, web servers that fetch URLs, API gateways, and even hardware blocks inside a system on a chip.
How it happens
The core idea is that the deputy has more access than the caller. If an attacker cannot reach a target directly, but your product can, then a request sent to your product and forwarded on arrives with your product's identity and network position.
MITRE is careful to say that proxying is often legitimate. It becomes a vulnerability when three things line up:
- The product runs with different privileges, or on a different system, than the upstream component.
- The attacker is prevented from making the request directly to the target.
- The attacker can craft a request the proxy never meant to forward for them, such as one aimed at an unexpected hostname, port, IP address or service, or one that carries disallowed commands to an allowed service.
The observed examples show the same pattern across decades of software:
- CVE-1999-0017: the FTP bounce attack. The protocol design lets an attacker change the PORT command so the FTP server connects to other machines.
- CVE-2005-0315: an FTP server did not check that the IP address in a PORT command matched the user's session, allowing port scanning by proxy.
- CVE-1999-0168: the RPC portmapper could redirect service requests from an attacker to another entity, which believed the requests came from the portmapper.
- CVE-2002-1484: a web server let attackers request a URL from another server, including other ports, which allowed proxied scanning.
MITRE also describes a system on a chip where a DMA controller is allowed to reach protected registers for functional reasons. Low-privilege code cannot read those registers directly, but it can configure the DMA controller to do it.
What an attacker gains
From the record: they can gain privileges or assume an identity, bypass access controls such as firewalls, hide their activity because requests do not come from their own system, and in some cases execute unauthorized code or commands. Non-repudiation is also lost, since the logs name the deputy and not the real sender.
How to find it
MITRE notes that automated static analysis (SAST) can find some instances by modeling data flow from untrusted input to a forwarding action. You can also review by hand:
- List every place your code makes an outbound request or issues a command based on caller input.
- For each, ask what the caller controls: host, port, path, headers, command.
- Check whether the original identity travels with the forwarded request.
- Try requests that point at internal addresses, other ports and other services.
How to fix it
MITRE lists two architecture and design mitigations:
- Enforce strong mutual authentication between the two parties.
- When acting as an intermediary or proxy, do not drop the identity of the initiator. Keep it immutable and forward it all the way to the target.
A small sketch of the second point in Python. The vulnerable version forwards whatever URL the caller supplies, using the service's own network access:
# Vulnerable: caller picks the target, service supplies the access
def fetch(url):
return requests.get(url).text
A safer version restricts targets to a fixed set and passes the caller's identity along:
ALLOWED_HOSTS = {"reports.internal.example"}
def fetch(url, caller_id):
host = urlparse(url).hostname
if host not in ALLOWED_HOSTS:
raise PermissionError("target not allowed")
return requests.get(url, headers={"X-Original-Caller": caller_id}).text
The allowlist limits where the deputy can be steered. The forwarded identity lets the target apply its own access decisions and keeps logs honest.
Try it yourself
If your service accepts URLs or commands that it relays, this demo shows how an API scan surfaces risky endpoints.
Click through it at your own pace, or open it full screen.
Quick check
Why is the proxy "confused"?
It holds its own authority and cannot tell whether a request is being made for its owner or for an attacker. It uses its access on behalf of whoever asked.
Is every proxy a CWE-441 problem?
No. Per MITRE, forwarding is often legitimate. It becomes a weakness when the product has more access than the caller, the caller cannot reach the target directly, and the caller can craft a request the proxy was never meant to forward.