Skip to content

[Bug][Node.js]: SSRF protection bypass via policy mutation after agent creation #24

Description

@nedlir

Bug Behavior

Bug: AntiSSRFPolicy can be mutated after agent creation (Missing parity with .NET _editLock)

Bug Description

The Node.js implementation of AntiSSRF allows you to modify the policy configurations after an HTTP/HTTPS agent has already been initialized from it. This means any module or dependency with a reference to the policy object can dynamically call methods like addAllowedAddresses() or flip denyAllUnspecifiedIPs at runtime, completely changing the validation rules under the hood of an active agent.

The .NET version explicitly prevents this, but the Node.js port is missing the lock mechanism entirely.

Code Location

In AntiSSRFPolicy.ts, methods like getHttpAgent() and getHttpsAgent() simply pass this by reference to the agents without locking down the settings.

Because of this, all of the following mutations remain exposed and usable on a live policy:

  • addAllowedAddresses() / addDeniedAddresses()
  • addRequiredHeaders() / addDeniedHeaders()
  • set denyAllUnspecifiedIPs
  • set allowPlainTextHttp
  1. A request to an internal target container is correctly blocked by the agent (IP address disallowed by policy).
  2. addAllowedAddresses(['0.0.0.0/0']) is called on the policy object.
  3. The exact same agent instance is used to make the request again.
  4. Bypass: The request passes right through, and the target container logs an incoming 200 hit from the app.

Expected Behavior

The policy should freeze as soon as it's used to build an agent. Trying to mutate it after the fact should throw an error, matching the .NET implementation.

Proposed Fix

We should mirror the _editLock approach used in the .NET side (AntiSSRFPolicy.cs). Add a private boolean flag to the TS policy class, trip it to true when an agent is requested, and check it in the setters/mutators:

private _editLock = false;

public getHttpAgent(options?: HttpAgentOptions) {
    this._editLock = true;
    return new AntiSSRFHttpAgent(this, options);
}

// In your setters and add* methods:
if (this._editLock) {
    throw new AntiSSRFError("Cannot modify policy after agent creation");
}

Expected Behavior

No response

Steps To Reproduce

No response

Version

1.0.0

Operating System

Kali 2025.4

Node.js Version

20.0.0

Additional Context

No response

Verification

  • I have searched existing issues and confirmed this bug has not already been reported

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingnodejsRelated to the Node.js version of the AntiSSRF library

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions