refactor(validation): update isValidSearch to prevent command injection

- Enhanced the isValidSearch function to restrict allowed characters to alphanumeric, space, dot, underscore, and hyphen, preventing command injection vulnerabilities.
- Updated unit tests to reflect the new validation rules and ensure comprehensive coverage against potential injection attacks.
This commit is contained in:
Mauricio Siu
2026-02-17 18:17:39 -06:00
parent 33c3a4ed4e
commit 9880c71dba
2 changed files with 20 additions and 9 deletions

View File

@@ -73,10 +73,11 @@ describe("isValidSearch (docker-container-logs)", () => {
expect(isValidSearch("")).toBe(true);
});
it("accepts safe printable ASCII", () => {
it("accepts only alphanumeric, space, dot, underscore, hyphen", () => {
expect(isValidSearch("error")).toBe(true);
expect(isValidSearch("foo bar")).toBe(true);
expect(isValidSearch("a-zA-Z0-9_.-")).toBe(true);
expect(isValidSearch("")).toBe(true);
});
it("rejects strings longer than 500 chars", () => {
@@ -91,10 +92,20 @@ describe("isValidSearch (docker-container-logs)", () => {
expect(isValidSearch("a\x19b")).toBe(false);
});
it("search is only used in Node (filter) or escaped for SSH; printable ASCII is allowed", () => {
// search is never concatenated into shell unescaped: local path filters in Node, SSH escapes
expect(isValidSearch("error")).toBe(true);
expect(isValidSearch("foo bar")).toBe(true);
it("rejects command injection vectors in search (search is concatenated into shell)", () => {
// Double-quoted context (SSH line 99): $ and ` execute
expect(isValidSearch("$(whoami)")).toBe(false);
expect(isValidSearch("`id`")).toBe(false);
expect(isValidSearch("$(id)")).toBe(false);
// Single-quoted context (local line 153): ' breaks out
expect(isValidSearch("'$(whoami)'")).toBe(false);
expect(isValidSearch("error'")).toBe(false);
expect(isValidSearch("'; whoami; #")).toBe(false);
// Other shell-metacharacters
expect(isValidSearch("error; id")).toBe(false);
expect(isValidSearch("a|b")).toBe(false);
expect(isValidSearch('error"')).toBe(false);
expect(isValidSearch("a&b")).toBe(false);
});
});

View File

@@ -37,13 +37,13 @@ export const isValidSince = (since: string): boolean => {
/**
* Validates the `search` parameter for log filtering.
* Allows only safe printable characters to prevent injection when filtering in Node.
* Search is concatenated into shell commands (SSH path: double quotes; local path: single quotes).
* Only allow alphanumeric, space, dot, underscore, hyphen to prevent $, `, ', " from enabling command injection.
* Max length 500.
*/
export const isValidSearch = (search: string): boolean => {
return /^[\x20-\x21\x23-\x25\x27-\x28\x2A-\x3A\x3D\x3F-\x5B\x5D-\x7B\x7D-\x7E]{0,500}$/.test(
search,
);
// Space only (not \s) to reject \n, \r, \t and other control chars
return /^[a-zA-Z0-9 ._-]{0,500}$/.test(search);
};
/**