Shitty hack for cross-domain login cookies

This commit is contained in:
calzoneman 2014-02-27 20:50:47 -06:00
parent ceab7dabf9
commit c44e70893b
4 changed files with 103 additions and 14 deletions

View file

@ -18,6 +18,10 @@ http:
# Specifies the root domain for cookies. If you have multiple domains
# e.g. a.example.com and b.example.com, the root domain is example.com
root-domain: 'localhost'
# Specify alternate domains/hosts that are allowed to set the login cookie
# Leave out the http://
alt-domains:
- '127.0.0.1'
# Use express-minify to minify CSS and Javascript
minify: false
# Static content cache (in seconds)

View file

@ -27,6 +27,7 @@ var defaults = {
port: 8080,
domain: "http://localhost",
"root-domain": "localhost",
"alt-domains": ["127.0.0.1"],
minify: false,
"cache-ttl": 0
},
@ -143,7 +144,7 @@ exports.load = function (file) {
function preprocessConfig(cfg) {
// Root domain should start with a . for cookies
var root = cfg.http["root-domain"];
root = "." + root.replace(/^\.*/, "");
root = root.replace(/^\.*/, "");
cfg.http["root-domain"] = root;
// Setup nodemailer

View file

@ -14,6 +14,7 @@ var Logger = require("../logger");
var $util = require("../utilities");
var db = require("../database");
var Config = require("../config");
var url = require("url");
/**
* Processes a login request. Sets a cookie upon successful authentication
@ -40,14 +41,16 @@ function handleLogin(req, res) {
loginError: err
});
} else {
cookieall(res, "auth", user.name + ":" + user.hash, {
var auth = user.name + ":" + user.hash;
res.cookie("auth", auth, {
domain: Config.get("http.root-domain"),
expires: new Date(Date.now() + 7*24*60*60*1000),
httpOnly: true
});
cookieall(res, "rank", user.global_rank, {
res.cookie("rank", user.global_rank, {
domain: "." + Config.get("http.root-domain"),
expires: new Date(Date.now() + 7*24*60*60*1000),
httpOnly: true
});
// Try to find an appropriate redirect
@ -60,6 +63,25 @@ function handleLogin(req, res) {
ref = "";
}
// Redirect to shim cookie layer if the host doesn't match
try {
var data = url.parse(ref);
if (data.host.indexOf(Config.get("http.root-domain")) === -1) {
var host = data.host.replace(/:\d+$/, "");
if (Config.get("http.alt-domains").indexOf(host) === -1) {
Logger.syslog.log("WARNING: Attempted login from non-approved "+
"domain " + host);
} else {
var dest = "/shimcookie?auth=" + encodeURIComponent(auth) +
"&rank=" + encodeURIComponent(user.global_rank) +
"&redirect=" + encodeURIComponent(ref);
res.redirect(data.protocol + "//" + data.host + dest);
return;
}
}
} catch (e) {
}
if (ref.match(/login|logout/)) {
ref = "";
}
@ -76,6 +98,63 @@ function handleLogin(req, res) {
});
}
function handleShimCookie(req, res) {
var auth = req.query.auth;
var rank = req.query.rank;
var redirect = req.query.redirect;
if (typeof auth !== "string" || typeof redirect !== "string" ||
typeof rank !== "string") {
res.send(400);
return;
}
res.cookie("auth", auth, {
expires: new Date(Date.now() + 7*24*60*60*1000),
httpOnly: true
});
res.cookie("rank", rank, {
expires: new Date(Date.now() + 7*24*60*60*1000),
});
if (redirect.match(/login|logout/)) {
redirect = "";
}
if (redirect) {
res.redirect(redirect);
} else {
sendJade(res, "login", {
loggedIn: true,
loginName: auth.split(":")[0]
});
}
}
function handleShimLogout(req, res) {
var redirect = req.query.redirect;
if (typeof redirect !== "string") {
res.send(400);
return;
}
res.clearCookie("auth");
res.clearCookie("rank");
res.clearCookie("auth", { domain: "." + Config.get("http.root-domain") });
res.clearCookie("rank", { domain: "." + Config.get("http.root-domain") });
if (redirect.match(/login|logout/)) {
redirect = "";
}
if (redirect) {
res.redirect(redirect);
} else {
sendJade(res, "logout", {});
}
}
/**
* Handles a GET request for /login
*/
@ -106,17 +185,28 @@ function handleLoginPage(req, res) {
*/
function handleLogout(req, res) {
res.clearCookie("auth");
res.clearCookie("auth", { domain: Config.get("http.root-domain") });
res.clearCookie("rank");
// Try to find an appropriate redirect
var ref = req.header("referrer");
if (!ref) {
ref = req.body.redirect;
ref = req.query.redirect;
}
if (typeof ref !== "string") {
ref = "";
}
var host = req.host;
if (host.indexOf(Config.get("http.root-domain")) !== -1) {
res.clearCookie("auth", { domain: Config.get("http.root-domain") });
res.clearCookie("rank", { domain: Config.get("http.root-domain") });
} else {
var dest = Config.get("http.full-address") + "/shimlogout?redirect=" +
encodeURIComponent(ref);
res.redirect(dest);
return;
}
if (ref.match(/login|logout/)) {
ref = "";
}
@ -227,5 +317,7 @@ module.exports = {
app.get("/logout", handleLogout);
app.get("/register", handleRegisterPage);
app.post("/register", handleRegister);
app.get("/shimcookie", handleShimCookie);
app.get("/shimlogout", handleShimLogout);
}
};

View file

@ -62,12 +62,6 @@ function logRequest(req, status) {
].join(" "));
}
function cookieall(res, name, val, opts) {
res.cookie(name, val, opts);
opts.domain = Config.get("http.root-domain");
res.cookie(name, val, opts);
}
/**
* Redirects a request to HTTPS if the server supports it
*/
@ -296,6 +290,4 @@ module.exports = {
redirectHttps: redirectHttps,
redirectHttp: redirectHttp,
cookieall: cookieall
};