cookies: Use js-cookie to read and write cookies

Rather than reinvent the wheel, use a well-tested library to parse and
write cookies. This should also help prevent XSS vulnerabilities
because the library handles special characters such as semicolon.
This commit is contained in:
Richard Hansen 2020-10-02 18:43:12 -04:00 committed by John McLear
parent d55edebddd
commit 3ab0f30ac8
9 changed files with 54 additions and 96 deletions

View file

@ -30,6 +30,7 @@ require('./jquery');
require('./farbtastic');
require('./excanvas');
const Cookies = require('./pad_utils').Cookies;
var chat = require('./chat').chat;
var getCollabClient = require('./collab_client').getCollabClient;
var padconnectionstatus = require('./pad_connectionstatus').padconnectionstatus;
@ -42,8 +43,6 @@ var padsavedrevs = require('./pad_savedrevs');
var paduserlist = require('./pad_userlist').paduserlist;
var padutils = require('./pad_utils').padutils;
var colorutils = require('./colorutils').colorutils;
var createCookie = require('./pad_utils').createCookie;
var readCookie = require('./pad_utils').readCookie;
var randomString = require('./pad_utils').randomString;
var gritter = require('./gritter').gritter;
@ -83,7 +82,7 @@ var getParameters = [
{ name: "rtl", checkVal: "true", callback: function(val) { settings.rtlIsTrue = true } },
{ name: "alwaysShowChat", checkVal: "true", callback: function(val) { if(!settings.hideChat) chat.stickToScreen(); } },
{ name: "chatAndUsers", checkVal: "true", callback: function(val) { chat.chatAndUsers(); } },
{ name: "lang", checkVal: null, callback: function(val) { window.html10n.localize([val, 'en']); createCookie('language', val); } }
{ name: "lang", checkVal: null, callback: function(val) { window.html10n.localize([val, 'en']); Cookies.set('language', val); } },
];
function getParams()
@ -130,7 +129,7 @@ function getUrlVars()
function savePassword()
{
//set the password cookie
createCookie("password",$("#passwordinput").val(),null,document.location.pathname);
Cookies.set('password', $('#passwordinput').val(), {path: document.location.pathname});
//reload
document.location=document.location;
return false;
@ -149,25 +148,21 @@ function sendClientReady(isReconnect, messageType)
document.title = padId.replace(/_+/g, ' ') + " | " + title;
}
var token = readCookie("token");
let token = Cookies.get('token');
if (token == null)
{
token = "t." + randomString();
createCookie("token", token, 60);
Cookies.set('token', token, {expires: 60});
}
var encodedSessionID = readCookie('sessionID');
var sessionID = encodedSessionID == null ? null : decodeURIComponent(encodedSessionID);
var password = readCookie("password");
var msg = {
"component": "pad",
"type": messageType,
"padId": padId,
"sessionID": sessionID,
"password": password,
"token": token,
"protocolVersion": 2
const msg = {
component: 'pad',
type: messageType,
padId: padId,
sessionID: Cookies.get('sessionID'),
password: Cookies.get('password'),
token: token,
protocolVersion: 2
};
// this is a reconnect, lets tell the server our revisionnumber
@ -456,7 +451,6 @@ var pad = {
{
pad.collabClient.sendClientMessage(msg);
},
createCookie: createCookie,
init: function()
{
@ -957,8 +951,6 @@ var settings = {
pad.settings = settings;
exports.baseURL = '';
exports.settings = settings;
exports.createCookie = createCookie;
exports.readCookie = readCookie;
exports.randomString = randomString;
exports.getParams = getParams;
exports.getUrlVars = getUrlVars;

View file

@ -14,8 +14,7 @@
* limitations under the License.
*/
const createCookie = require('./pad_utils').createCookie;
const readCookie = require('./pad_utils').readCookie;
const Cookies = require('./pad_utils').Cookies;
exports.padcookie = new class {
constructor() {
@ -40,17 +39,17 @@ exports.padcookie = new class {
}
readPrefs_() {
const jsonEsc = readCookie(this.cookieName_);
if (jsonEsc == null) return null;
try {
return JSON.parse(unescape(jsonEsc));
const json = Cookies.get(this.cookieName_);
if (json == null) return null;
return JSON.parse(json);
} catch (e) {
return null;
}
}
savePrefs_() {
createCookie(this.cookieName_, escape(JSON.stringify(this.prefs_)), 365 * 100);
Cookies.set(this.cookieName_, JSON.stringify(this.prefs_), {expires: 365 * 100});
}
getPref(prefName) {

View file

@ -20,6 +20,7 @@
* limitations under the License.
*/
const Cookies = require('./pad_utils').Cookies;
var padcookie = require('./pad_cookie').padcookie;
var padutils = require('./pad_utils').padutils;
@ -108,7 +109,7 @@ var padeditor = (function()
})
$("#languagemenu").val(html10n.getLanguage());
$("#languagemenu").change(function() {
pad.createCookie("language",$("#languagemenu").val(),null,'/');
Cookies.set('language', $('#languagemenu').val());
window.html10n.localize([$("#languagemenu").val(), 'en']);
});
},

View file

@ -39,49 +39,6 @@ function randomString(len)
return randomstring;
}
function createCookie(name, value, days, path){ /* Used by IE */
if (days)
{
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
}
else{
var expires = "";
}
if(!path){ // IF the Path of the cookie isn't set then just create it on root
path = "/";
}
//Check if we accessed the pad over https
var secure = window.location.protocol == "https:" ? ";secure" : "";
var isHttpsScheme = window.location.protocol === "https:";
var sameSite = isHttpsScheme ? ";sameSite=Strict": ";sameSite=Lax";
//Check if the browser is IE and if so make sure the full path is set in the cookie
if((navigator.appName == 'Microsoft Internet Explorer') || ((navigator.appName == 'Netscape') && (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null))){
document.cookie = name + "=" + value + expires + "; path=/" + secure + sameSite; /* Note this bodge fix for IE is temporary until auth is rewritten */
}
else{
document.cookie = name + "=" + value + expires + "; path=" + path + secure + sameSite;
}
}
function readCookie(name)
{
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++)
{
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
var padutils = {
escapeHtml: function(x)
{
@ -571,7 +528,12 @@ padutils.setupGlobalExceptionHandler = setupGlobalExceptionHandler;
padutils.binarySearch = require('./ace2_common').binarySearch;
// This file is included from Node so that it can reuse randomString, but Node doesn't have a global
// window object.
if (typeof window !== 'undefined') {
exports.Cookies = require('js-cookie/src/js.cookie');
exports.Cookies.defaults.sameSite = window.location.protocol === 'https:' ? 'Strict' : 'Lax';
exports.Cookies.defaults.secure = window.location.protocol === 'https:';
}
exports.randomString = randomString;
exports.createCookie = createCookie;
exports.readCookie = readCookie;
exports.padutils = padutils;

View file

@ -24,8 +24,7 @@
// assigns to the global `$` and augments it with plugins.
require('./jquery');
var createCookie = require('./pad_utils').createCookie;
var readCookie = require('./pad_utils').readCookie;
const Cookies = require('./pad_utils').Cookies;
var randomString = require('./pad_utils').randomString;
var hooks = require('./pluginfw/hooks');
@ -45,11 +44,11 @@ function init() {
document.title = padId.replace(/_+/g, ' ') + " | " + document.title;
//ensure we have a token
token = readCookie("token");
token = Cookies.get('token');
if(token == null)
{
token = "t." + randomString();
createCookie("token", token, 60);
Cookies.set('token', token, {expires: 60});
}
var loc = document.location;
@ -107,19 +106,16 @@ function init() {
//sends a message over the socket
function sendSocketMsg(type, data)
{
var sessionID = decodeURIComponent(readCookie("sessionID"));
var password = readCookie("password");
var msg = { "component" : "pad", // FIXME: Remove this stupidity!
"type": type,
"data": data,
"padId": padId,
"token": token,
"sessionID": sessionID,
"password": password,
"protocolVersion": 2};
socket.json.send(msg);
socket.json.send({
component: 'pad', // FIXME: Remove this stupidity!
type,
data,
padId,
token,
sessionID: Cookies.get('sessionID'),
password: Cookies.get('password'),
protocolVersion: 2,
});
}
var fireWhenAllScriptsAreLoaded = [];