@aikidosec/firewall
Version:
Zen by Aikido is an embedded Application Firewall that autonomously protects Node.js apps against common and critical attacks, provides rate limiting, detects malicious traffic (including bots), and more.
96 lines (95 loc) • 2.96 kB
JavaScript
/**
* Implementation based on https://github.com/jshttp/cookie
* License: MIT
* Copyright (c) 2012-2014 Roman Shtylman <shtylman@gmail.com>
* Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = parse;
/**
* Decodes the URI provided to it
* @param str encoded URI
* @returns decoded URI
*/
function decode(str) {
return str.indexOf("%") !== -1 ? decodeURIComponent(str) : str;
}
/**
* Encapsulates the "decode" function with a try-catch.
* @param str string that needs to be decoded
* @returns Returns the decoded result or the same string if decode fails
*/
function tryDecode(str) {
try {
return decode(str);
}
catch {
return str;
}
}
/**
* This function parses a cookie string and returns an object
* @param str A string containing cookies
* @returns Object with the cookie name as a key and their value as a value
* @example
* parse("foo=oof;bar=rab"); // Returns {foo: "oof", bar: "rab"}
*/
function parse(str) {
const obj = {};
const len = str.length;
// RFC 6265 sec 4.1.1, RFC 2616 2.2 defines a cookie name consists of one char minimum, plus '='.
if (len < 2) {
return obj;
}
let index = 0;
do {
const eqIdx = str.indexOf("=", index);
// no more cookie pairs
if (eqIdx === -1) {
break;
}
let endIdx = str.indexOf(";", index);
if (endIdx === -1) {
endIdx = len;
}
else if (eqIdx > endIdx) {
// backtrack on prior semicolon
index = str.lastIndexOf(";", eqIdx - 1) + 1;
continue;
}
const keyStartIdx = startIndex(str, index, eqIdx);
const keyEndIdx = endIndex(str, eqIdx, keyStartIdx);
const key = str.slice(keyStartIdx, keyEndIdx);
// only assign once
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
let valStartIdx = startIndex(str, eqIdx + 1, endIdx);
let valEndIdx = endIndex(str, endIdx, valStartIdx);
if (str.charCodeAt(valStartIdx) === 0x22 /* " */ &&
str.charCodeAt(valEndIdx - 1) === 0x22 /* " */) {
valStartIdx++;
valEndIdx--;
}
const val = str.slice(valStartIdx, valEndIdx);
obj[key] = tryDecode(val);
}
index = endIdx + 1;
} while (index < len);
return obj;
}
function startIndex(str, index, max) {
do {
const code = str.charCodeAt(index);
if (code !== 0x20 /* */ && code !== 0x09 /* \t */)
return index;
} while (++index < max);
return max;
}
function endIndex(str, index, min) {
while (index > min) {
const code = str.charCodeAt(--index);
if (code !== 0x20 /* */ && code !== 0x09 /* \t */)
return index + 1;
}
return min;
}
;