Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
447be8af34 | ||
|
|
0989550e5c | ||
|
|
4d9b48b4d8 | ||
|
|
979652387d | ||
|
|
de84fbdd1c | ||
|
|
170e564319 | ||
|
|
530836876f | ||
|
|
1abc46058c | ||
|
|
892a3716ed | ||
|
|
5d982a9c8d | ||
|
|
6206224f1e | ||
|
|
766310e2c7 | ||
|
|
02a397d2ae | ||
|
|
4563c86acd | ||
|
|
0a59f8068e | ||
|
|
24548e3a48 | ||
|
|
f4784d49e7 | ||
|
|
14d5069c6e | ||
|
|
9fdd55c5c6 | ||
|
|
5bc523aeff | ||
|
|
3ae2e2e2c8 | ||
|
|
83e49da7f6 | ||
|
|
fe6df8778f | ||
|
|
69073c9d99 | ||
|
|
d5a0adea0c | ||
|
|
1bcb8e433d | ||
|
|
fa05cf1d78 | ||
|
|
63dff0d34d | ||
|
|
e228b197f9 | ||
|
|
4bbeb6caa3 | ||
|
|
139d25dff9 | ||
|
|
6984258404 | ||
|
|
ba66fd6546 | ||
|
|
47bbefd81f | ||
|
|
50f796049c | ||
|
|
887ea0cf06 | ||
|
|
3e0525ee9e | ||
|
|
2e0af64ac3 |
No files matched your search
@@ -0,0 +1,32 @@
|
||||
name: "CodeQL Analysis"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '22 17 * * 5'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Master
|
||||
name: "Master Build, Test & Deploy"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: PRs
|
||||
name: "Pull Requests"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Release
|
||||
name: "Releases"
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
+2
-2
@@ -13,10 +13,10 @@ All major and minor version changes will be documented in this file. Details of
|
||||
|
||||
## Details
|
||||
|
||||
### [9.24.0] - 2020-02-02
|
||||
### [9.24.0] - 2021-02-02
|
||||
- 'SM3' hashing function added along with more configuration options for other hashing operations [@n1073645] [@n1474335] | [#1022]
|
||||
|
||||
### [9.23.0] - 2020-02-01
|
||||
### [9.23.0] - 2021-02-01
|
||||
- Various RSA operations added to encrypt, decrypt, sign, verify and generate keys [@mattnotmitt] [@GCHQ77703] | [#652]
|
||||
|
||||
### [9.22.0] - 2021-02-01
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ module.exports = function (grunt) {
|
||||
// previous one fails. & would coninue on a fail
|
||||
.join("&&")
|
||||
// Windows does not support \n properly
|
||||
.replace("\n", "\\n");
|
||||
.replace(/\n/g, "\\n");
|
||||
}
|
||||
|
||||
grunt.initConfig({
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.24.4",
|
||||
"version": "9.24.8",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.24.4",
|
||||
"version": "9.24.8",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
|
||||
@@ -212,7 +212,7 @@ self.loadRequiredModules = function(recipeConfig) {
|
||||
if (!(module in OpModules)) {
|
||||
log.info(`Loading ${module} module`);
|
||||
self.sendStatusMessage(`Loading ${module} module`);
|
||||
self.importScripts(`${self.docURL}/modules/${module}.js`);
|
||||
self.importScripts(`${self.docURL}/modules/${module}.js`); // lgtm [js/client-side-unvalidated-url-redirection]
|
||||
self.sendStatusMessage("");
|
||||
}
|
||||
});
|
||||
|
||||
+1
-1
@@ -207,7 +207,7 @@ class Dish {
|
||||
const data = new Uint8Array(this.value.slice(0, 2048)),
|
||||
types = detectFileType(data);
|
||||
|
||||
if (!types.length || !types[0].mime || !types[0].mime === "text/plain") {
|
||||
if (!types.length || !types[0].mime || !(types[0].mime === "text/plain")) {
|
||||
return null;
|
||||
} else {
|
||||
return types[0].mime;
|
||||
|
||||
+16
-4
@@ -704,8 +704,21 @@ class Utils {
|
||||
* Utils.stripHtmlTags("<div>Test</div>");
|
||||
*/
|
||||
static stripHtmlTags(htmlStr, removeScriptAndStyle=false) {
|
||||
/**
|
||||
* Recursively remove a pattern from a string until there are no more matches.
|
||||
* Avoids incomplete sanitization e.g. "aabcbc".replace(/abc/g, "") === "abc"
|
||||
*
|
||||
* @param {RegExp} pattern
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
function recursiveRemove(pattern, str) {
|
||||
const newStr = str.replace(pattern, "");
|
||||
return newStr.length === str.length ? newStr : recursiveRemove(pattern, newStr);
|
||||
}
|
||||
|
||||
if (removeScriptAndStyle) {
|
||||
htmlStr = htmlStr.replace(/<(script|style)[^>]*>.*<\/(script|style)>/gmi, "");
|
||||
htmlStr = recursiveRemove(/<(script|style)[^>]*>.*?<\/(script|style)>/gi, htmlStr);
|
||||
}
|
||||
return htmlStr.replace(/<[^>]+>/g, "");
|
||||
}
|
||||
@@ -729,11 +742,10 @@ class Utils {
|
||||
">": ">",
|
||||
'"': """,
|
||||
"'": "'", // ' not recommended because it's not in the HTML spec
|
||||
"/": "/", // forward slash is included as it helps end an HTML entity
|
||||
"`": "`"
|
||||
};
|
||||
|
||||
return str.replace(/[&<>"'/`]/g, function (match) {
|
||||
return str.replace(/[&<>"'`]/g, function (match) {
|
||||
return HTML_CHARS[match];
|
||||
});
|
||||
}
|
||||
@@ -879,7 +891,7 @@ class Utils {
|
||||
while ((m = recipeRegex.exec(recipe))) {
|
||||
// Translate strings in args back to double-quotes
|
||||
args = m[2]
|
||||
.replace(/"/g, '\\"') // Escape double quotes
|
||||
.replace(/"/g, '\\"') // Escape double quotes lgtm [js/incomplete-sanitization]
|
||||
.replace(/(^|,|{|:)'/g, '$1"') // Replace opening ' with "
|
||||
.replace(/([^\\]|(?:\\\\)+)'(,|:|}|$)/g, '$1"$2') // Replace closing ' with "
|
||||
.replace(/\\'/g, "'"); // Unescape single quotes
|
||||
|
||||
@@ -121,7 +121,7 @@ prompt.get(schema, (err, result) => {
|
||||
|
||||
const moduleName = result.opName.replace(/\w\S*/g, txt => {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
||||
}).replace(/[\s-()/./]/g, "");
|
||||
}).replace(/[\s-()./]/g, "");
|
||||
|
||||
|
||||
const template = `/**
|
||||
|
||||
@@ -32,9 +32,9 @@ export const ALPHABET_OPTIONS = [
|
||||
* @returns {string}
|
||||
*/
|
||||
export function alphabetName(alphabet) {
|
||||
alphabet = alphabet.replace("'", "'");
|
||||
alphabet = alphabet.replace("\"", """);
|
||||
alphabet = alphabet.replace("\\", "\");
|
||||
alphabet = alphabet.replace(/'/g, "'");
|
||||
alphabet = alphabet.replace(/"/g, """);
|
||||
alphabet = alphabet.replace(/\\/g, "\");
|
||||
let name;
|
||||
|
||||
ALPHABET_OPTIONS.forEach(function(a) {
|
||||
|
||||
@@ -86,8 +86,8 @@ export function getScatterValues(input, recordDelimiter, fieldDelimiter, columnH
|
||||
}
|
||||
|
||||
values = values.map(row => {
|
||||
const x = parseFloat(row[0], 10),
|
||||
y = parseFloat(row[1], 10);
|
||||
const x = parseFloat(row[0]),
|
||||
y = parseFloat(row[1]);
|
||||
|
||||
if (Number.isNaN(x)) throw new OperationError("Values must be numbers in base 10.");
|
||||
if (Number.isNaN(y)) throw new OperationError("Values must be numbers in base 10.");
|
||||
@@ -121,8 +121,8 @@ export function getScatterValuesWithColour(input, recordDelimiter, fieldDelimite
|
||||
}
|
||||
|
||||
values = values.map(row => {
|
||||
const x = parseFloat(row[0], 10),
|
||||
y = parseFloat(row[1], 10),
|
||||
const x = parseFloat(row[0]),
|
||||
y = parseFloat(row[1]),
|
||||
colour = row[2];
|
||||
|
||||
if (Number.isNaN(x)) throw new OperationError("Values must be numbers in base 10.");
|
||||
@@ -157,7 +157,7 @@ export function getSeriesValues(input, recordDelimiter, fieldDelimiter, columnHe
|
||||
values.forEach(row => {
|
||||
const serie = row[0],
|
||||
xVal = row[1],
|
||||
val = parseFloat(row[2], 10);
|
||||
val = parseFloat(row[2]);
|
||||
|
||||
if (Number.isNaN(val)) throw new OperationError("Values must be numbers in base 10.");
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Crypt resources.
|
||||
*
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2021
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
export const cryptNotice = "WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
|
||||
@@ -2197,14 +2197,14 @@ export const FILE_SIGNATURES = {
|
||||
mime: "application/octet-stream",
|
||||
description: "",
|
||||
signature: {
|
||||
0: 0x6b, // keych
|
||||
0: 0x6b, // kych
|
||||
1: 0x79,
|
||||
2: 0x63,
|
||||
3: 0x68,
|
||||
4: 0x00,
|
||||
5: 0x01
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractMacOSXKeychain
|
||||
},
|
||||
{
|
||||
name: "TCP Packet",
|
||||
@@ -2355,6 +2355,12 @@ export const FILE_SIGNATURES = {
|
||||
1: 0x03,
|
||||
2: 0xc6,
|
||||
3: 0x04
|
||||
},
|
||||
{
|
||||
0: 0x95,
|
||||
1: 0x05,
|
||||
2: 0x86,
|
||||
3: 0x04
|
||||
}
|
||||
],
|
||||
extractor: null
|
||||
@@ -3406,6 +3412,26 @@ export function extractPListXML(bytes, offset) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MacOS X Keychain Extactor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractMacOSXKeychain(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Move to size field.
|
||||
stream.moveTo(0x14);
|
||||
|
||||
// Move forwards by size.
|
||||
stream.moveForwardsBy(stream.readInt(4));
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OLE2 extractor.
|
||||
*
|
||||
|
||||
@@ -213,7 +213,7 @@ function locatePotentialSig(buf, sig, offset) {
|
||||
export function isType(type, buf) {
|
||||
const types = detectFileType(buf);
|
||||
|
||||
if (!(types && types.length)) return false;
|
||||
if (!types.length) return false;
|
||||
|
||||
if (typeof type === "string") {
|
||||
return types.reduce((acc, t) => {
|
||||
|
||||
@@ -71,12 +71,12 @@ function fuzzyMatchRecursive(
|
||||
|
||||
// Return if recursion limit is reached.
|
||||
if (++recursionCount >= recursionLimit) {
|
||||
return [false, outScore];
|
||||
return [false, outScore, []];
|
||||
}
|
||||
|
||||
// Return if we reached ends of strings.
|
||||
if (patternCurIndex === pattern.length || strCurrIndex === str.length) {
|
||||
return [false, outScore];
|
||||
return [false, outScore, []];
|
||||
}
|
||||
|
||||
// Recursion params
|
||||
@@ -92,7 +92,7 @@ function fuzzyMatchRecursive(
|
||||
pattern[patternCurIndex].toLowerCase() === str[strCurrIndex].toLowerCase()
|
||||
) {
|
||||
if (nextMatch >= maxMatches) {
|
||||
return [false, outScore];
|
||||
return [false, outScore, []];
|
||||
}
|
||||
|
||||
if (firstMatch && srcMatches) {
|
||||
@@ -100,8 +100,7 @@ function fuzzyMatchRecursive(
|
||||
firstMatch = false;
|
||||
}
|
||||
|
||||
const recursiveMatches = [];
|
||||
const [matched, recursiveScore] = fuzzyMatchRecursive(
|
||||
const [matched, recursiveScore, recursiveMatches] = fuzzyMatchRecursive(
|
||||
pattern,
|
||||
str,
|
||||
patternCurIndex,
|
||||
@@ -181,17 +180,17 @@ function fuzzyMatchRecursive(
|
||||
// Return best result
|
||||
if (recursiveMatch && (!matched || bestRecursiveScore > outScore)) {
|
||||
// Recursive score is better than "this"
|
||||
matches = [...bestRecursiveMatches];
|
||||
matches = bestRecursiveMatches;
|
||||
outScore = bestRecursiveScore;
|
||||
return [true, outScore, calcMatchRanges(matches)];
|
||||
return [true, outScore, matches];
|
||||
} else if (matched) {
|
||||
// "this" score is better than recursive
|
||||
return [true, outScore, calcMatchRanges(matches)];
|
||||
return [true, outScore, matches];
|
||||
} else {
|
||||
return [false, outScore];
|
||||
return [false, outScore, matches];
|
||||
}
|
||||
}
|
||||
return [false, outScore];
|
||||
return [false, outScore, matches];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,7 +200,7 @@ function fuzzyMatchRecursive(
|
||||
* @param [number] matches
|
||||
* @returns [[number]]
|
||||
*/
|
||||
function calcMatchRanges(matches) {
|
||||
export function calcMatchRanges(matches) {
|
||||
const ranges = [];
|
||||
let start = matches[0],
|
||||
curr = start;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* JWT resources
|
||||
*
|
||||
* @author mt3571 [mt3571@protonmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* List of the JWT algorithms that can be used
|
||||
*/
|
||||
export const JWT_ALGORITHMS = [
|
||||
"HS256",
|
||||
"HS384",
|
||||
"HS512",
|
||||
"RS256",
|
||||
"RS384",
|
||||
"RS512",
|
||||
"ES256",
|
||||
"ES384",
|
||||
"ES512",
|
||||
"None"
|
||||
];
|
||||
@@ -177,7 +177,7 @@ export default class Stream {
|
||||
|
||||
// Get the skip table.
|
||||
const skiptable = preprocess(val, length);
|
||||
let found = true;
|
||||
let found;
|
||||
|
||||
while (this.position < this.length) {
|
||||
// Until we hit the final element of val in the stream.
|
||||
|
||||
@@ -39,8 +39,8 @@ class ExtractEmailAddresses extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const displayTotal = args[0],
|
||||
// email regex from: https://www.regextester.com/98066
|
||||
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/ig;
|
||||
// email regex from: https://www.regextester.com/98066
|
||||
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig;
|
||||
return search(input, regex, null, displayTotal);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ class FrequencyDistribution extends Operation {
|
||||
"name": "Show 0%s",
|
||||
"type": "boolean",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"name": "Show ASCII",
|
||||
"type": "boolean",
|
||||
"value": true
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -76,14 +81,14 @@ class FrequencyDistribution extends Operation {
|
||||
* @returns {html}
|
||||
*/
|
||||
present(freq, args) {
|
||||
const showZeroes = args[0];
|
||||
const [showZeroes, showAscii] = args;
|
||||
|
||||
// Print
|
||||
let output = `<canvas id='chart-area'></canvas><br>
|
||||
Total data length: ${freq.dataLength}
|
||||
Number of bytes represented: ${freq.bytesRepresented}
|
||||
Number of bytes not represented: ${256 - freq.bytesRepresented}
|
||||
|
||||
Byte Percentage
|
||||
<script>
|
||||
var canvas = document.getElementById("chart-area"),
|
||||
parentRect = canvas.parentNode.getBoundingClientRect(),
|
||||
@@ -93,16 +98,32 @@ Byte Percentage
|
||||
canvas.height = parentRect.height * 0.9;
|
||||
|
||||
CanvasComponents.drawBarChart(canvas, scores, "Byte", "Frequency %", 16, 6);
|
||||
</script>`;
|
||||
</script>
|
||||
<table class="table table-hover table-sm">
|
||||
<tr><th>Byte</th>${showAscii ? "<th>ASCII</th>" : ""}<th>Percentage</th><th></th></tr>`;
|
||||
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if (freq.distribution[i] || showZeroes) {
|
||||
output += " " + Utils.hex(i, 2) + " (" +
|
||||
(freq.percentages[i].toFixed(2).replace(".00", "") + "%)").padEnd(8, " ") +
|
||||
Array(Math.ceil(freq.percentages[i])+1).join("|") + "\n";
|
||||
let c = "";
|
||||
if (showAscii) {
|
||||
if (i <= 32) {
|
||||
c = String.fromCharCode(0x2400 + i);
|
||||
} else if (i === 127) {
|
||||
c = String.fromCharCode(0x2421);
|
||||
} else {
|
||||
c = String.fromCharCode(i);
|
||||
}
|
||||
}
|
||||
const bite = `<td>${Utils.hex(i, 2)}</td>`,
|
||||
ascii = showAscii ? `<td>${c}</td>` : "",
|
||||
percentage = `<td>${(freq.percentages[i].toFixed(2).replace(".00", "") + "%").padEnd(8, " ")}</td>`,
|
||||
bars = `<td>${Array(Math.ceil(freq.percentages[i])+1).join("|")}</td>`;
|
||||
|
||||
output += `<tr>${bite}${ascii}${percentage}${bars}</tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
output += "</table>";
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ class FromBCD extends Operation {
|
||||
if (!packed) {
|
||||
// Discard each high nibble
|
||||
for (let i = 0; i < nibbles.length; i++) {
|
||||
nibbles.splice(i, 1);
|
||||
nibbles.splice(i, 1); // lgtm [js/loop-iteration-skipped-due-to-shifting]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class FromBase extends Operation {
|
||||
}
|
||||
|
||||
const number = input.replace(/\s/g, "").split(".");
|
||||
let result = new BigNumber(number[0], radix) || 0;
|
||||
let result = new BigNumber(number[0], radix);
|
||||
|
||||
if (number.length === 1) return result;
|
||||
|
||||
|
||||
@@ -84,10 +84,10 @@ class FromBase32 extends Operation {
|
||||
chr5 = ((enc7 & 7) << 5) | enc8;
|
||||
|
||||
output.push(chr1);
|
||||
if (enc2 & 3 !== 0 || enc3 !== 32) output.push(chr2);
|
||||
if (enc4 & 15 !== 0 || enc5 !== 32) output.push(chr3);
|
||||
if (enc5 & 1 !== 0 || enc6 !== 32) output.push(chr4);
|
||||
if (enc7 & 7 !== 0 || enc8 !== 32) output.push(chr5);
|
||||
if ((enc2 & 3) !== 0 || enc3 !== 32) output.push(chr2);
|
||||
if ((enc4 & 15) !== 0 || enc5 !== 32) output.push(chr3);
|
||||
if ((enc5 & 1) !== 0 || enc6 !== 32) output.push(chr4);
|
||||
if ((enc7 & 7) !== 0 || enc8 !== 32) output.push(chr5);
|
||||
}
|
||||
|
||||
return output;
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
import Operation from "../Operation.mjs";
|
||||
import kbpgp from "kbpgp";
|
||||
import { getSubkeySize, ASP } from "../lib/PGP.mjs";
|
||||
import { cryptNotice } from "../lib/Crypt.mjs";
|
||||
import * as es6promisify from "es6-promisify";
|
||||
const promisify = es6promisify.default ? es6promisify.default.promisify : es6promisify.promisify;
|
||||
|
||||
|
||||
/**
|
||||
* Generate PGP Key Pair operation
|
||||
*/
|
||||
@@ -25,7 +27,7 @@ class GeneratePGPKeyPair extends Operation {
|
||||
|
||||
this.name = "Generate PGP Key Pair";
|
||||
this.module = "PGP";
|
||||
this.description = "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.<br><br>WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
|
||||
this.description = `Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.<br><br>${cryptNotice}`;
|
||||
this.infoURL = "https://wikipedia.org/wiki/Pretty_Good_Privacy";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import forge from "node-forge";
|
||||
import { cryptNotice } from "../lib/Crypt.mjs";
|
||||
|
||||
/**
|
||||
* Generate RSA Key Pair operation
|
||||
@@ -21,7 +22,7 @@ class GenerateRSAKeyPair extends Operation {
|
||||
|
||||
this.name = "Generate RSA Key Pair";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Generate an RSA key pair with a given number of bits.<br><br>WARNING: Cryptographic operations in CyberChef should not be relied upon to provide security in any situation. No guarantee is offered for their correctness. We advise you not to use keys generated from CyberChef in operational contexts.";
|
||||
this.description = `Generate an RSA key pair with a given number of bits.<br><br>${cryptNotice}`;
|
||||
this.infoURL = "https://wikipedia.org/wiki/RSA_(cryptosystem)";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import jwt from "jsonwebtoken";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import {JWT_ALGORITHMS} from "../lib/JWT.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* JWT Sign operation
|
||||
@@ -34,18 +35,7 @@ class JWTSign extends Operation {
|
||||
{
|
||||
name: "Signing algorithm",
|
||||
type: "option",
|
||||
value: [
|
||||
"HS256",
|
||||
"HS384",
|
||||
"HS512",
|
||||
"RS256",
|
||||
"RS384",
|
||||
"RS512",
|
||||
"ES256",
|
||||
"ES384",
|
||||
"ES512",
|
||||
"None"
|
||||
]
|
||||
value: JWT_ALGORITHMS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import jwt from "jsonwebtoken";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import {JWT_ALGORITHMS} from "../lib/JWT.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* JWT Verify operation
|
||||
@@ -27,7 +28,7 @@ class JWTVerify extends Operation {
|
||||
this.outputType = "JSON";
|
||||
this.args = [
|
||||
{
|
||||
name: "Private/Secret Key",
|
||||
name: "Public/Secret Key",
|
||||
type: "text",
|
||||
value: "secret"
|
||||
},
|
||||
@@ -41,14 +42,11 @@ class JWTVerify extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const [key] = args;
|
||||
const algos = JWT_ALGORITHMS;
|
||||
algos[algos.indexOf("None")] = "none";
|
||||
|
||||
try {
|
||||
const verified = jwt.verify(input, key, { algorithms: [
|
||||
"HS256",
|
||||
"HS384",
|
||||
"HS512",
|
||||
"none"
|
||||
]});
|
||||
const verified = jwt.verify(input, key, { algorithms: algos });
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(verified, "name") && verified.name === "JsonWebTokenError") {
|
||||
throw new OperationError(verified.message);
|
||||
|
||||
@@ -376,7 +376,7 @@ class Lorenz extends Operation {
|
||||
// Psi wheels only move sometimes, dependent on M37 current setting and limitations
|
||||
|
||||
const basicmotor = m37lug;
|
||||
let totalmotor = basicmotor;
|
||||
let totalmotor;
|
||||
let lim = 0;
|
||||
|
||||
p5[2] = p5[1];
|
||||
|
||||
@@ -51,7 +51,7 @@ class OpticalCharacterRecognition extends Operation {
|
||||
async run(input, args) {
|
||||
const [showConfidence] = args;
|
||||
|
||||
if (!isWorkerEnvironment()) throw OperationError("This operation only works in a browser");
|
||||
if (!isWorkerEnvironment()) throw new OperationError("This operation only works in a browser");
|
||||
|
||||
const type = isImage(input);
|
||||
if (!type) {
|
||||
|
||||
@@ -111,7 +111,7 @@ class PHPDeserialize extends Operation {
|
||||
} else {
|
||||
const numberCheck = lastItem.match(/[0-9]+/);
|
||||
if (args[0] && numberCheck && numberCheck[0].length === lastItem.length) {
|
||||
result.push("\"" + lastItem + "\": " + item);
|
||||
result.push('"' + lastItem + '": ' + item);
|
||||
} else {
|
||||
result.push(lastItem + ": " + item);
|
||||
}
|
||||
@@ -149,11 +149,11 @@ class PHPDeserialize extends Operation {
|
||||
const length = readUntil(":");
|
||||
expect("\"");
|
||||
const value = read(length);
|
||||
expect("\";");
|
||||
expect('";');
|
||||
if (args[0]) {
|
||||
return "\"" + value.replace(/"/g, "\\\"") + "\"";
|
||||
return '"' + value.replace(/"/g, '\\"') + '"'; // lgtm [js/incomplete-sanitization]
|
||||
} else {
|
||||
return "\"" + value + "\"";
|
||||
return '"' + value + '"';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ class ParseIPv6Address extends Operation {
|
||||
|
||||
|
||||
// Detect possible EUI-64 addresses
|
||||
if ((ipv6[5] & 0xff === 0xff) && (ipv6[6] >>> 8 === 0xfe)) {
|
||||
if (((ipv6[5] & 0xff) === 0xff) && (ipv6[6] >>> 8 === 0xfe)) {
|
||||
output += "\n\nThis IPv6 address contains a modified EUI-64 address, identified by the presence of FF:FE in the 12th and 13th octets.";
|
||||
|
||||
const intIdent = Utils.hex(ipv6[4] >>> 8) + ":" + Utils.hex(ipv6[4] & 0xff) + ":" +
|
||||
|
||||
@@ -87,7 +87,7 @@ class ParseSSHHostKey extends Operation {
|
||||
* @returns {byteArray}
|
||||
*/
|
||||
convertKeyToBinary(inputKey, inputFormat) {
|
||||
const keyPattern = new RegExp(/^(?:[ssh]|[ecdsa-sha2])\S+\s+(\S*)/),
|
||||
const keyPattern = new RegExp(/^(?:ssh|ecdsa-sha2)\S+\s+(\S*)/),
|
||||
keyMatch = inputKey.match(keyPattern);
|
||||
|
||||
if (keyMatch) {
|
||||
|
||||
@@ -45,7 +45,7 @@ class RegularExpression extends Operation {
|
||||
},
|
||||
{
|
||||
name: "Email address",
|
||||
value: "(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?\\.)+[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])"
|
||||
value: "(?:[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9](?:[\\u00A0-\\uD7FF\\uE000-\\uFFFF-a-z0-9-]*[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9])?\\.)+[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9](?:[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9-]*[\\u00A0-\\uD7FF\\uE000-\\uFFFFa-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}\\])"
|
||||
},
|
||||
{
|
||||
name: "URL",
|
||||
|
||||
@@ -81,7 +81,7 @@ class SharpenImage extends Operation {
|
||||
|
||||
if (isWorkerEnvironment())
|
||||
self.sendStatusMessage("Sharpening image... (Blurring cloned image)");
|
||||
const blurImage = gaussianBlur(image.clone(), radius, 3);
|
||||
const blurImage = gaussianBlur(image.clone(), radius);
|
||||
|
||||
|
||||
if (isWorkerEnvironment())
|
||||
|
||||
@@ -125,7 +125,7 @@ class Sort extends Operation {
|
||||
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
||||
if (ret !== 0) return ret;
|
||||
}
|
||||
if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers
|
||||
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
||||
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,7 @@ class Sort extends Operation {
|
||||
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
||||
if (ret !== 0) return ret;
|
||||
}
|
||||
if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers
|
||||
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
||||
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class ToCharcode extends Operation {
|
||||
const delim = Utils.charRep(args[0] || "Space"),
|
||||
base = args[1];
|
||||
let output = "",
|
||||
padding = 2,
|
||||
padding,
|
||||
ordinal;
|
||||
|
||||
if (base < 2 || base > 36) {
|
||||
|
||||
@@ -47,7 +47,6 @@ class UnescapeUnicodeCharacters extends Operation {
|
||||
while ((m = regex.exec(input))) {
|
||||
// Add up to match
|
||||
output += input.slice(i, m.index);
|
||||
i = m.index;
|
||||
|
||||
// Add match
|
||||
output += Utils.chr(parseInt(m[1], 16));
|
||||
|
||||
@@ -153,7 +153,7 @@ class HTMLIngredient {
|
||||
for (i = 0; i < this.value.length; i++) {
|
||||
if ((m = this.value[i].match(/\[([a-z0-9 -()^]+)\]/i))) {
|
||||
html += `<optgroup label="${m[1]}">`;
|
||||
} else if ((m = this.value[i].match(/\[\/([a-z0-9 -()^]+)\]/i))) {
|
||||
} else if (this.value[i].match(/\[\/([a-z0-9 -()^]+)\]/i)) {
|
||||
html += "</optgroup>";
|
||||
} else {
|
||||
html += `<option ${this.defaultIndex === i ? "selected" : ""}>${this.value[i]}</option>`;
|
||||
@@ -177,7 +177,7 @@ class HTMLIngredient {
|
||||
for (i = 0; i < this.value.length; i++) {
|
||||
if ((m = this.value[i].name.match(/\[([a-z0-9 -()^]+)\]/i))) {
|
||||
html += `<optgroup label="${m[1]}">`;
|
||||
} else if ((m = this.value[i].name.match(/\[\/([a-z0-9 -()^]+)\]/i))) {
|
||||
} else if (this.value[i].name.match(/\[\/([a-z0-9 -()^]+)\]/i)) {
|
||||
html += "</optgroup>";
|
||||
} else {
|
||||
const val = this.type === "populateMultiOption" ?
|
||||
|
||||
+25
-14
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
|
||||
import HTMLIngredient from "./HTMLIngredient.mjs";
|
||||
import Utils from "../core/Utils.mjs";
|
||||
import url from "url";
|
||||
|
||||
|
||||
/**
|
||||
@@ -72,7 +74,7 @@ class HTMLOperation {
|
||||
* @returns {string}
|
||||
*/
|
||||
toFullHtml() {
|
||||
let html = `<div class="op-title">${this.name}</div>
|
||||
let html = `<div class="op-title">${Utils.escapeHtml(this.name)}</div>
|
||||
<div class="ingredients">`;
|
||||
|
||||
for (let i = 0; i < this.ingList.length; i++) {
|
||||
@@ -97,12 +99,13 @@ class HTMLOperation {
|
||||
* @param {[[number]]} descIdxs - Indexes of the search strings in the operation description [[start, length]]
|
||||
*/
|
||||
highlightSearchStrings(nameIdxs, descIdxs) {
|
||||
if (nameIdxs.length) {
|
||||
if (nameIdxs.length && typeof nameIdxs[0][0] === "number") {
|
||||
let opName = "",
|
||||
pos = 0;
|
||||
|
||||
nameIdxs.forEach(idxs => {
|
||||
const [start, length] = idxs;
|
||||
if (typeof start !== "number") return;
|
||||
opName += this.name.slice(pos, start) + "<b>" +
|
||||
this.name.slice(start, start + length) + "</b>";
|
||||
pos = start + length;
|
||||
@@ -111,7 +114,7 @@ class HTMLOperation {
|
||||
this.name = opName;
|
||||
}
|
||||
|
||||
if (this.description && descIdxs.length) {
|
||||
if (this.description && descIdxs.length && descIdxs[0][0] >= 0) {
|
||||
// Find HTML tag offsets
|
||||
const re = /<[^>]+>/g;
|
||||
let match;
|
||||
@@ -145,21 +148,29 @@ class HTMLOperation {
|
||||
/**
|
||||
* Given a URL for a Wikipedia (or other wiki) page, this function returns a link to that page.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {string} urlStr
|
||||
* @returns {string}
|
||||
*/
|
||||
function titleFromWikiLink(url) {
|
||||
const splitURL = url.split("/");
|
||||
if (splitURL.indexOf("wikipedia.org") < 0 && splitURL.indexOf("forensicswiki.org") < 0) {
|
||||
// Not a wiki link, return full URL
|
||||
return `<a href='${url}' target='_blank'>More Information<i class='material-icons inline-icon'>open_in_new</i></a>`;
|
||||
function titleFromWikiLink(urlStr) {
|
||||
const urlObj = url.parse(urlStr);
|
||||
let wikiName = "",
|
||||
pageTitle = "";
|
||||
|
||||
switch (urlObj.host) {
|
||||
case "forensicswiki.xyz":
|
||||
wikiName = "Forensics Wiki";
|
||||
pageTitle = urlObj.query.substr(6).replace(/_/g, " "); // Chop off 'title='
|
||||
break;
|
||||
case "wikipedia.org":
|
||||
wikiName = "Wikipedia";
|
||||
pageTitle = urlObj.pathname.substr(6).replace(/_/g, " "); // Chop off '/wiki/'
|
||||
break;
|
||||
default:
|
||||
// Not a wiki link, return full URL
|
||||
return `<a href='${urlStr}' target='_blank'>More Information<i class='material-icons inline-icon'>open_in_new</i></a>`;
|
||||
}
|
||||
|
||||
const wikiName = splitURL.indexOf("forensicswiki.org") < 0 ? "Wikipedia" : "Forensics Wiki";
|
||||
|
||||
const pageTitle = decodeURIComponent(splitURL[splitURL.length - 1])
|
||||
.replace(/_/g, " ");
|
||||
return `<a href='${url}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on ${wikiName}`;
|
||||
return `<a href='${urlObj.href}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on ${wikiName}`;
|
||||
}
|
||||
|
||||
export default HTMLOperation;
|
||||
@@ -153,7 +153,7 @@
|
||||
<script type="text/javascript">
|
||||
// Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
|
||||
if (navigator.userAgent && navigator.userAgent.match(/Trident/)) {
|
||||
document.write("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||
document.getElementById("notice").innerHTML += "Internet Explorer is not supported, please use Firefox or Chrome instead";
|
||||
alert("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -102,7 +102,7 @@ class ControlsWaiter {
|
||||
const saveLinkEl = document.getElementById("save-link");
|
||||
const saveLink = this.generateStateUrl(includeRecipe, includeInput, recipeConfig);
|
||||
|
||||
saveLinkEl.innerHTML = Utils.truncate(saveLink, 120);
|
||||
saveLinkEl.innerHTML = Utils.escapeHtml(Utils.truncate(saveLink, 120));
|
||||
saveLinkEl.setAttribute("href", saveLink);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ class ControlsWaiter {
|
||||
|
||||
const params = [
|
||||
includeRecipe ? ["recipe", recipeStr] : undefined,
|
||||
includeInput ? ["input", input] : undefined,
|
||||
includeInput ? ["input", Utils.escapeHtml(input)] : undefined,
|
||||
];
|
||||
|
||||
const hash = params
|
||||
|
||||
@@ -510,10 +510,6 @@ class InputWaiter {
|
||||
if (inputNum !== activeTab) return;
|
||||
|
||||
const fileLoaded = document.getElementById("input-file-loaded");
|
||||
let oldProgress = fileLoaded.textContent;
|
||||
if (oldProgress !== "Error") {
|
||||
oldProgress = parseInt(oldProgress.replace("%", ""), 10);
|
||||
}
|
||||
if (progress === "error") {
|
||||
fileLoaded.textContent = "Error";
|
||||
fileLoaded.style.color = "#FF0000";
|
||||
@@ -1276,7 +1272,7 @@ class InputWaiter {
|
||||
const func = function(time) {
|
||||
if (this.mousedown) {
|
||||
this.changeTabRight();
|
||||
const newTime = (time > 50) ? time = time - 10 : 50;
|
||||
const newTime = (time > 50) ? time - 10 : 50;
|
||||
setTimeout(func.bind(this, [newTime]), newTime);
|
||||
}
|
||||
};
|
||||
@@ -1293,7 +1289,7 @@ class InputWaiter {
|
||||
const func = function(time) {
|
||||
if (this.mousedown) {
|
||||
this.changeTabLeft();
|
||||
const newTime = (time > 50) ? time = time - 10 : 50;
|
||||
const newTime = (time > 50) ? time - 10 : 50;
|
||||
setTimeout(func.bind(this, [newTime]), newTime);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import HTMLOperation from "../HTMLOperation.mjs";
|
||||
import Sortable from "sortablejs";
|
||||
import {fuzzyMatch} from "../../core/lib/FuzzySearch.mjs";
|
||||
import {fuzzyMatch, calcMatchRanges} from "../../core/lib/FuzzySearch.mjs";
|
||||
|
||||
|
||||
/**
|
||||
@@ -109,8 +109,6 @@ class OperationsWaiter {
|
||||
const matchedOps = [];
|
||||
const matchedDescs = [];
|
||||
|
||||
const searchStr = inStr.toLowerCase();
|
||||
|
||||
for (const opName in this.app.operations) {
|
||||
const op = this.app.operations[opName];
|
||||
|
||||
@@ -118,12 +116,12 @@ class OperationsWaiter {
|
||||
const [nameMatch, score, idxs] = fuzzyMatch(inStr, opName);
|
||||
|
||||
// Match description based on exact match
|
||||
const descPos = op.description.toLowerCase().indexOf(searchStr);
|
||||
const descPos = op.description.toLowerCase().indexOf(inStr.toLowerCase());
|
||||
|
||||
if (nameMatch || descPos >= 0) {
|
||||
const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
|
||||
if (highlight) {
|
||||
operation.highlightSearchStrings(idxs || [], [[descPos, searchStr.length]]);
|
||||
operation.highlightSearchStrings(calcMatchRanges(idxs), [[descPos, inStr.length]]);
|
||||
}
|
||||
|
||||
if (nameMatch) {
|
||||
|
||||
@@ -306,8 +306,6 @@ class OutputWaiter {
|
||||
outputText.value = "";
|
||||
outputHtml.innerHTML = "";
|
||||
|
||||
lines = 0;
|
||||
length = 0;
|
||||
this.toggleLoader(false);
|
||||
return;
|
||||
}
|
||||
@@ -765,7 +763,7 @@ class OutputWaiter {
|
||||
const func = function(time) {
|
||||
if (this.mousedown) {
|
||||
this.changeTabRight();
|
||||
const newTime = (time > 50) ? time = time - 10 : 50;
|
||||
const newTime = (time > 50) ? time - 10 : 50;
|
||||
setTimeout(func.bind(this, [newTime]), newTime);
|
||||
}
|
||||
};
|
||||
@@ -782,7 +780,7 @@ class OutputWaiter {
|
||||
const func = function(time) {
|
||||
if (this.mousedown) {
|
||||
this.changeTabLeft();
|
||||
const newTime = (time > 50) ? time = time - 10 : 50;
|
||||
const newTime = (time > 50) ? time - 10 : 50;
|
||||
setTimeout(func.bind(this, [newTime]), newTime);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -316,7 +316,7 @@ class RecipeWaiter {
|
||||
};
|
||||
} else if (ingList[j].getAttribute("type") === "number") {
|
||||
// number
|
||||
ingredients[j] = parseFloat(ingList[j].value, 10);
|
||||
ingredients[j] = parseFloat(ingList[j].value);
|
||||
} else {
|
||||
// all others
|
||||
ingredients[j] = ingList[j].value;
|
||||
|
||||
@@ -218,7 +218,7 @@ module.exports = {
|
||||
.clearValue("#search")
|
||||
.setValue("#search", "md5")
|
||||
.useXpath()
|
||||
.waitForElementVisible("//ul[@id='search-results']//u[text()='MD5']", 1000);
|
||||
.waitForElementVisible("//ul[@id='search-results']//b[text()='MD5']", 1000);
|
||||
},
|
||||
|
||||
after: browser => {
|
||||
|
||||
@@ -14,10 +14,9 @@ const outputObject = JSON.stringify({
|
||||
iat: 1
|
||||
}, null, 4);
|
||||
|
||||
const invalidAlgorithm = "JsonWebTokenError: invalid algorithm";
|
||||
|
||||
const hsKey = "secret_cat";
|
||||
const rsKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||
/* Retaining private key as a comment
|
||||
const rsPriv = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw
|
||||
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW
|
||||
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
|
||||
@@ -32,11 +31,24 @@ fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523
|
||||
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP
|
||||
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
|
||||
-----END RSA PRIVATE KEY-----`;
|
||||
const esKey = `-----BEGIN PRIVATE KEY-----
|
||||
*/
|
||||
const rsPub = `-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd
|
||||
UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs
|
||||
HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D
|
||||
o2kQ+X5xK9cipRgEKwIDAQAB
|
||||
-----END PUBLIC KEY-----`;
|
||||
/* Retaining private key as a comment
|
||||
const esPriv = `-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
|
||||
OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
|
||||
1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
|
||||
-----END PRIVATE KEY-----`;
|
||||
*/
|
||||
const esPub = `-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEVs/o5+uQbTjL3chynL4wXgUg2R9
|
||||
q9UU8I5mEovUf86QZ7kOBIjJwqnzD1omageEHWwHdBO6B+dFabmdT9POxg==
|
||||
-----END PUBLIC KEY-----`;
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
@@ -53,22 +65,22 @@ TestRegister.addTests([
|
||||
{
|
||||
name: "JWT Verify: RS",
|
||||
input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y",
|
||||
expectedOutput: invalidAlgorithm,
|
||||
expectedOutput: outputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Verify",
|
||||
args: [rsKey],
|
||||
args: [rsPub],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Verify: ES",
|
||||
input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA",
|
||||
expectedOutput: invalidAlgorithm,
|
||||
expectedOutput: outputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Verify",
|
||||
args: [esKey],
|
||||
args: [esPub],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user