From 1d32a5939c4cd822eb85683c9a180d090bd75923 Mon Sep 17 00:00:00 2001 From: h345983745 Date: Mon, 19 Aug 2019 20:14:22 +0100 Subject: [PATCH 01/32] Core UDP parsing functionality Added to categorie Description Added Tests Added tests --- src/core/config/Categories.json | 1 + src/core/operations/ParseUDP.mjs | 92 +++++++++++++++++++++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/ParseUDP.mjs | 68 +++++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 src/core/operations/ParseUDP.mjs create mode 100644 tests/operations/tests/ParseUDP.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index f1a7b815..89b93b87 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -167,6 +167,7 @@ "Parse IP range", "Parse IPv6 address", "Parse IPv4 header", + "Parse UDP", "Parse SSH Host Key", "Parse URI", "URL Encode", diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs new file mode 100644 index 00000000..14033143 --- /dev/null +++ b/src/core/operations/ParseUDP.mjs @@ -0,0 +1,92 @@ +/** + * @author h345983745 [] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Stream from "../lib/Stream.mjs"; +import {toHex} from "../lib/Hex.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +/** + * Parse UDP operation + */ +class ParseUDP extends Operation { + + /** + * ParseUDP constructor + */ + constructor() { + super(); + + this.name = "Parse UDP"; + this.module = "Default"; + this.description = "Parses a UDP header and payload if present."; + this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; + this.inputType = "byteArray"; + this.outputType = "json"; + this.presentType = "html"; + this.args = []; + } + + /** + * @param {Uint8Array} input + * @returns {Object} + */ + run(input, args) { + + if (input.length < "8"){ + throw new OperationError("Need 8 bytes for a UDP Header"); + } + + const s = new Stream(input); + //Parse Header + const UDPPacket = { + "Source port": s.readInt(2), + "Desination port": s.readInt(2), + "Length": s.readInt(2), + "Checksum": toHex(s.getBytes(2), "0x") + }; + //Parse data if present + if (s.hasMore()){ + UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), "0x"); + } + + return UDPPacket; + + } + + /** + * Displays the UDP Packet in a table style + * @param {Object} data + * @returns {html} + */ + present(data) { + // const currentRecipeConfig = this.state.opList.map(op => op.config); + // console.log(currentRecipeConfig); + const html = []; + html.push(""); + html.push(""); + html.push(""); + html.push(""); + html.push(""); + + for (const key in data) { + switch (key){ + default: { + html.push(""); + html.push(""); + html.push(""); + html.push(""); + } + } + } + html.push("
FieldValue
" + key + "" + data[key] + "
"); + return html.join(""); + } + +} + + +export default ParseUDP; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index eac6ab9a..1ad69228 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -88,6 +88,7 @@ import "./tests/BLAKE2s"; import "./tests/Protobuf"; import "./tests/ParseSSHHostKey"; import "./tests/DefangIP"; +import "./tests/ParseUDP"; // Cannot test operations that use the File type yet //import "./tests/SplitColourChannels"; diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs new file mode 100644 index 00000000..1cd6482f --- /dev/null +++ b/tests/operations/tests/ParseUDP.mjs @@ -0,0 +1,68 @@ +/** + * Parse UDP tests. + * + * @author h345983745 + * + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Parse UDP: No Data - JSON", + input: "04 89 00 35 00 2c 01 01", + expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"], + }, + { + op: "Parse UDP", + args: [], + }, + { + op: "JSON Minify", + args: [], + }, + ], + }, { + name: "Parse UDP: With Data - JSON", + input: "04 89 00 35 00 2c 01 01 02 02", + expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"], + }, + { + op: "Parse UDP", + args: [], + }, + { + op: "JSON Minify", + args: [], + }, + ], + }, + { + name: "Parse UDP: Not Enough Bytes", + input: "04 89 00", + expectedOutput: "Need 8 bytes for a UDP Header", + recipeConfig: [ + { + op: "From Hex", + args: ["Auto"], + }, + { + op: "Parse UDP", + args: [], + }, + { + op: "JSON Minify", + args: [], + }, + ], + } +]); From b14cb99587faa49da10237b49f4842527293995e Mon Sep 17 00:00:00 2001 From: h345983745 Date: Mon, 19 Aug 2019 20:55:04 +0100 Subject: [PATCH 02/32] Removed console.log --- src/core/operations/ParseUDP.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index 14033143..ec529d1b 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -63,8 +63,6 @@ class ParseUDP extends Operation { * @returns {html} */ present(data) { - // const currentRecipeConfig = this.state.opList.map(op => op.config); - // console.log(currentRecipeConfig); const html = []; html.push(""); html.push(""); From b8dbb111364346d027ce252f6bb2ec9f5c4b68e9 Mon Sep 17 00:00:00 2001 From: h345983745 Date: Mon, 19 Aug 2019 21:05:38 +0100 Subject: [PATCH 03/32] Spelling --- src/core/operations/ParseUDP.mjs | 4 ++-- tests/operations/tests/ParseUDP.mjs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index ec529d1b..234a08f6 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -22,7 +22,7 @@ class ParseUDP extends Operation { this.name = "Parse UDP"; this.module = "Default"; - this.description = "Parses a UDP header and payload if present."; + this.description = "Parses a UDP header and payload (if present)."; this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; this.inputType = "byteArray"; this.outputType = "json"; @@ -44,7 +44,7 @@ class ParseUDP extends Operation { //Parse Header const UDPPacket = { "Source port": s.readInt(2), - "Desination port": s.readInt(2), + "Destination port": s.readInt(2), "Length": s.readInt(2), "Checksum": toHex(s.getBytes(2), "0x") }; diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs index 1cd6482f..f6bf54d0 100644 --- a/tests/operations/tests/ParseUDP.mjs +++ b/tests/operations/tests/ParseUDP.mjs @@ -12,7 +12,7 @@ TestRegister.addTests([ { name: "Parse UDP: No Data - JSON", input: "04 89 00 35 00 2c 01 01", - expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", recipeConfig: [ { op: "From Hex", @@ -30,7 +30,7 @@ TestRegister.addTests([ }, { name: "Parse UDP: With Data - JSON", input: "04 89 00 35 00 2c 01 01 02 02", - expectedOutput: "{\"Source port\":1161,\"Desination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", recipeConfig: [ { op: "From Hex", From 082d939f7d02889b9125d35cfe5a553167ec25f8 Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 22 Aug 2019 11:26:04 +0100 Subject: [PATCH 04/32] Add customisations for confirm box. Can change the text of the accept and reject buttons. Now returns undefined if the user clicks off it --- src/web/App.mjs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/web/App.mjs b/src/web/App.mjs index 56746a41..60491ef4 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -670,18 +670,22 @@ class App { * * @param {string} title - The title of the box * @param {string} body - The question (HTML supported) + * @param {string} accept - The text of the accept button + * @param {string} reject - The text of the reject button * @param {function} callback - A function accepting one boolean argument which handles the * response e.g. function(answer) {...} * @param {Object} [scope=this] - The object to bind to the callback function * * @example * // Pops up a box asking if the user would like a cookie. Prints the answer to the console. - * this.confirm("Question", "Would you like a cookie?", function(answer) {console.log(answer);}); + * this.confirm("Question", "Would you like a cookie?", "Yes", "No", function(answer) {console.log(answer);}); */ - confirm(title, body, callback, scope) { + confirm(title, body, accept, reject, callback, scope) { scope = scope || this; document.getElementById("confirm-title").innerHTML = title; document.getElementById("confirm-body").innerHTML = body; + document.getElementById("confirm-yes").innerText = accept; + document.getElementById("confirm-no").innerText = reject; document.getElementById("confirm-modal").style.display = "block"; this.confirmClosed = false; @@ -694,9 +698,14 @@ class App { callback.bind(scope)(true); $("#confirm-modal").modal("hide"); }.bind(this)) + .one("click", "#confirm-no", function() { + this.confirmClosed = true; + callback.bind(scope)(false); + }.bind(this)) .one("hide.bs.modal", function(e) { - if (!this.confirmClosed) - callback.bind(scope)(false); + if (!this.confirmClosed) { + callback.bind(scope)(undefined); + } this.confirmClosed = true; }.bind(this)); } From 9f2d1453edda0190279fae8c45f6b17885302be7 Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 22 Aug 2019 11:26:43 +0100 Subject: [PATCH 05/32] Make the wordWrap change event only fire when the word wrap checkbox is changed --- src/web/Manager.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Manager.mjs b/src/web/Manager.mjs index 5ab44b21..cb579721 100755 --- a/src/web/Manager.mjs +++ b/src/web/Manager.mjs @@ -224,7 +224,7 @@ class Manager { document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options)); document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options)); this.addDynamicListener(".option-item input[type=checkbox]", "change", this.options.switchChange, this.options); - this.addDynamicListener(".option-item input[type=checkbox]", "change", this.options.setWordWrap, this.options); + this.addDynamicListener(".option-item input[type=checkbox]#wordWrap", "change", this.options.setWordWrap, this.options); this.addDynamicListener(".option-item input[type=checkbox]#useMetaKey", "change", this.bindings.updateKeybList, this.bindings); this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options); this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options); From f43a868607832f58929ada59797ffb4a53003f45 Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 22 Aug 2019 11:53:41 +0100 Subject: [PATCH 06/32] Add carriage return detection for pasted and switched inputs. Fix switching the output to input not working properly. Add nicer confirmation boxes for zipping outputs. --- src/web/html/index.html | 17 +- src/web/index.js | 4 +- src/web/waiters/InputWaiter.mjs | 101 +++++++--- src/web/waiters/OptionsWaiter.mjs | 308 +++++++++++++++--------------- src/web/waiters/OutputWaiter.mjs | 170 ++++++++++++----- src/web/workers/InputWorker.mjs | 45 +++-- 6 files changed, 399 insertions(+), 246 deletions(-) diff --git a/src/web/html/index.html b/src/web/html/index.html index 011742d3..cb9c3dbe 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -568,11 +568,18 @@
- -
+ + + +
+ +
diff --git a/src/web/waiters/InputWaiter.mjs b/src/web/waiters/InputWaiter.mjs index 36b5f05c..e519b963 100644 --- a/src/web/waiters/InputWaiter.mjs +++ b/src/web/waiters/InputWaiter.mjs @@ -728,30 +728,46 @@ class InputWaiter { e.preventDefault(); e.stopPropagation(); - const pastedData = e.clipboardData.getData("Text"); - const preserve = await this.preserveCarriageReturns(pastedData); - - if (pastedData.length < (this.app.options.ioDisplayThreshold * 1024) && !preserve) { - // Pasting normally fires the inputChange() event before - // changing the value, so instead change it here ourselves - // and manually fire inputChange() - const inputText = document.getElementById("input-text"); - const selStart = inputText.selectionStart; - const selEnd = inputText.selectionEnd; - const startVal = inputText.value.slice(0, selStart); - const endVal = inputText.value.slice(selEnd); - - inputText.value = startVal + pastedData + endVal; - inputText.setSelectionRange(selStart + pastedData.length, selStart + pastedData.length); - this.debounceInputChange(e); - } else { + const self = this; + /** + * Triggers the input file/binary data overlay + * + * @param {string} pastedData + */ + function triggerOverlay(pastedData) { const file = new File([pastedData], "PastedData", { type: "text/plain", lastModified: Date.now() }); - this.loadUIFiles([file]); + self.loadUIFiles([file]); + } + + const pastedData = e.clipboardData.getData("Text"); + const inputText = document.getElementById("input-text"); + const selStart = inputText.selectionStart; + const selEnd = inputText.selectionEnd; + const startVal = inputText.value.slice(0, selStart); + const endVal = inputText.value.slice(selEnd); + const val = startVal + pastedData + endVal; + + if (val.length >= (this.app.options.ioDisplayThreshold * 1024)) { + // Data too large to display, use overlay + triggerOverlay(val); return false; + } else if (await this.preserveCarriageReturns(val)) { + // Data contains a carriage return and the user doesn't wish to edit it, use overlay + // We check this in a separate condition to make sure it is not run unless absolutely + // necessary. + triggerOverlay(val); + return false; + } else { + // Pasting normally fires the inputChange() event before + // changing the value, so instead change it here ourselves + // and manually fire inputChange() + inputText.value = val; + inputText.setSelectionRange(selStart + pastedData.length, selStart + pastedData.length); + this.debounceInputChange(e); } } @@ -839,33 +855,34 @@ class InputWaiter { * preserved, so display an overlay so it can't be edited */ async preserveCarriageReturns(input) { - if (input.indexOf("\r") >= 0) { - const optionsStr = "This behaviour can be changed in the options"; - if (!this.app.options.userSetCR) { - let preserve = await new Promise(function(resolve, reject) { - this.app.confirm( - "Carriage Return Detected", - "A carriage return was detected in your input. As HTML textareas can't display carriage returns, editing must be turned off to preserve them.
Alternatively, you can enable editing but your carriage returns will not be preserved.

This preference will be saved, and can be toggled in the options.", - "Preserve Carriage Returns", - "Enable Editing", resolve, this); - }.bind(this)); - if (preserve === undefined) { - this.app.alert(`Not preserving carriage returns. ${optionsStr}`, 4000); - preserve = false; - } - this.manager.options.updateOption("preserveCR", preserve); - this.manager.options.updateOption("userSetCR", true); - } else { - if (this.app.options.preserveCR) { - this.app.alert(`A carriage return was detected in your input, so editing has been disabled to preserve it. ${optionsStr}`, 6000); - } else { - this.app.alert(`A carriage return was detected in your input. Editing is remaining enabled, but any carriage returns will be removed. ${optionsStr}`, 6000); - } + if (input.indexOf("\r") < 0) return false; + + const optionsStr = "This behaviour can be changed in the Options pane"; + if (!this.app.options.userSetCR) { + // User has not set a CR preference yet + let preserve = await new Promise(function(resolve, reject) { + this.app.confirm( + "Carriage Return Detected", + "A carriage return (\\r, 0x0d) was detected in your input. As HTML textareas can't display carriage returns, editing must be turned off to preserve them.
Alternatively, you can enable editing but your carriage returns will not be preserved.

This preference will be saved but can be toggled in the options pane.", + "Preserve Carriage Returns", + "Enable Editing", resolve, this); + }.bind(this)); + if (preserve === undefined) { + // The confirm pane was closed without picking a specific choice + this.app.alert(`Not preserving carriage returns.\n${optionsStr}`, 5000); + preserve = false; } - return this.app.options.preserveCR; + this.manager.options.updateOption("preserveCR", preserve); + this.manager.options.updateOption("userSetCR", true); } else { - return false; + if (this.app.options.preserveCR) { + this.app.alert(`A carriage return (\\r, 0x0d) was detected in your input, so editing has been disabled to preserve it.
${optionsStr}`, 10000); + } else { + this.app.alert(`A carriage return (\\r, 0x0d) was detected in your input. Editing is remaining enabled, but carriage returns will not be preserved.
${optionsStr}`, 10000); + } } + + return this.app.options.preserveCR; } /** diff --git a/src/web/waiters/OutputWaiter.mjs b/src/web/waiters/OutputWaiter.mjs index af39b80c..6bbe8f4a 100755 --- a/src/web/waiters/OutputWaiter.mjs +++ b/src/web/waiters/OutputWaiter.mjs @@ -546,7 +546,7 @@ class OutputWaiter { "Cancel zipping", resolve, this); }.bind(this)); - if (!cancel && cancel !== undefined) { + if (!cancel) { this.terminateZipWorker(); } } From 9fc451ece804458557676f87ffb4704b7b61147c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 22 Aug 2019 16:31:59 +0100 Subject: [PATCH 11/32] 9.0.9 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd899ffc..a8c69106 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.0.8", + "version": "9.0.9", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 50239b44..640e0b2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.0.8", + "version": "9.0.9", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 05bfd993180ee022b6ce26b97083fda4b884ee2c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 22 Aug 2019 16:35:20 +0100 Subject: [PATCH 12/32] 9.0.10 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a8c69106..f0ccc74e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.0.9", + "version": "9.0.10", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 640e0b2b..e7e7614c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.0.9", + "version": "9.0.10", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 4624266a5c9444445d7ea64b07eb5db73dcdd280 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 22 Aug 2019 16:50:43 +0100 Subject: [PATCH 13/32] Updated CHANGELOG --- CHANGELOG.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a19eec80..28592902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,9 @@ All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master). -### [9.2.0] - 2019-08-13 -- 'Defang IP Addresses' operation added [@h345983745] | [#556] - -### [9.1.0] - 2019-08-13 +### [9.1.0] - 2019-08-22 - 'Parse SSH Host Key' operation added [@j433866] | [#595] +- 'Defang IP Addresses' operation added [@h345983745] | [#556] ## [9.0.0] - 2019-07-09 - [Multiple inputs](https://github.com/gchq/CyberChef/wiki/Multiple-Inputs) are now supported in the main web UI, allowing you to upload and process multiple files at once [@j433866] | [#566] @@ -164,7 +162,6 @@ All major and minor version changes will be documented in this file. Details of -[9.2.0]: https://github.com/gchq/CyberChef/releases/tag/v9.2.0 [9.1.0]: https://github.com/gchq/CyberChef/releases/tag/v9.1.0 [9.0.0]: https://github.com/gchq/CyberChef/releases/tag/v9.0.0 [8.38.0]: https://github.com/gchq/CyberChef/releases/tag/v8.38.0 From dc99797f7badaec6d33cbb0e0310361259d2a63b Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 22 Aug 2019 16:51:50 +0100 Subject: [PATCH 14/32] 9.1.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f0ccc74e..2edee97c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.0.10", + "version": "9.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e7e7614c..f29b393a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.0.10", + "version": "9.1.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From afc7c40975dbd56d187deae3ff466605ab36e18f Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 22 Aug 2019 17:38:56 +0100 Subject: [PATCH 15/32] Create SECURITY.md --- SECURITY.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..c934c934 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,26 @@ +# Security Policy + +## Supported Versions + +CyberChef is supported on a best endeavours basis. Patches will be applied to +the latest version rather than retroactively to older versions. To ensure you +are using the most secure version of CyberChef, please make sure you have the +[latest release](https://github.com/gchq/CyberChef/releases/latest). The +official [live demo](https://gchq.github.io/CyberChef/) is always up to date. + +## Reporting a Vulnerability + +In most scenarios, the most appropriate way to report a vulnerability is to +[raise a new issue](https://github.com/gchq/CyberChef/issues/new/choose) +describing the problem in as much detail as possible, ideally with examples. +This will obviously be public. If you feel that the vulnerability is +significant enough to warrant a private disclosure, please email +[oss@gchq.gov.uk](mailto:oss@gchq.gov.uk) and +[n1474335@gmail.com](mailto:n1474335@gmail.com). + +Disclosures of vulnerabilities in CyberChef are always welcomed. Whilst we aim +to write clean and secure code free from bugs, we recognise that this is an open +source project written by analysts in their spare time, relying on dozens of +open source libraries that are modified and updated on a regular basis. We hope +that the community will continue to support us as we endeavour to maintain and +develop this tool together. From 00313453837eb4b4ef19d366e22a149e1ff0b094 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 23 Aug 2019 10:56:13 +0100 Subject: [PATCH 16/32] Tidied up 'Parse UDP' operation --- README.md | 1 - src/core/operations/ParseUDP.mjs | 34 ++++++++++++----------------- tests/operations/tests/ParseUDP.mjs | 4 ++-- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 299b5d87..c0996378 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef) [![dependencies Status](https://david-dm.org/gchq/CyberChef/status.svg)](https://david-dm.org/gchq/CyberChef) [![npm](https://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/cyberchef) -![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=blue) [![](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/gchq/CyberChef/blob/master/LICENSE) [![Gitter](https://badges.gitter.im/gchq/CyberChef.svg)](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index 234a08f6..0a88fd5d 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -24,37 +24,35 @@ class ParseUDP extends Operation { this.module = "Default"; this.description = "Parses a UDP header and payload (if present)."; this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; - this.inputType = "byteArray"; + this.inputType = "ArrayBuffer"; this.outputType = "json"; this.presentType = "html"; this.args = []; } /** - * @param {Uint8Array} input + * @param {ArrayBuffer} input * @returns {Object} */ run(input, args) { - - if (input.length < "8"){ + if (input.byteLength < 8) { throw new OperationError("Need 8 bytes for a UDP Header"); } - const s = new Stream(input); - //Parse Header + const s = new Stream(new Uint8Array(input)); + // Parse Header const UDPPacket = { "Source port": s.readInt(2), "Destination port": s.readInt(2), "Length": s.readInt(2), - "Checksum": toHex(s.getBytes(2), "0x") + "Checksum": toHex(s.getBytes(2), "") }; - //Parse data if present - if (s.hasMore()){ - UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), "0x"); + // Parse data if present + if (s.hasMore()) { + UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), ""); } return UDPPacket; - } /** @@ -64,21 +62,17 @@ class ParseUDP extends Operation { */ present(data) { const html = []; - html.push("
"); + html.push("
"); html.push(""); html.push(""); html.push(""); html.push(""); for (const key in data) { - switch (key){ - default: { - html.push(""); - html.push(""); - html.push(""); - html.push(""); - } - } + html.push(""); + html.push(""); + html.push(""); + html.push(""); } html.push("
FieldValue
" + key + "" + data[key] + "
" + key + "" + data[key] + "
"); return html.join(""); diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs index f6bf54d0..2c519232 100644 --- a/tests/operations/tests/ParseUDP.mjs +++ b/tests/operations/tests/ParseUDP.mjs @@ -12,7 +12,7 @@ TestRegister.addTests([ { name: "Parse UDP: No Data - JSON", input: "04 89 00 35 00 2c 01 01", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\"}", recipeConfig: [ { op: "From Hex", @@ -30,7 +30,7 @@ TestRegister.addTests([ }, { name: "Parse UDP: With Data - JSON", input: "04 89 00 35 00 2c 01 01 02 02", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x010x01\",\"Data\":\"0x020x02\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\",\"Data\":\"0202\"}", recipeConfig: [ { op: "From Hex", From f1794a2dfe2988d1a032febc0e8ce0c2557a8332 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 23 Aug 2019 11:22:00 +0100 Subject: [PATCH 17/32] Updated CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28592902..8914ea43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master). +### [9.2.0] - 2019-08-23 +- 'Parse UDP' operation added [@h345983745] | [#614] + ### [9.1.0] - 2019-08-22 - 'Parse SSH Host Key' operation added [@j433866] | [#595] - 'Defang IP Addresses' operation added [@h345983745] | [#556] @@ -162,6 +165,7 @@ All major and minor version changes will be documented in this file. Details of +[9.2.0]: https://github.com/gchq/CyberChef/releases/tag/v9.2.0 [9.1.0]: https://github.com/gchq/CyberChef/releases/tag/v9.1.0 [9.0.0]: https://github.com/gchq/CyberChef/releases/tag/v9.0.0 [8.38.0]: https://github.com/gchq/CyberChef/releases/tag/v8.38.0 @@ -286,3 +290,4 @@ All major and minor version changes will be documented in this file. Details of [#585]: https://github.com/gchq/CyberChef/pull/585 [#591]: https://github.com/gchq/CyberChef/pull/591 [#595]: https://github.com/gchq/CyberChef/pull/595 +[#614]: https://github.com/gchq/CyberChef/pull/614 From d3e3e6e6fc415915cd8143fbf57d04dd94078f36 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Fri, 23 Aug 2019 11:22:03 +0100 Subject: [PATCH 18/32] 9.2.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2edee97c..351f4864 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.1.0", + "version": "9.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f29b393a..6c7acfb3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.1.0", + "version": "9.2.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 8e1bd36b4ce500d47217efaf50450ba7ae31a50b Mon Sep 17 00:00:00 2001 From: Chris Hepner Date: Fri, 23 Aug 2019 14:52:16 -0700 Subject: [PATCH 19/32] Fix typo in ScanForEmbeddedFiles Change "suffiently" to "sufficiently" --- src/core/operations/ScanForEmbeddedFiles.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/ScanForEmbeddedFiles.mjs b/src/core/operations/ScanForEmbeddedFiles.mjs index b1497407..11102f21 100644 --- a/src/core/operations/ScanForEmbeddedFiles.mjs +++ b/src/core/operations/ScanForEmbeddedFiles.mjs @@ -41,7 +41,7 @@ class ScanForEmbeddedFiles extends Operation { * @returns {string} */ run(input, args) { - let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n", + let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any sufficiently long file is likely to contain these magic bytes coincidentally.\n", numFound = 0; const categories = [], data = new Uint8Array(input); From 6c9ce15b2609e96c5fc9fbe482a1abda4b01d6ca Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Sat, 24 Aug 2019 01:14:44 +0100 Subject: [PATCH 20/32] Add octal support to Change IP Format. Also add test cases covering interchanging between all four formats. --- src/core/operations/ChangeIPFormat.mjs | 34 +++++++++++---- tests/operations/index.mjs | 1 + tests/operations/tests/ChangeIPFormat.mjs | 52 +++++++++++++++++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 tests/operations/tests/ChangeIPFormat.mjs diff --git a/src/core/operations/ChangeIPFormat.mjs b/src/core/operations/ChangeIPFormat.mjs index fea5c561..c9adc5d8 100644 --- a/src/core/operations/ChangeIPFormat.mjs +++ b/src/core/operations/ChangeIPFormat.mjs @@ -29,12 +29,12 @@ class ChangeIPFormat extends Operation { { "name": "Input format", "type": "option", - "value": ["Dotted Decimal", "Decimal", "Hex"] + "value": ["Dotted Decimal", "Decimal", "Octal", "Hex"] }, { "name": "Output format", "type": "option", - "value": ["Dotted Decimal", "Decimal", "Hex"] + "value": ["Dotted Decimal", "Decimal", "Octal", "Hex"] } ]; } @@ -54,7 +54,6 @@ class ChangeIPFormat extends Operation { if (lines[i] === "") continue; let baIp = []; let octets; - let decimal; if (inFormat === outFormat) { output += lines[i] + "\n"; @@ -70,11 +69,10 @@ class ChangeIPFormat extends Operation { } break; case "Decimal": - decimal = lines[i].toString(); - baIp.push(decimal >> 24 & 255); - baIp.push(decimal >> 16 & 255); - baIp.push(decimal >> 8 & 255); - baIp.push(decimal & 255); + baIp = this.fromNumber(lines[i].toString(), 10); + break; + case "Octal": + baIp = this.fromNumber(lines[i].toString(), 8); break; case "Hex": baIp = fromHex(lines[i]); @@ -100,6 +98,10 @@ class ChangeIPFormat extends Operation { decIp = ((baIp[0] << 24) | (baIp[1] << 16) | (baIp[2] << 8) | baIp[3]) >>> 0; output += decIp.toString() + "\n"; break; + case "Octal": + decIp = ((baIp[0] << 24) | (baIp[1] << 16) | (baIp[2] << 8) | baIp[3]) >>> 0; + output += "0" + decIp.toString(8) + "\n"; + break; case "Hex": hexIp = ""; for (j = 0; j < baIp.length; j++) { @@ -115,6 +117,22 @@ class ChangeIPFormat extends Operation { return output.slice(0, output.length-1); } + /** + * Constructs an array of IP address octets from a numerical value. + * @param {string} value The value of the IP address + * @param {number} radix The numeral system to be used + * @returns {number[]} + */ + fromNumber(value, radix) { + const decimal = parseInt(value, radix); + const baIp = []; + baIp.push(decimal >> 24 & 255); + baIp.push(decimal >> 16 & 255); + baIp.push(decimal >> 8 & 255); + baIp.push(decimal & 255); + return baIp; + } + } export default ChangeIPFormat; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 1ad69228..696deba0 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -26,6 +26,7 @@ import "./tests/BitwiseOp"; import "./tests/ByteRepr"; import "./tests/CartesianProduct"; import "./tests/CharEnc"; +import "./tests/ChangeIPFormat"; import "./tests/Charts"; import "./tests/Checksum"; import "./tests/Ciphers"; diff --git a/tests/operations/tests/ChangeIPFormat.mjs b/tests/operations/tests/ChangeIPFormat.mjs new file mode 100644 index 00000000..d92ffb79 --- /dev/null +++ b/tests/operations/tests/ChangeIPFormat.mjs @@ -0,0 +1,52 @@ +/** + * Change IP format tests. + * + * @author Chris Smith + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Change IP format: Dotted Decimal to Hex", + input: "192.168.1.1", + expectedOutput: "c0a80101", + recipeConfig: [ + { + op: "Change IP format", + args: ["Dotted Decimal", "Hex"], + }, + ], + }, { + name: "Change IP format: Decimal to Dotted Decimal", + input: "3232235777", + expectedOutput: "192.168.1.1", + recipeConfig: [ + { + op: "Change IP format", + args: ["Decimal", "Dotted Decimal"], + }, + ], + }, { + name: "Change IP format: Hex to Octal", + input: "c0a80101", + expectedOutput: "030052000401", + recipeConfig: [ + { + op: "Change IP format", + args: ["Hex", "Octal"], + }, + ], + }, { + name: "Change IP format: Octal to Decimal", + input: "030052000401", + expectedOutput: "3232235777", + recipeConfig: [ + { + op: "Change IP format", + args: ["Octal", "Decimal"], + }, + ], + }, +]); From e7980a888623fcd15b78d1b713c2ebd96771f288 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 27 Aug 2019 13:02:24 +0100 Subject: [PATCH 21/32] 9.2.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 351f4864..f5669cc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.2.0", + "version": "9.2.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6c7acfb3..c6da7887 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.2.0", + "version": "9.2.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 44b90be7d6c23be3aeaf17a99e107d729f11eb5b Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 27 Aug 2019 17:59:45 +0100 Subject: [PATCH 22/32] Added 'fully qualified' to the description for the 'Extract Domains' operation to reduce ambiguity. #618 --- src/core/operations/ExtractDomains.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/ExtractDomains.mjs b/src/core/operations/ExtractDomains.mjs index ed1bbdb6..cc65ff4b 100644 --- a/src/core/operations/ExtractDomains.mjs +++ b/src/core/operations/ExtractDomains.mjs @@ -20,7 +20,7 @@ class ExtractDomains extends Operation { this.name = "Extract domains"; this.module = "Regex"; - this.description = "Extracts domain names.
Note that this will not include paths. Use Extract URLs to find entire URLs."; + this.description = "Extracts fully qualified domain names.
Note that this will not include paths. Use Extract URLs to find entire URLs."; this.inputType = "string"; this.outputType = "string"; this.args = [ From 094d352e5ff35709c12a644c7fb61bb560befc0c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 27 Aug 2019 18:13:33 +0100 Subject: [PATCH 23/32] Added eslint space-before-blocks rule --- .eslintrc.json | 1 + src/core/lib/Arithmetic.mjs | 2 +- src/core/lib/ConvertCoordinates.mjs | 8 ++++---- src/core/lib/IP.mjs | 6 +++--- src/core/lib/LoremIpsum.mjs | 2 +- src/core/operations/BlurImage.mjs | 2 +- src/core/operations/DNSOverHTTPS.mjs | 2 +- src/core/operations/FlipImage.mjs | 2 +- src/core/operations/GenerateLoremIpsum.mjs | 2 +- src/core/operations/ImageFilter.mjs | 2 +- src/core/operations/MicrosoftScriptDecoder.mjs | 2 +- src/core/operations/ParseColourCode.mjs | 2 +- src/core/operations/SharpenImage.mjs | 2 +- src/core/operations/SwapEndianness.mjs | 2 +- src/core/operations/UNIXTimestampToWindowsFiletime.mjs | 4 ++-- src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs | 2 +- src/node/api.mjs | 2 +- 17 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 495c000f..e307112b 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -43,6 +43,7 @@ // stylistic conventions "brace-style": ["error", "1tbs"], + "space-before-blocks": ["error", "always"], "block-spacing": "error", "array-bracket-spacing": "error", "comma-spacing": "error", diff --git a/src/core/lib/Arithmetic.mjs b/src/core/lib/Arithmetic.mjs index 2c56e483..7c10855f 100644 --- a/src/core/lib/Arithmetic.mjs +++ b/src/core/lib/Arithmetic.mjs @@ -109,7 +109,7 @@ export function mean(data) { */ export function median(data) { if ((data.length % 2) === 0 && data.length > 0) { - data.sort(function(a, b){ + data.sort(function(a, b) { return a.minus(b); }); const first = data[Math.floor(data.length / 2)]; diff --git a/src/core/lib/ConvertCoordinates.mjs b/src/core/lib/ConvertCoordinates.mjs index 1acb5ef4..d688d29e 100644 --- a/src/core/lib/ConvertCoordinates.mjs +++ b/src/core/lib/ConvertCoordinates.mjs @@ -327,13 +327,13 @@ export function convertCoordinates (input, inFormat, inDelim, outFormat, outDeli * @param {string} input - The input data to be split * @returns {number[]} An array of the different items in the string, stored as floats */ -function splitInput (input){ +function splitInput (input) { const split = []; input.split(/\s+/).forEach(item => { // Remove any character that isn't a digit, decimal point or negative sign item = item.replace(/[^0-9.-]/g, ""); - if (item.length > 0){ + if (item.length > 0) { // Turn the item into a float split.push(parseFloat(item)); } @@ -350,7 +350,7 @@ function splitInput (input){ * @param {number} precision - The precision the result should be rounded to * @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string) */ -function convDMSToDD (degrees, minutes, seconds, precision){ +function convDMSToDD (degrees, minutes, seconds, precision) { const absDegrees = Math.abs(degrees); let conv = absDegrees + (minutes / 60) + (seconds / 3600); let outString = round(conv, precision) + "°"; @@ -566,7 +566,7 @@ export function findFormat (input, delim) { // Test DMS/DDM/DD formats if (testData !== undefined) { const split = splitInput(testData); - switch (split.length){ + switch (split.length) { case 3: return "Degrees Minutes Seconds"; case 2: diff --git a/src/core/lib/IP.mjs b/src/core/lib/IP.mjs index f378763e..f9c54ad0 100644 --- a/src/core/lib/IP.mjs +++ b/src/core/lib/IP.mjs @@ -241,7 +241,7 @@ export function ipv6ListedRange(match, includeNetworkInfo) { ipv6List = ipv6List.filter(function(str) { return str.trim(); }); - for (let i =0; i < ipv6List.length; i++){ + for (let i =0; i < ipv6List.length; i++) { ipv6List[i] = ipv6List[i].trim(); } const ipv6CidrList = ipv6List.filter(function(a) { @@ -502,8 +502,8 @@ export function ipv6Compare(a, b) { const a_ = strToIpv6(a), b_ = strToIpv6(b); - for (let i = 0; i < a_.length; i++){ - if (a_[i] !== b_[i]){ + for (let i = 0; i < a_.length; i++) { + if (a_[i] !== b_[i]) { return a_[i] - b_[i]; } } diff --git a/src/core/lib/LoremIpsum.mjs b/src/core/lib/LoremIpsum.mjs index d7fff69b..3d60fa89 100644 --- a/src/core/lib/LoremIpsum.mjs +++ b/src/core/lib/LoremIpsum.mjs @@ -85,7 +85,7 @@ function getWords(length=3) { const words = []; let word; let previousWord; - while (words.length < length){ + while (words.length < length) { do { word = wordList[Math.floor(Math.random() * wordList.length)]; } while (previousWord === word); diff --git a/src/core/operations/BlurImage.mjs b/src/core/operations/BlurImage.mjs index 8561f49d..c6f54421 100644 --- a/src/core/operations/BlurImage.mjs +++ b/src/core/operations/BlurImage.mjs @@ -64,7 +64,7 @@ class BlurImage extends Operation { throw new OperationError(`Error loading image. (${err})`); } try { - switch (blurType){ + switch (blurType) { case "Fast": if (isWorkerEnvironment()) self.sendStatusMessage("Fast blurring image..."); diff --git a/src/core/operations/DNSOverHTTPS.mjs b/src/core/operations/DNSOverHTTPS.mjs index b6e98250..ca779815 100644 --- a/src/core/operations/DNSOverHTTPS.mjs +++ b/src/core/operations/DNSOverHTTPS.mjs @@ -111,7 +111,7 @@ class DNSOverHTTPS extends Operation { * @returns {JSON} */ function extractData(data) { - if (typeof(data) == "undefined"){ + if (typeof(data) == "undefined") { return []; } else { const dataValues = []; diff --git a/src/core/operations/FlipImage.mjs b/src/core/operations/FlipImage.mjs index b04469ca..a6a262fc 100644 --- a/src/core/operations/FlipImage.mjs +++ b/src/core/operations/FlipImage.mjs @@ -58,7 +58,7 @@ class FlipImage extends Operation { try { if (isWorkerEnvironment()) self.sendStatusMessage("Flipping image..."); - switch (flipAxis){ + switch (flipAxis) { case "Horizontal": image.flip(true, false); break; diff --git a/src/core/operations/GenerateLoremIpsum.mjs b/src/core/operations/GenerateLoremIpsum.mjs index 50056b46..7bc636ac 100644 --- a/src/core/operations/GenerateLoremIpsum.mjs +++ b/src/core/operations/GenerateLoremIpsum.mjs @@ -47,7 +47,7 @@ class GenerateLoremIpsum extends Operation { */ run(input, args) { const [length, lengthType] = args; - if (length < 1){ + if (length < 1) { throw new OperationError("Length must be greater than 0"); } switch (lengthType) { diff --git a/src/core/operations/ImageFilter.mjs b/src/core/operations/ImageFilter.mjs index 8501ab34..95c89197 100644 --- a/src/core/operations/ImageFilter.mjs +++ b/src/core/operations/ImageFilter.mjs @@ -48,7 +48,7 @@ class ImageFilter extends Operation { */ async run(input, args) { const [filterType] = args; - if (!isImage(new Uint8Array(input))){ + if (!isImage(new Uint8Array(input))) { throw new OperationError("Invalid file type."); } diff --git a/src/core/operations/MicrosoftScriptDecoder.mjs b/src/core/operations/MicrosoftScriptDecoder.mjs index 460573b2..952a8788 100644 --- a/src/core/operations/MicrosoftScriptDecoder.mjs +++ b/src/core/operations/MicrosoftScriptDecoder.mjs @@ -34,7 +34,7 @@ class MicrosoftScriptDecoder extends Operation { run(input, args) { const matcher = /#@~\^.{6}==(.+).{6}==\^#~@/; const encodedData = matcher.exec(input); - if (encodedData){ + if (encodedData) { return MicrosoftScriptDecoder._decode(encodedData[1]); } else { return ""; diff --git a/src/core/operations/ParseColourCode.mjs b/src/core/operations/ParseColourCode.mjs index f24b1043..9cf40ba7 100644 --- a/src/core/operations/ParseColourCode.mjs +++ b/src/core/operations/ParseColourCode.mjs @@ -134,7 +134,7 @@ CMYK: ${cmyk} static _hslToRgb(h, s, l) { let r, g, b; - if (s === 0){ + if (s === 0) { r = g = b = l; // achromatic } else { const hue2rgb = function hue2rgb(p, q, t) { diff --git a/src/core/operations/SharpenImage.mjs b/src/core/operations/SharpenImage.mjs index 2ea8a122..338679c0 100644 --- a/src/core/operations/SharpenImage.mjs +++ b/src/core/operations/SharpenImage.mjs @@ -62,7 +62,7 @@ class SharpenImage extends Operation { async run(input, args) { const [radius, amount, threshold] = args; - if (!isImage(new Uint8Array(input))){ + if (!isImage(new Uint8Array(input))) { throw new OperationError("Invalid file type."); } diff --git a/src/core/operations/SwapEndianness.mjs b/src/core/operations/SwapEndianness.mjs index d0a7492b..872d3529 100644 --- a/src/core/operations/SwapEndianness.mjs +++ b/src/core/operations/SwapEndianness.mjs @@ -79,7 +79,7 @@ class SwapEndianness extends Operation { const word = data.slice(i, i + wordLength); // Pad word if too short - if (padIncompleteWords && word.length < wordLength){ + if (padIncompleteWords && word.length < wordLength) { for (j = word.length; j < wordLength; j++) { word.push(0); } diff --git a/src/core/operations/UNIXTimestampToWindowsFiletime.mjs b/src/core/operations/UNIXTimestampToWindowsFiletime.mjs index b93c881f..5a042885 100644 --- a/src/core/operations/UNIXTimestampToWindowsFiletime.mjs +++ b/src/core/operations/UNIXTimestampToWindowsFiletime.mjs @@ -51,7 +51,7 @@ class UNIXTimestampToWindowsFiletime extends Operation { input = new BigNumber(input); - if (units === "Seconds (s)"){ + if (units === "Seconds (s)") { input = input.multipliedBy(new BigNumber("10000000")); } else if (units === "Milliseconds (ms)") { input = input.multipliedBy(new BigNumber("10000")); @@ -65,7 +65,7 @@ class UNIXTimestampToWindowsFiletime extends Operation { input = input.plus(new BigNumber("116444736000000000")); - if (format === "Hex"){ + if (format === "Hex") { return input.toString(16); } else { return input.toFixed(); diff --git a/src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs b/src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs index 18542bee..57d1e477 100644 --- a/src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs +++ b/src/core/operations/WindowsFiletimeToUNIXTimestamp.mjs @@ -57,7 +57,7 @@ class WindowsFiletimeToUNIXTimestamp extends Operation { input = input.minus(new BigNumber("116444736000000000")); - if (units === "Seconds (s)"){ + if (units === "Seconds (s)") { input = input.dividedBy(new BigNumber("10000000")); } else if (units === "Milliseconds (ms)") { input = input.dividedBy(new BigNumber("10000")); diff --git a/src/node/api.mjs b/src/node/api.mjs index e136143c..f03d45b6 100644 --- a/src/node/api.mjs +++ b/src/node/api.mjs @@ -295,7 +295,7 @@ export function help(input) { * bake [Wrapped] - Perform an array of operations on some input. * @returns {Function} */ -export function bake(){ +export function bake() { /** * bake From 570a4c7fcab1bc25321c143c7a84accab62274fc Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 27 Aug 2019 18:30:33 +0100 Subject: [PATCH 24/32] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8914ea43..9ec9af1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ All major and minor version changes will be documented in this file. Details of - A [read-eval-print loop (REPL)](https://github.com/gchq/CyberChef/wiki/Node-API#repl) is also included to enable prototyping and experimentation with the API [@d98762625] | [#291] - Light and dark Solarized themes added [@j433866] | [#566] +
+ Click to expand v8 minor versions + ### [8.38.0] - 2019-07-03 - 'Streebog' and 'GOST hash' operations added [@MShwed] [@n1474335] | [#530] @@ -136,6 +139,8 @@ All major and minor version changes will be documented in this file. Details of ### [8.1.0] - 2018-08-19 - 'Dechunk HTTP response' operation added [@sevzero] | [#311] +
+ ## [8.0.0] - 2018-08-05 - Codebase rewritten using [ES modules](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/) and [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) [@n1474335] [@d98762625] [@artemisbot] [@picapi] | [#284] - Operation architecture restructured to make adding new operations a lot simpler [@n1474335] | [#284] From 6a6fe0f56dfe3558f1750bb8405fd080941d30ae Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 28 Aug 2019 15:47:33 +0100 Subject: [PATCH 25/32] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e90196e5..abb37d42 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ There are lots of opportunities to contribute to CyberChef. If you want ideas, t Before your contributions can be accepted, you must: - - Sign the [GCHQ Contributor Licence Agreement](https://github.com/gchq/Gaffer/wiki/GCHQ-OSS-Contributor-License-Agreement-V1.0) + - Sign the [GCHQ Contributor Licence Agreement](https://cla-assistant.io/gchq/CyberChef) - Push your changes to your fork. - Submit a pull request. @@ -25,9 +25,9 @@ Before your contributions can be accepted, you must: ## Design Principles 1. If at all possible, all operations and features should be client-side and not rely on connections to an external server. This increases the utility of CyberChef on closed networks and in virtual machines that are not connected to the Internet. Calls to external APIs may be accepted if there is no other option, but not for critical components. -2. Latency should be kept to a minimum to enhance the user experience. This means that all operation code should sit on the client, rather than being loaded dynamically from a server. -3. Use Vanilla JS if at all possible to reduce the number of libraries required and relied upon. Frameworks like jQuery, although included, should not be used unless absolutely necessary. -4. Minimise the use of large libraries, especially for niche operations that won't be used very often - these will be downloaded by everyone using the app, whether they use that operation or not (due to principal 2). +2. Latency should be kept to a minimum to enhance the user experience. This means that operation code should sit on the client and be executed there. However, as a trade-off between latency and bandwidth, operation code with large dependencies can be loaded in discrete modules in order to reduce the size of the initial download. The downloading of additional modules must remain entirely transparent so that the user is not inconvenienced. +3. Large libraries should be kept in separate modules so that they are not downloaded by everyone who uses the app, just those who specifically require the relevant operations. +4. Use Vanilla JS if at all possible to reduce the number of libraries required and relied upon. Frameworks like jQuery, although included, should not be used unless absolutely necessary. With these principles in mind, any changes or additions to CyberChef should keep it: From 4c28627459fd0cb7e77b18085120edc64bc38e8b Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 28 Aug 2019 16:14:13 +0100 Subject: [PATCH 26/32] Added pulse to Background Magic button to draw attention. --- src/web/App.mjs | 6 ++---- src/web/html/index.html | 2 +- src/web/stylesheets/layout/_io.css | 23 +++++++++++++++++++++++ src/web/stylesheets/layout/_structure.css | 4 +++- src/web/waiters/OutputWaiter.mjs | 2 ++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/web/App.mjs b/src/web/App.mjs index 60491ef4..606b2aff 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -633,7 +633,7 @@ class App { * Pops up a message to the user and writes it to the console log. * * @param {string} str - The message to display (HTML supported) - * @param {number} timeout - The number of milliseconds before the alert closes automatically + * @param {number} [timeout=0] - The number of milliseconds before the alert closes automatically * 0 for never (until the user closes it) * @param {boolean} [silent=false] - Don't show the message in the popup, only print it to the * console @@ -646,14 +646,12 @@ class App { * // Pops up a box with the message "Happy Christmas!" that will disappear after 5 seconds. * this.alert("Happy Christmas!", 5000); */ - alert(str, timeout, silent) { + alert(str, timeout=0, silent=false) { const time = new Date(); log.info("[" + time.toLocaleString() + "] " + str); if (silent) return; - timeout = timeout || 0; - this.currentSnackbar = $.snackbar({ content: str, timeout: timeout, diff --git a/src/web/html/index.html b/src/web/html/index.html index 13b06d61..419f726d 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -709,7 +709,7 @@

                                 
- Raise issue on GitHub + Raise issue on GitHub
What
diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index d7d628cb..2c8be70e 100755 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -337,6 +337,29 @@ fill: var(--primary-font-colour); } +.pulse { + box-shadow: 0 0 0 0 rgba(90, 153, 212, .3); + animation: pulse 1.5s 1; +} + +.pulse:hover { + animation-play-state: paused; +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + 70% { + transform: scale(1.1); + box-shadow: 0 0 0 20px rgba(90, 153, 212, 0); + } + 100% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(90, 153, 212, 0); + } +} + #input-find-options, #output-find-options { display: flex; diff --git a/src/web/stylesheets/layout/_structure.css b/src/web/stylesheets/layout/_structure.css index 77902d09..3eed5e2d 100755 --- a/src/web/stylesheets/layout/_structure.css +++ b/src/web/stylesheets/layout/_structure.css @@ -39,7 +39,9 @@ div#output { .split { box-sizing: border-box; - overflow: auto; + /* overflow: auto; + Removed to enable Background Magic button pulse to overflow. + Replace this rule if it seems to be causing problems. */ position: relative; } diff --git a/src/web/waiters/OutputWaiter.mjs b/src/web/waiters/OutputWaiter.mjs index 6bbe8f4a..4a08fe8d 100755 --- a/src/web/waiters/OutputWaiter.mjs +++ b/src/web/waiters/OutputWaiter.mjs @@ -1083,6 +1083,7 @@ class OutputWaiter { magicButton.setAttribute("data-original-title", `${opSequence} will produce "${Utils.escapeHtml(Utils.truncate(result), 30)}"`); magicButton.setAttribute("data-recipe", JSON.stringify(recipeConfig), null, ""); magicButton.classList.remove("hidden"); + magicButton.classList.add("pulse"); } @@ -1092,6 +1093,7 @@ class OutputWaiter { hideMagicButton() { const magicButton = document.getElementById("magic"); magicButton.classList.add("hidden"); + magicButton.classList.remove("pulse"); magicButton.setAttribute("data-recipe", ""); magicButton.setAttribute("data-original-title", "Magic!"); } From 686ca284fe8edc863ad257087628e89b0f0be4a2 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 28 Aug 2019 16:37:31 +0100 Subject: [PATCH 27/32] Removed JSDoc generation as it is never really used. JSDoc comments are still required but the doc files will no longer be generated. This simplifies the build process and config scripts. --- .gitignore | 3 - .npmignore | 1 - .travis.yml | 3 +- Gruntfile.js | 32 ---- docs/favicon.ico | Bin 1082 -> 0 bytes docs/jsdoc.conf.json | 32 ---- package-lock.json | 362 ------------------------------------------- package.json | 4 - 8 files changed, 1 insertion(+), 436 deletions(-) delete mode 100755 docs/favicon.ico delete mode 100755 docs/jsdoc.conf.json diff --git a/.gitignore b/.gitignore index 6c9f300a..e546c949 100755 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,6 @@ node_modules npm-debug.log travis.log build -docs/* -!docs/*.conf.json -!docs/*.ico .vscode .*.swp .DS_Store diff --git a/.npmignore b/.npmignore index 6f32ec06..05ab5f52 100755 --- a/.npmignore +++ b/.npmignore @@ -3,6 +3,5 @@ npm-debug.log travis.log build/* !build/node -docs .vscode .github diff --git a/.travis.yml b/.travis.yml index e99e3903..6996a5e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,9 @@ before_script: script: - grunt lint - grunt test - - grunt docs + - grunt testnodeconsumer - grunt prod --msg="$COMPILE_MSG" - xvfb-run --server-args="-screen 0 1200x800x24" grunt testui - - grunt testnodeconsumer before_deploy: - grunt exec:sitemap - grunt copy:ghPages diff --git a/Gruntfile.js b/Gruntfile.js index e228d785..3eb67068 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -52,17 +52,10 @@ module.exports = function (grunt) { "A task which checks whether consuming CJS and ESM apps work with the CyberChef build", ["exec:setupNodeConsumers", "exec:testCJSNodeConsumer", "exec:testESMNodeConsumer", "exec:testESMDeepImportNodeConsumer", "exec:teardownNodeConsumers"]); - grunt.registerTask("docs", - "Compiles documentation in the /docs directory.", - ["clean:docs", "jsdoc", "chmod:docs"]); - - grunt.registerTask("default", "Lints the code base", ["eslint", "exec:repoSize"]); - - grunt.registerTask("doc", "docs"); grunt.registerTask("tests", "test"); grunt.registerTask("lint", "eslint"); @@ -70,7 +63,6 @@ module.exports = function (grunt) { // Load tasks provided by each plugin grunt.loadNpmTasks("grunt-eslint"); grunt.loadNpmTasks("grunt-webpack"); - grunt.loadNpmTasks("grunt-jsdoc"); grunt.loadNpmTasks("grunt-contrib-clean"); grunt.loadNpmTasks("grunt-contrib-copy"); grunt.loadNpmTasks("grunt-contrib-watch"); @@ -117,7 +109,6 @@ module.exports = function (grunt) { node: ["build/node/*"], config: ["src/core/config/OperationConfig.json", "src/core/config/modules/*", "src/code/operations/index.mjs"], nodeConfig: ["src/node/index.mjs", "src/node/config/OperationConfig.json"], - docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico", "!docs/*.png"], standalone: ["build/prod/CyberChef*.html"] }, eslint: { @@ -130,22 +121,6 @@ module.exports = function (grunt) { node: ["src/node/**/*.{js,mjs}"], tests: ["tests/**/*.{js,mjs}"], }, - jsdoc: { - options: { - destination: "docs", - template: "node_modules/ink-docstrap/template", - recurse: true, - readme: "./README.md", - configure: "docs/jsdoc.conf.json" - }, - all: { - src: [ - "src/**/*.js", - "src/**/*.mjs", - "!src/core/vendor/**/*" - ], - } - }, accessibility: { options: { accessibilityLevel: "WCAG2A", @@ -298,7 +273,6 @@ module.exports = function (grunt) { }, { expand: true, - src: "docs/**", dest: "build/prod/" }, ] @@ -332,12 +306,6 @@ module.exports = function (grunt) { mode: "755", }, src: ["build/**/*", "build/"] - }, - docs: { - options: { - mode: "755", - }, - src: ["docs/**/*", "docs/"] } }, watch: { diff --git a/docs/favicon.ico b/docs/favicon.ico deleted file mode 100755 index fa2deb032ee0845745e495fb77de2fab56e2871a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1082 zcma)5ORG{*6yAc+AmZLTC;}mZBAV2oKTs&*K)KECK$?g-5Ct77+Cv0i;R8h_5fLv0 zJ_b5a2dQMD-h84?ZxG^Z(k!Tm&Tg%9^{{bb`|zFpopbiL_FC)PhY%55$43P2cgcM* zA-4!24*|!3I{EZdclDHl@Si zICZ<-XF8qk39DgwEEfAXolfawGT|{EkGX6%OACd90E@*EW;HDL`Fxpfw@W*n4v%)b z%_R~EnoK4I==J(HtcK;qV)0_L+0fN$#bdc#a{Ydv4u?Y?qtS>)qtSC#!}3z8)LpOF zf_|}BaJ^oS4h91r7$+PKXHcWjXuvT-#9}eo^*)!&T^!Owj+d!a>O7y%_q1BA1Y_WU zygtn5b760+VSoQ!9yr%(wLeCq@eyh>nat~L-5k^`#K8L5{8@dqTK($x`(McA^6Sv^ z&%2&6Gan1|9IM-MzOU$&TCKkE1qP%0ul-xC*3Wc0-G=l<<#PEw_6_r8Ka8VBqcLZ_$2j|X%)Qxc{;gChzv}h+Z#YYj6$-^w1h{*>-k0FZyLdeQ zYBrmF$6lfa>jZBvK|`HRXB3v67z~DIJE24(*tmN|OeWL4NF-tn27^hf)p{nCN^ip1 nc>tcD2#bK=Z;SYL4FD&KpOK3Q`LxAbSjS`g`~$vI_zV64z;+{# diff --git a/docs/jsdoc.conf.json b/docs/jsdoc.conf.json deleted file mode 100755 index 36e9611b..00000000 --- a/docs/jsdoc.conf.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "tags": { - "allowUnknownTags": true - }, - "plugins": [ - "plugins/markdown", - "node_modules/jsdoc-babel" - ], - "templates": { - "systemName": "CyberChef", - "footer": "", - "copyright": "© Crown Copyright 2017", - "navType": "inline", - "theme": "cerulean", - "linenums": true, - "collapseSymbols": false, - "inverseNav": true, - "outputSourceFiles": true, - "outputSourcePath": true, - "dateFormat": "ddd MMM Do YYYY", - "sort": false, - "logoFile": "cyberchef-32x32.png", - "cleverLinks": false, - "monospaceLinks": false, - "protocol": "html://", - "methodHeadingReturns": false - }, - "markdown": { - "parser": "gfm", - "hardwrap": true - } -} diff --git a/package-lock.json b/package-lock.json index f5669cc1..717711fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4623,15 +4623,6 @@ "webidl-conversions": "^4.0.2" } }, - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, "domutils": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", @@ -7216,16 +7207,6 @@ "integrity": "sha512-cgAlreXf3muSYS5LzW0Cc4xHK03BjFOYk0MqCQ/MZ3k1Xz2GU7D+IAJg4UKicxpO+XdONJdx/NJ6kpy2wI+uHg==", "dev": true }, - "grunt-jsdoc": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.4.0.tgz", - "integrity": "sha512-JpZd1W7HbK0sHbpiL9+VyDFwZlkYoDQMaP+v6z1R23W/NYLoqJM76L9eBOr7O6NycqtddRHN5DzlSkW45MJ82w==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.5", - "jsdoc": "~3.6.0" - } - }, "grunt-known-options": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", @@ -8000,16 +7981,6 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "ink-docstrap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/ink-docstrap/-/ink-docstrap-1.3.2.tgz", - "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==", - "dev": true, - "requires": { - "moment": "^2.14.1", - "sanitize-html": "^1.13.0" - } - }, "inquirer": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz", @@ -8510,106 +8481,6 @@ "esprima": "^4.0.0" } }, - "js2xmlparser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz", - "integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==", - "dev": true, - "requires": { - "xmlcreate": "^2.0.0" - } - }, - "jsdoc": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.3.tgz", - "integrity": "sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A==", - "dev": true, - "requires": { - "@babel/parser": "^7.4.4", - "bluebird": "^3.5.4", - "catharsis": "^0.8.11", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.0", - "klaw": "^3.0.0", - "markdown-it": "^8.4.2", - "markdown-it-anchor": "^5.0.2", - "marked": "^0.7.0", - "mkdirp": "^0.5.1", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.0.1", - "taffydb": "2.6.2", - "underscore": "~1.9.1" - }, - "dependencies": { - "catharsis": { - "version": "0.8.11", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", - "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, - "requizzle": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", - "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", - "dev": true - } - } - }, - "jsdoc-babel": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.5.0.tgz", - "integrity": "sha512-PYfTbc3LNTeR8TpZs2M94NLDWqARq0r9gx3SvuziJfmJS7/AeMKvtj0xjzOX0R/4MOVA7/FqQQK7d6U0iEoztQ==", - "dev": true, - "requires": { - "jsdoc-regex": "^1.0.1", - "lodash": "^4.17.10" - } - }, - "jsdoc-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz", - "integrity": "sha1-hCRCjVtWOtjFx/vsB5uaiwnI3Po=", - "dev": true - }, "jsdom": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", @@ -8915,15 +8786,6 @@ "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-0.0.12.tgz", "integrity": "sha512-AjTe4FiBuH4F7HwGT/3UxoRenczXtrbM6oWGrifxb44LrkDh5VxRNg9zwfPpDA5Fcc1iYcXS0WVA/b3DGtD8cQ==" }, - "linkify-it": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz", - "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, "livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", @@ -9096,24 +8958,12 @@ "lodash._isiterateecall": "^3.0.0" } }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "lodash.defaultsdeep": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", "dev": true }, - "lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", - "dev": true - }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -9179,12 +9029,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true - }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -9297,33 +9141,6 @@ "object-visit": "^1.0.0" } }, - "markdown-it": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", - "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~1.1.1", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } - } - }, - "markdown-it-anchor": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.4.tgz", - "integrity": "sha512-n8zCGjxA3T+Mx1pG8HEgbJbkB8JFUuRkeTZQuIM8iPY6oQ8sWOPRZJDFC9a/pNg2QkHEjjGkhBEl/RSyzaDZ3A==", - "dev": true - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -9335,12 +9152,6 @@ "safe-buffer": "^5.1.2" } }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -12127,151 +11938,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sanitize-html": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.20.1.tgz", - "integrity": "sha512-txnH8TQjaQvg2Q0HY06G6CDJLVYCpbnxrdO0WN8gjCKaU5J0KbyGYhZxx5QJg3WLZ1lB7XU9kDkfrCXUozqptA==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "htmlparser2": "^3.10.0", - "lodash.clonedeep": "^4.5.0", - "lodash.escaperegexp": "^4.1.2", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.mergewith": "^4.6.1", - "postcss": "^7.0.5", - "srcset": "^1.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "domelementtype": { - "version": "1.3.0", - "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", - "dev": true - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "htmlparser2": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz", - "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.0", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.0.6" - } - }, - "postcss": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", - "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "readable-stream": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz", - "integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "sass-graph": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", @@ -13014,16 +12680,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "srcset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz", - "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=", - "dev": true, - "requires": { - "array-uniq": "^1.0.2", - "number-is-nan": "^1.0.0" - } - }, "ssdeep.js": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/ssdeep.js/-/ssdeep.js-0.0.2.tgz", @@ -13485,12 +13141,6 @@ } } }, - "taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", - "dev": true - }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -13946,12 +13596,6 @@ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==" }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, "uglify-js": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", @@ -14973,12 +14617,6 @@ } } }, - "xmlcreate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz", - "integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==", - "dev": true - }, "xmldom": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", diff --git a/package.json b/package.json index c6da7887..66e4557e 100644 --- a/package.json +++ b/package.json @@ -60,13 +60,10 @@ "grunt-contrib-watch": "^1.1.0", "grunt-eslint": "^22.0.0", "grunt-exec": "~3.0.0", - "grunt-jsdoc": "^2.4.0", "grunt-webpack": "^3.1.3", "grunt-zip": "^0.18.2", "html-webpack-plugin": "^3.2.0", "imports-loader": "^0.8.0", - "ink-docstrap": "^1.3.2", - "jsdoc-babel": "^0.5.0", "mini-css-extract-plugin": "^0.7.0", "nightwatch": "^1.1.13", "node-sass": "^4.12.0", @@ -161,7 +158,6 @@ "test": "grunt test", "test-node-consumer": "grunt testnodeconsumer", "testui": "grunt testui", - "docs": "grunt docs", "lint": "grunt lint", "newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs" } From c9deaae744625e76d62c7a3829fb9c942e29aba9 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 28 Aug 2019 17:14:12 +0100 Subject: [PATCH 28/32] Updated supported browser versions. --- README.md | 6 +++--- package.json | 7 +++---- src/web/html/index.html | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c0996378..d79c99a9 100755 --- a/README.md +++ b/README.md @@ -76,9 +76,9 @@ You can use as many operations as you like in simple or complex ways. Some examp CyberChef is built to support - - Google Chrome 40+ - - Mozilla Firefox 35+ - - Microsoft Edge 14+ + - Google Chrome 50+ + - Mozilla Firefox 38+ + ## Node.js support diff --git a/package.json b/package.json index 66e4557e..b19dd8bc 100644 --- a/package.json +++ b/package.json @@ -31,10 +31,9 @@ "module": "src/node/index.mjs", "bugs": "https://github.com/gchq/CyberChef/issues", "browserslist": [ - "Chrome >= 40", - "Firefox >= 35", - "Edge >= 14", - "node >= 6.5" + "Chrome >= 50", + "Firefox >= 38", + "node >= 10" ], "devDependencies": { "@babel/core": "^7.5.0", diff --git a/src/web/html/index.html b/src/web/html/index.html index 419f726d..4063e138 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -123,9 +123,9 @@ document.getElementById("preloader-error").innerHTML = "CyberChef encountered an error while loading.

" + "The following browser versions are supported:" + - "
  • Google Chrome 40+
  • Mozilla Firefox 35+
  • Microsoft Edge 14+
" + + "
  • Google Chrome 50+
  • Mozilla Firefox 38+
" + "Your user agent is:
" + escapeHtml(navigator.userAgent) + "

" + - "If your browser is supported, please " + + "If your browser is supported, please " + "raise an issue including the following details:

" + "
" + escapeHtml(msg) + "
"; }; From 4f2749e0dc96796e08991ba041abf05a1f2b728c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 28 Aug 2019 17:14:20 +0100 Subject: [PATCH 29/32] 9.2.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 717711fa..b93afa6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.2.1", + "version": "9.2.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b19dd8bc..b40a0180 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.2.1", + "version": "9.2.2", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 2f0b959aa4e8ed3d2c07062106e7f192347305de Mon Sep 17 00:00:00 2001 From: n1474335 Date: Wed, 28 Aug 2019 18:48:31 +0100 Subject: [PATCH 30/32] Fixed copy:ghPages docs error --- Gruntfile.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 3eb67068..cd4c998e 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -270,11 +270,7 @@ module.exports = function (grunt) { { src: "build/prod/index.html", dest: "build/prod/index.html" - }, - { - expand: true, - dest: "build/prod/" - }, + } ] }, standalone: { From 59917cca458f21ea40c374055f1c931918a833ae Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 29 Aug 2019 10:18:52 +0100 Subject: [PATCH 31/32] Add overflow CSS rule to fix scrolling. Fixes #626 --- src/web/stylesheets/layout/_structure.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/web/stylesheets/layout/_structure.css b/src/web/stylesheets/layout/_structure.css index 3eed5e2d..62ea1f9d 100755 --- a/src/web/stylesheets/layout/_structure.css +++ b/src/web/stylesheets/layout/_structure.css @@ -45,6 +45,10 @@ div#output { position: relative; } +#operations { + overflow: auto; +} + .split.split-horizontal, .gutter.gutter-horizontal { height: 100%; float: left; From 6992858e675703863f76c9b404a7b2110f633bbf Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 29 Aug 2019 10:23:41 +0100 Subject: [PATCH 32/32] 9.2.3 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b93afa6f..7812c3d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.2.2", + "version": "9.2.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b40a0180..fddf38f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.2.2", + "version": "9.2.3", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef",