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 # 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 # e.g. a.example.com and b.example.com, the root domain is example.com
root-domain: 'localhost' 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 # Use express-minify to minify CSS and Javascript
minify: false minify: false
# Static content cache (in seconds) # Static content cache (in seconds)

View file

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

View file

@ -14,6 +14,7 @@ var Logger = require("../logger");
var $util = require("../utilities"); var $util = require("../utilities");
var db = require("../database"); var db = require("../database");
var Config = require("../config"); var Config = require("../config");
var url = require("url");
/** /**
* Processes a login request. Sets a cookie upon successful authentication * Processes a login request. Sets a cookie upon successful authentication
@ -40,14 +41,16 @@ function handleLogin(req, res) {
loginError: err loginError: err
}); });
} else { } 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), expires: new Date(Date.now() + 7*24*60*60*1000),
httpOnly: true 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), expires: new Date(Date.now() + 7*24*60*60*1000),
httpOnly: true
}); });
// Try to find an appropriate redirect // Try to find an appropriate redirect
@ -60,6 +63,25 @@ function handleLogin(req, res) {
ref = ""; 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/)) { if (ref.match(/login|logout/)) {
ref = ""; 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 * Handles a GET request for /login
*/ */
@ -106,17 +185,28 @@ function handleLoginPage(req, res) {
*/ */
function handleLogout(req, res) { function handleLogout(req, res) {
res.clearCookie("auth"); res.clearCookie("auth");
res.clearCookie("auth", { domain: Config.get("http.root-domain") }); res.clearCookie("rank");
// Try to find an appropriate redirect // Try to find an appropriate redirect
var ref = req.header("referrer"); var ref = req.header("referrer");
if (!ref) { if (!ref) {
ref = req.body.redirect; ref = req.query.redirect;
} }
if (typeof ref !== "string") { if (typeof ref !== "string") {
ref = ""; 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/)) { if (ref.match(/login|logout/)) {
ref = ""; ref = "";
} }
@ -227,5 +317,7 @@ module.exports = {
app.get("/logout", handleLogout); app.get("/logout", handleLogout);
app.get("/register", handleRegisterPage); app.get("/register", handleRegisterPage);
app.post("/register", handleRegister); app.post("/register", handleRegister);
app.get("/shimcookie", handleShimCookie);
app.get("/shimlogout", handleShimLogout);
} }
}; };

View file

@ -62,12 +62,6 @@ function logRequest(req, status) {
].join(" ")); ].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 * Redirects a request to HTTPS if the server supports it
*/ */
@ -296,6 +290,4 @@ module.exports = {
redirectHttps: redirectHttps, redirectHttps: redirectHttps,
redirectHttp: redirectHttp, redirectHttp: redirectHttp,
cookieall: cookieall
}; };