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 {fromDecimal} from "./lib/Decimal.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.
|
||||
@ -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.
|
||||
* Accepts hex, Base64, UTF8 and Latin1 strings.
|
||||
@ -383,7 +340,6 @@ class Utils {
|
||||
* Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
|
||||
*/
|
||||
static convertToByteArray(str, type) {
|
||||
Utils.validateFormatInput(str, type);
|
||||
switch (type.toLowerCase()) {
|
||||
case "binary":
|
||||
return fromBinary(str);
|
||||
@ -421,7 +377,6 @@ class Utils {
|
||||
* Utils.convertToByteString("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
|
||||
*/
|
||||
static convertToByteString(str, type) {
|
||||
Utils.validateFormatInput(str, type);
|
||||
switch (type.toLowerCase()) {
|
||||
case "binary":
|
||||
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
|
||||
* hex delimiter conventions (commas, spaces, 0x prefix, etc.) before parsing.
|
||||
@ -100,7 +142,7 @@ export const format = {
|
||||
* @returns {CryptoJS.lib.WordArray}
|
||||
*/
|
||||
export function parseFormatString(str, formatName) {
|
||||
Utils.validateFormatInput(str, formatName);
|
||||
validateFormatInput(str, formatName);
|
||||
if (formatName === "Hex") {
|
||||
return CryptoJS.enc.Hex.parse(toHexFast(fromHex(str)));
|
||||
}
|
||||
|
||||
@ -658,7 +658,7 @@ WWFkYSBZYWRh\r
|
||||
}),
|
||||
|
||||
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", () => {
|
||||
@ -882,8 +882,8 @@ pCGTErs=
|
||||
|
||||
it("Scrypt", () => {
|
||||
assert.strictEqual(
|
||||
chef.scrypt("Playing For Keeps", {salt: {string: "salty", option: "UTF8"}}).toString(),
|
||||
"2f1417e682a7bf008c60abf8e8b8dc33bde9eead9290f9f03d83a8acb49392cfd22ad1425db88f821c67f06a12bb203ccdd47ca5109b8364451d6ebf2215bbdf");
|
||||
chef.scrypt("Playing For Keeps", {salt: {string: "salty", option: "Hex"}}).toString(),
|
||||
"5446b6d86d88515894a163201765bceed0bc39610b1506cdc4d939ffc638bc46e051bce756e2865165d89d955a43a7eb5504502567dea8bfc9e7d49aaa894c07");
|
||||
}),
|
||||
|
||||
it("SHA3", () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user