Narrow hex/base64/binary format validation to RC4/RC4Drop only
Move validateFormatInput() out of Utils.convertToByteArray()/convertToByteString(), which are shared by ~50 operations, and into Ciphers.mjs where it's only reachable via parseFormatString() (used by RC4/RC4Drop). This keeps the fix scoped to issue #2004 instead of changing accepted input globally, and avoids the unrelated HMAC/Scrypt regressions the broader validation caused. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
8882a481e7
commit
075d84ef43
@ -11,7 +11,6 @@ import {fromBase64, toBase64} from "./lib/Base64.mjs";
|
|||||||
import {fromHex} from "./lib/Hex.mjs";
|
import {fromHex} from "./lib/Hex.mjs";
|
||||||
import {fromDecimal} from "./lib/Decimal.mjs";
|
import {fromDecimal} from "./lib/Decimal.mjs";
|
||||||
import {fromBinary} from "./lib/Binary.mjs";
|
import {fromBinary} from "./lib/Binary.mjs";
|
||||||
import OperationError from "./errors/OperationError.mjs";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility functions for use in operations, the core framework and the stage.
|
* Utility functions for use in operations, the core framework and the stage.
|
||||||
@ -322,48 +321,6 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates that a string contains only characters valid for the given format type.
|
|
||||||
* Recognised delimiters (spaces, commas, colons, 0x prefix, etc.) are always
|
|
||||||
* permitted in Hex and Binary formats.
|
|
||||||
* Throws an OperationError if genuinely invalid characters are found.
|
|
||||||
*
|
|
||||||
* @param {string} str
|
|
||||||
* @param {string} type - One of "Hex", "Base64", "Binary", "UTF8", "Latin1", etc.
|
|
||||||
* @throws {OperationError}
|
|
||||||
*/
|
|
||||||
static validateFormatInput(str, type) {
|
|
||||||
if (!str) return;
|
|
||||||
switch (type.toLowerCase()) {
|
|
||||||
case "hex": {
|
|
||||||
const stripped = str.replace(/0x|\\x|%|[\s,;:\n\r]/gi, "");
|
|
||||||
const invalid = stripped.match(/[^0-9a-fA-F]/);
|
|
||||||
if (invalid) throw new OperationError(
|
|
||||||
`Invalid character '${invalid[0]}' in Hex input. ` +
|
|
||||||
`Hex accepts 0-9, a-f, A-F, and delimiters (space, comma, colon, 0x prefix).`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "base64": {
|
|
||||||
const invalid = str.replace(/[\s]/g, "").match(/[^A-Za-z0-9+/=]/);
|
|
||||||
if (invalid) throw new OperationError(
|
|
||||||
`Invalid character '${invalid[0]}' in Base64 input. ` +
|
|
||||||
`Base64 accepts A-Z, a-z, 0-9, +, /, and = (padding).`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "binary": {
|
|
||||||
const stripped = str.replace(/[\s,;:\n\r]/g, "");
|
|
||||||
const invalid = stripped.match(/[^01]/);
|
|
||||||
if (invalid) throw new OperationError(
|
|
||||||
`Invalid character '${invalid[0]}' in Binary input. Binary accepts only 0 and 1.`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coverts data of varying types to a byteArray.
|
* Coverts data of varying types to a byteArray.
|
||||||
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
||||||
@ -383,7 +340,6 @@ class Utils {
|
|||||||
* Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
|
* Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
|
||||||
*/
|
*/
|
||||||
static convertToByteArray(str, type) {
|
static convertToByteArray(str, type) {
|
||||||
Utils.validateFormatInput(str, type);
|
|
||||||
switch (type.toLowerCase()) {
|
switch (type.toLowerCase()) {
|
||||||
case "binary":
|
case "binary":
|
||||||
return fromBinary(str);
|
return fromBinary(str);
|
||||||
@ -421,7 +377,6 @@ class Utils {
|
|||||||
* Utils.convertToByteString("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
|
* Utils.convertToByteString("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
|
||||||
*/
|
*/
|
||||||
static convertToByteString(str, type) {
|
static convertToByteString(str, type) {
|
||||||
Utils.validateFormatInput(str, type);
|
|
||||||
switch (type.toLowerCase()) {
|
switch (type.toLowerCase()) {
|
||||||
case "binary":
|
case "binary":
|
||||||
return Utils.byteArrayToChars(fromBinary(str));
|
return Utils.byteArrayToChars(fromBinary(str));
|
||||||
|
|||||||
@ -89,6 +89,48 @@ export const format = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that a passphrase/key string contains only characters valid for the
|
||||||
|
* given format. Recognised delimiters (spaces, commas, colons, 0x prefix, etc.)
|
||||||
|
* are always permitted in Hex and Binary formats.
|
||||||
|
* Throws an OperationError if genuinely invalid characters are found.
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @param {string} type - One of "Hex", "Base64", "Binary", "UTF8", "Latin1", etc.
|
||||||
|
* @throws {OperationError}
|
||||||
|
*/
|
||||||
|
function validateFormatInput(str, type) {
|
||||||
|
if (!str) return;
|
||||||
|
switch (type.toLowerCase()) {
|
||||||
|
case "hex": {
|
||||||
|
const stripped = str.replace(/0x|\\x|%|[\s,;:\n\r]/gi, "");
|
||||||
|
const invalid = stripped.match(/[^0-9a-fA-F]/);
|
||||||
|
if (invalid) throw new OperationError(
|
||||||
|
`Invalid character '${invalid[0]}' in Hex input. ` +
|
||||||
|
`Hex accepts 0-9, a-f, A-F, and delimiters (space, comma, colon, 0x prefix).`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "base64": {
|
||||||
|
const invalid = str.replace(/[\s]/g, "").match(/[^A-Za-z0-9+/=]/);
|
||||||
|
if (invalid) throw new OperationError(
|
||||||
|
`Invalid character '${invalid[0]}' in Base64 input. ` +
|
||||||
|
`Base64 accepts A-Z, a-z, 0-9, +, /, and = (padding).`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "binary": {
|
||||||
|
const stripped = str.replace(/[\s,;:\n\r]/g, "");
|
||||||
|
const invalid = stripped.match(/[^01]/);
|
||||||
|
if (invalid) throw new OperationError(
|
||||||
|
`Invalid character '${invalid[0]}' in Binary input. Binary accepts only 0 and 1.`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a user-entered string in a given CryptoJS format, normalising common
|
* Parses a user-entered string in a given CryptoJS format, normalising common
|
||||||
* hex delimiter conventions (commas, spaces, 0x prefix, etc.) before parsing.
|
* hex delimiter conventions (commas, spaces, 0x prefix, etc.) before parsing.
|
||||||
@ -100,7 +142,7 @@ export const format = {
|
|||||||
* @returns {CryptoJS.lib.WordArray}
|
* @returns {CryptoJS.lib.WordArray}
|
||||||
*/
|
*/
|
||||||
export function parseFormatString(str, formatName) {
|
export function parseFormatString(str, formatName) {
|
||||||
Utils.validateFormatInput(str, formatName);
|
validateFormatInput(str, formatName);
|
||||||
if (formatName === "Hex") {
|
if (formatName === "Hex") {
|
||||||
return CryptoJS.enc.Hex.parse(toHexFast(fromHex(str)));
|
return CryptoJS.enc.Hex.parse(toHexFast(fromHex(str)));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -658,7 +658,7 @@ WWFkYSBZYWRh\r
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
it("HMAC", () => {
|
it("HMAC", () => {
|
||||||
assert.strictEqual(chef.HMAC("On Cloud Nine", {key: {string: "idea", option: "Latin1"}}).toString(), "b128b48ec0d6b0f1a27220c396d0f3e5");
|
assert.strictEqual(chef.HMAC("On Cloud Nine", {key: "idea"}).toString(), "e15c268b4ee755c9e52db094ed50add7");
|
||||||
}),
|
}),
|
||||||
|
|
||||||
it("JPathExpression", () => {
|
it("JPathExpression", () => {
|
||||||
@ -882,8 +882,8 @@ pCGTErs=
|
|||||||
|
|
||||||
it("Scrypt", () => {
|
it("Scrypt", () => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
chef.scrypt("Playing For Keeps", {salt: {string: "salty", option: "UTF8"}}).toString(),
|
chef.scrypt("Playing For Keeps", {salt: {string: "salty", option: "Hex"}}).toString(),
|
||||||
"2f1417e682a7bf008c60abf8e8b8dc33bde9eead9290f9f03d83a8acb49392cfd22ad1425db88f821c67f06a12bb203ccdd47ca5109b8364451d6ebf2215bbdf");
|
"5446b6d86d88515894a163201765bceed0bc39610b1506cdc4d939ffc638bc46e051bce756e2865165d89d955a43a7eb5504502567dea8bfc9e7d49aaa894c07");
|
||||||
}),
|
}),
|
||||||
|
|
||||||
it("SHA3", () => {
|
it("SHA3", () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user