Move x-forwarded-for middleware

This commit is contained in:
calzoneman 2015-10-27 23:54:32 -07:00
parent 13d4a49976
commit c2726898e5
6 changed files with 53 additions and 40 deletions

View file

@ -1,5 +1,10 @@
import clone from 'clone';
const DEFAULT_TRUSTED_PROXIES = [
'127.0.0.1',
'::1'
];
export default class WebConfiguration {
constructor(config) {
this.config = config;
@ -8,6 +13,10 @@ export default class WebConfiguration {
getEmailContacts() {
return clone(this.config.contacts);
}
getTrustedProxies() {
return DEFAULT_TRUSTED_PROXIES.slice();
}
}
WebConfiguration.fromOldConfig = function (oldConfig) {

View file

@ -92,7 +92,7 @@ function handleChangePassword(req, res) {
return;
}
Logger.eventlog.log("[account] " + webserver.ipForRequest(req) +
Logger.eventlog.log("[account] " + req.realIP +
" changed password for " + name);
db.users.getUser(name, function (err, user) {
@ -172,7 +172,7 @@ function handleChangeEmail(req, res) {
});
return;
}
Logger.eventlog.log("[account] " + webserver.ipForRequest(req) +
Logger.eventlog.log("[account] " + req.realIP +
" changed email for " + name +
" to " + email);
sendJade(res, "account-edit", {
@ -269,7 +269,7 @@ function handleNewChannel(req, res) {
db.channels.register(name, req.user.name, function (err, channel) {
if (!err) {
Logger.eventlog.log("[channel] " + req.user.name + "@" +
webserver.ipForRequest(req) +
req.realIP +
" registered channel " + name);
var sv = Server.getServer();
if (sv.isChannelLoaded(name)) {
@ -336,7 +336,7 @@ function handleDeleteChannel(req, res) {
db.channels.drop(name, function (err) {
if (!err) {
Logger.eventlog.log("[channel] " + req.user.name + "@" +
webserver.ipForRequest(req) + " deleted channel " +
req.realIP + " deleted channel " +
name);
}
var sv = Server.getServer();
@ -498,7 +498,7 @@ function handlePasswordReset(req, res) {
var hash = $util.sha1($util.randomSalt(64));
// 24-hour expiration
var expire = Date.now() + 86400000;
var ip = webserver.ipForRequest(req);
var ip = req.realIP;
db.addPasswordReset({
ip: ip,
@ -575,7 +575,7 @@ function handlePasswordRecover(req, res) {
return;
}
var ip = webserver.ipForRequest(req);
var ip = req.realIP;
db.lookupPasswordReset(hash, function (err, row) {
if (err) {

View file

@ -15,7 +15,7 @@ function checkAdmin(cb) {
if (req.user.global_rank < 255) {
res.send(403);
Logger.eventlog.log("[acp] Attempted GET "+req.path+" from non-admin " +
user.name + "@" + webserver.ipForRequest(req));
user.name + "@" + req.realIP);
return;
}

View file

@ -54,7 +54,7 @@ function handleLogin(req, res) {
if (err) {
if (err === "Invalid username/password combination") {
Logger.eventlog.log("[loginfail] Login failed (bad password): " + name
+ "@" + webserver.ipForRequest(req));
+ "@" + req.realIP);
}
sendJade(res, "login", {
loggedIn: false,
@ -173,7 +173,7 @@ function handleRegister(req, res) {
if (typeof email !== "string") {
email = "";
}
var ip = webserver.ipForRequest(req);
var ip = req.realIP;
if (typeof name !== "string" || typeof password !== "string") {
res.sendStatus(400);

View file

@ -0,0 +1,32 @@
import net from 'net';
export default function initialize(app, webConfig) {
function isTrustedProxy(ip) {
return webConfig.getTrustedProxies().indexOf(ip) >= 0;
}
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;
}
app.use((req, res, next) => {
if (isTrustedProxy(req.ip)) {
req.realIP = getForwardedIP(req);
}
next();
});
}

View file

@ -20,30 +20,7 @@ import * as HTTPStatus from './httpstatus';
import { CSRFError, HTTPError } from '../errors';
const LOG_FORMAT = ':real-address - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
morgan.token('real-address', function (req) { return req._ip; });
/**
* Extracts an IP address from a request. Uses X-Forwarded-For if the IP is localhost
*/
function ipForRequest(req) {
var ip = req.ip;
if (ip === "127.0.0.1" || ip === "::1") {
var xforward = req.header("x-forwarded-for");
if (typeof xforward !== "string") {
xforward = [];
} else {
xforward = xforward.split(",");
}
for (var i = 0; i < xforward.length; i++) {
if (net.isIP(xforward[i])) {
return xforward[i];
}
}
return ip;
}
return ip;
}
morgan.token('real-address', function (req) { return req.realIP; });
/**
* Redirects a request to HTTPS if the server supports it
@ -87,7 +64,7 @@ function handleSocketConfig(req, res) {
var sioconfig = Config.get("sioconfig");
var iourl;
var ip = ipForRequest(req);
var ip = req.realIP;
var ipv6 = false;
if (net.isIPv6(ip)) {
@ -115,10 +92,7 @@ module.exports = {
* Initializes webserver callbacks
*/
init: function (app, webConfig, ioConfig, clusterClient, channelIndex) {
app.use(function (req, res, next) {
req._ip = ipForRequest(req);
next();
});
require("./middleware/x-forwarded-for")(app, webConfig);
app.use(bodyParser.urlencoded({
extended: false,
limit: '1kb' // No POST data should ever exceed this size under normal usage
@ -226,8 +200,6 @@ module.exports = {
});
},
ipForRequest: ipForRequest,
redirectHttps: redirectHttps,
redirectHttp: redirectHttp