Use proxy-addr for parsing x-forwarded-for

Closes #683 by providing functionality to trust proxies other than
localhost.
This commit is contained in:
Calvin Montgomery 2017-06-27 23:37:18 -07:00
parent 9cffd7dde8
commit 76e0d1b7ec
7 changed files with 45 additions and 78 deletions

View file

@ -1,45 +1,29 @@
import net from 'net';
import proxyaddr from 'proxy-addr';
export default function initialize(app, webConfig) {
function isTrustedProxy(ip) {
return webConfig.getTrustedProxies().indexOf(ip) >= 0;
}
export function initialize(app, webConfig) {
const trustFn = proxyaddr.compile(webConfig.getTrustedProxies());
function getForwardedIP(req) {
const xForwardedFor = req.header('x-forwarded-for');
if (!xForwardedFor) {
return req.ip;
}
const ipList = xForwardedFor.split(',');
for (let i = 0; i < ipList.length; i++) {
const ip = ipList[i].trim();
if (net.isIP(ip)) {
return ip;
}
}
return req.ip;
}
function getForwardedProto(req) {
const xForwardedProto = req.header('x-forwarded-proto');
if (xForwardedProto && xForwardedProto.match(/^https?$/)) {
return xForwardedProto;
} else {
return req.protocol;
}
}
app.use((req, res, next) => {
if (isTrustedProxy(req.ip)) {
req.realIP = getForwardedIP(req);
req.realProtocol = getForwardedProto(req);
} else {
req.realIP = req.ip;
req.realProtocol = req.protocol;
}
next();
});
app.use(readProxyHeaders.bind(null, trustFn));
}
function getForwardedProto(req) {
const xForwardedProto = req.header('x-forwarded-proto');
if (xForwardedProto && xForwardedProto.match(/^https?$/)) {
return xForwardedProto;
} else {
return req.protocol;
}
}
function readProxyHeaders(trustFn, req, res, next) {
const forwardedIP = proxyaddr(req, trustFn);
if (forwardedIP !== req.ip) {
req.realIP = forwardedIP;
req.realProtocol = getForwardedProto(req);
} else {
req.realIP = req.ip;
req.realProtocol = req.protocol;
}
next();
}

View file

@ -138,7 +138,7 @@ module.exports = {
counters.add("http:request", 1);
next();
});
require('./middleware/x-forwarded-for')(app, webConfig);
require('./middleware/x-forwarded-for').initialize(app, webConfig);
app.use(bodyParser.urlencoded({
extended: false,
limit: '1kb' // No POST data should ever exceed this size under normal usage