Package Exports
- request-filtering-agent
- request-filtering-agent/lib/request-filtering-agent.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (request-filtering-agent) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
request-filtering-agent 
An http(s).Agent class block the request to Private IP addresses and Reserved IP addresses.
It helps to prevent server-side request forgery (SSRF) attack.
This library depended on ipaddr.js definitions. This library block the request to these IP addresses by default.
So, This library block the request to non-unicast
IP addresses.
⚠️ Node.js's built-in fetch
does not support http.Agent
.
Support http.Agent
libraries
This library provides Node.js's http.Agent implementation. http.Agent is supported by popular library.
- Node.js's built-in
http
andhttps
- node-fetch
- Request
- node-http-proxy
- axios
- got
request-filtering-agent
works with these libraries!
Install
Install with npm:
npm install request-filtering-agent
Usage
useAgent(url, options)
return an agent for the url.
The agent blocks the request to Private network and Reserved IP addresses by default.
const fetch = require("node-fetch");
const { useAgent } = require("request-filtering-agent");
const url = 'http://127.0.0.1:8080/';
fetch(url, {
// use http or https agent for url
agent: useAgent(url, { stopPortScanningByUrlRedirection: true })
}).catch(err => {
console.err(err); // DNS lookup 127.0.0.1(family:4, host:127.0.0.1.nip.io) is not allowed. Because, It is private IP address.
});
request-filtering-agent
support loopback domain like nip.io.
This library detects the IP address that is dns lookup-ed.
$ dig 127.0.0.1.nip.io
;127.0.0.1.nip.io. IN A
;; ANSWER SECTION:
127.0.0.1.nip.io. 300 IN A 127.0.0.1
Example code:
const fetch = require("node-fetch");
const { useAgent } = require("request-filtering-agent");
const url = 'http://127.0.0.1.nip.io:8080/';
fetch(url, {
agent: useAgent(url)
}).catch(err => {
console.err(err); // DNS lookup 127.0.0.1(family:4, host:127.0.0.1.nip.io) is not allowed. Because, It is private IP address.
});
It will prevent DNS rebinding
API
export interface RequestFilteringAgentOptions {
// Allow to connect private IP address
// This includes Private IP addresses and Reserved IP addresses.
// https://en.wikipedia.org/wiki/Private_network
// https://en.wikipedia.org/wiki/Reserved_IP_addresses
// Example, http://127.0.0.1/, http://localhost/, https://169.254.169.254/
// Default: false
allowPrivateIPAddress?: boolean;
// Allow to connect meta address 0.0.0.0
// 0.0.0.0 (IPv4) and :: (IPv6) a meta address that routing another address
// https://en.wikipedia.org/wiki/Reserved_IP_addresses
// https://tools.ietf.org/html/rfc6890
// Default: false
allowMetaIPAddress?: boolean;
// Allow address list
// This values are preferred than denyAddressList
// Default: []
allowIPAddressList?: string[];
// Deny address list
// Default: []
denyIPAddressList?: string[]
// prevent url redirection attack
// connection not made to private IP adresses where the port is closed
// Default: false
stopPortScanningByUrlRedirection?: boolean;
}
/**
* Apply request filter to http(s).Agent instance
*/
export declare function applyRequestFilter<T extends http.Agent | https.Agent>(agent: T, options?: RequestFilteringAgentOptions): T;
/**
* A subclass of http.Agent with request filtering
*/
export declare class RequestFilteringHttpAgent extends http.Agent {
constructor(options?: http.AgentOptions & RequestFilteringAgentOptions);
}
/**
* A subclass of https.Agent with request filtering
*/
export declare class RequestFilteringHttpsAgent extends https.Agent {
constructor(options?: https.AgentOptions & RequestFilteringAgentOptions);
}
export declare const globalHttpAgent: RequestFilteringHttpAgent;
export declare const globalHttpsAgent: RequestFilteringHttpsAgent;
/**
* Get an agent for the url
* return http or https agent
* @param url
*/
export declare const useAgent: (url: string, options?: https.AgentOptions & RequestFilteringAgentOptions) => RequestFilteringHttpAgent | RequestFilteringHttpsAgent;
Example: Create an Agent with options
An agent that allow requesting 127.0.0.1
, but it disallows other Private IP.
const fetch = require("node-fetch");
const { RequestFilteringHttpAgent } = require("request-filtering-agent");
// Create http agent that allow 127.0.0.1, but it disallow other private ip
const agent = new RequestFilteringHttpAgent({
allowIPAddressList: ["127.0.0.1"], // it is preferred than allowPrivateIPAddress option
allowPrivateIPAddress: false, // Default: false
});
// 127.0.0.1 is private ip address, but it is allowed
const url = 'http://127.0.0.1:8080/';
fetch(url, {
agent: agent
}).then(res => {
console.log(res); // OK
});
Example: Apply request filtering to excising http.Agent
You can apply request filtering to http.Agent
or https.Agent
using applyRequestFilter
method.
const http = require("http")
const fetch = require("node-fetch");
const { applyRequestFilter } = require("request-filtering-agent");
// Create http agent with keepAlive option
const agent = new http.Agent({
keepAlive: true,
});
// Apply request filtering to http.Agent
const agentWithFiltering = applyRequestFilter(agent, {
allowPrivateIPAddress: false // Default: false
});
// 169.254.169.254 is private ip address aka. link-local addresses
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html
// https://serverfault.com/questions/427018/what-is-this-ip-address-169-254-169-254
const url = 'http://169.254.169.254/';
fetch(url, {
agent: agentWithFiltering
}).catch(error => {
console.error(error); // Dis-allowed
});
Related
- welefen/ssrf-agent: make http(s) request to prevent SSRF
- It provides only high level wrapper
- It only handles Private IP address that is definition in node-ip
- Missing Meta IP Address like
0.0.0.0
- Missing Meta IP Address like
Changelog
See Releases page.
Running tests
Install devDependencies and Run yarn test
:
yarn test
📝 This testing require IPv6 supports:
- Travis CI: NG
- GitHub Actions: OK
Contributing
Pull requests and stars are always welcome.
For bugs and feature requests, please create an issue.
For security issue, please see SECURITY.md
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
Author
License
MIT © azu