Skip to content

Commit

Permalink
Add max depth and array size
Browse files Browse the repository at this point in the history
  • Loading branch information
timokoessler committed Dec 9, 2024
1 parent 3cec1c7 commit 275f247
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 deletions.
27 changes: 27 additions & 0 deletions library/helpers/attackPath.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,30 @@ t.test("set max count", async (t) => {

t.same(get("test", testArr, 5), [".[0]", ".[1]", ".[2]", ".[3]", ".[4]"]);
});

t.test("respects max depth and array length", async (t) => {
const generateTestObjectWithDepth = (depth: number): object | string => {
if (depth === 0) {
return "testValue";
}

const obj = {
prop: generateTestObjectWithDepth(depth - 1),
};

return obj;
};

t.same(get("testValue", generateTestObjectWithDepth(100)), []);
t.same(get("testValue", generateTestObjectWithDepth(31)), []);
t.same(get("testValue", generateTestObjectWithDepth(30)), [
".prop".repeat(30),
]);

const testArr = Array.from({ length: 101 }, (_, i) => i.toString());

t.same(get("50", testArr), [".[50]"]);
t.same(get("99", testArr), [".[99]"]);
t.same(get("100", testArr), [".[100]"]);
t.same(get("101", testArr), []);
});
25 changes: 19 additions & 6 deletions library/helpers/attackPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { tryDecodeAsJWT } from "./tryDecodeAsJWT";
// Default match count to return
const DEFAULT_MATCH_COUNT = 1;

// Maximum depth to traverse
const MAX_DEPTH = 30;

// Maximum array length to traverse
const MAX_ARRAY_LENGTH = 100;

export type PathPart =
| { type: "jwt" }
| { type: "object"; key: string }
Expand Down Expand Up @@ -40,11 +46,15 @@ export function getPathsToPayload(

const attackPayloadLowercase = attackPayload.toLowerCase();

const traverse = (value: unknown, path: PathPart[] = []) => {
const traverse = (value: unknown, path: PathPart[] = [], depth = 0) => {
if (matches.length >= matchCount) {
return;
}

if (depth > MAX_DEPTH) {
return;
}

// Handle strings
if (typeof value === "string") {
if (value.toLowerCase() === attackPayloadLowercase) {
Expand All @@ -54,17 +64,20 @@ export function getPathsToPayload(

const jwt = tryDecodeAsJWT(value);
if (jwt.jwt) {
traverse(jwt.object, path.concat({ type: "jwt" }));
traverse(jwt.object, path.concat({ type: "jwt" }), depth + 1);
}

return;
}

if (Array.isArray(value)) {
// Handle arrays
value.forEach((item, index) => {
traverse(item, path.concat({ type: "array", index }));
});
for (const [index, item] of value.entries()) {
if (index > MAX_ARRAY_LENGTH) {
break;
}

Check warning on line 78 in library/helpers/attackPath.ts

View check run for this annotation

Codecov / codecov/patch

library/helpers/attackPath.ts#L77-L78

Added lines #L77 - L78 were not covered by tests
traverse(item, path.concat({ type: "array", index }), depth + 1);
}

if (value.join().toLowerCase() === attackPayloadLowercase) {
matches.push(buildPathToPayload(path));
Expand All @@ -76,7 +89,7 @@ export function getPathsToPayload(
if (isPlainObject(value)) {
// Handle objects
for (const key in value) {
traverse(value[key], path.concat({ type: "object", key }));
traverse(value[key], path.concat({ type: "object", key }), depth + 1);
}
}
};
Expand Down

0 comments on commit 275f247

Please sign in to comment.