Skip to content

Commit

Permalink
Rename helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
hansott committed Feb 27, 2024
1 parent 9dc4bce commit c093d02
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 85 deletions.
20 changes: 0 additions & 20 deletions library/src/agent/Context.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { AsyncLocalStorage } from "node:async_hooks";
import type { ParsedQs } from "qs";

/**
* @prop url This is the URL where the (express) request came in
* @prop method This is the HTTP Method used for the (express) request
* @prop query These are the URL Query parameters (e.g. example.com?param1=value1)
* @prop headers The HTTP headers accompanying the request
* @prop remoteAddress The remote address of the end-user
* @prop body This is the (form) body that possible accompanies the request
* @prop cookies These are the cookies accompanying the request
* @interface
*/
export type Context = {
url: string | undefined;
method: string;
Expand All @@ -23,20 +13,10 @@ export type Context = {

const requestContext = new AsyncLocalStorage<Context>();

/**
* This function gives you the {@link Context} stored in asynchronous local storage
* @returns the stored context in asynchronous local storage
*/
export function getContext() {
return requestContext.getStore();
}

/**
*
* @param context The context you want to set ({@link Context})
* @param fn
* @returns
*/
export function runWithContext<T>(context: Context, fn: () => T) {
return requestContext.run(context, fn);
}
27 changes: 0 additions & 27 deletions library/src/helpers/extractStringsFromContext.test.ts

This file was deleted.

19 changes: 0 additions & 19 deletions library/src/helpers/extractStringsFromContext.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
/* eslint-disable camelcase */
import * as t from "tap";
import { extractStringsFromObject } from "./extractStringsFromObject";
import { extractStringsFromUserInput } from "./extractStringsFromUserInput";

t.test("empty object returns empty array", async () => {
t.same(extractStringsFromObject({}), []);
t.same(extractStringsFromUserInput({}), []);
});

t.test("it can extract query objects", async () => {
t.same(extractStringsFromObject({ age: { $gt: "21" } }), [
t.same(extractStringsFromUserInput({ age: { $gt: "21" } }), [
"age",
"$gt",
"21",
]);
t.same(extractStringsFromObject({ title: { $ne: "null" } }), [
t.same(extractStringsFromUserInput({ title: { $ne: "null" } }), [
"title",
"$ne",
"null",
]);
t.same(
extractStringsFromObject({
extractStringsFromUserInput({
age: "whaat",
user_input: ["whaat", "dangerous"],
}),
Expand All @@ -27,13 +27,13 @@ t.test("it can extract query objects", async () => {
});

t.test("it can extract cookie objects", async () => {
t.same(extractStringsFromObject({ session: "ABC", session2: "DEF" }), [
t.same(extractStringsFromUserInput({ session: "ABC", session2: "DEF" }), [
"session2",
"session",
"ABC",
"DEF",
]);
t.same(extractStringsFromObject({ session: "ABC", session2: 1234 }), [
t.same(extractStringsFromUserInput({ session: "ABC", session2: 1234 }), [
"session2",
"session",
"ABC",
Expand All @@ -42,19 +42,19 @@ t.test("it can extract cookie objects", async () => {

t.test("it can extract header objects", async () => {
t.same(
extractStringsFromObject({
extractStringsFromUserInput({
"Content-Type": "application/json",
}),
["Content-Type", "application/json"]
);
t.same(
extractStringsFromObject({
extractStringsFromUserInput({
"Content-Type": 54321,
}),
["Content-Type"]
);
t.notSame(
extractStringsFromObject({
extractStringsFromUserInput({
"Content-Type": "application/json",
ExtraHeader: "value",
}),
Expand All @@ -63,12 +63,12 @@ t.test("it can extract header objects", async () => {
});

t.test("it can extract body objects", async () => {
t.same(extractStringsFromObject({ nested: { nested: { $ne: null } } }), [
t.same(extractStringsFromUserInput({ nested: { nested: { $ne: null } } }), [
"nested",
"$ne",
]);

t.same(extractStringsFromObject({ age: { $gt: "21", $lt: "100" } }), [
t.same(extractStringsFromUserInput({ age: { $gt: "21", $lt: "100" } }), [
"age",
"$lt",
"$gt",
Expand All @@ -79,7 +79,7 @@ t.test("it can extract body objects", async () => {

t.test("it decodes JWTs", async () => {
t.same(
extractStringsFromObject({
extractStringsFromUserInput({
token:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwidXNlcm5hbWUiOnsiJG5lIjpudWxsfSwiaWF0IjoxNTE2MjM5MDIyfQ._jhGJw9WzB6gHKPSozTFHDo9NOHs3CNOlvJ8rWy6VrQ",
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,32 @@ import { tryDecodeAsJWT } from "./tryDecodeAsJWT";
/**
* Extract all strings from an object, see unit tests for examples
*/
export function extractStringsFromObject(obj: unknown): string[] {
export function extractStringsFromUserInput(obj: unknown): string[] {
let results: Set<string> = new Set();

if (isPlainObject(obj)) {
for (const key in obj) {
results = new Set([
key,
...results,
...extractStringsFromObject(obj[key]),
...extractStringsFromUserInput(obj[key]),
]);
}
}

if (Array.isArray(obj)) {
for (const element of obj) {
results = new Set([...results, ...extractStringsFromObject(element)]);
results = new Set([...results, ...extractStringsFromUserInput(element)]);
}
}

if (typeof obj == "string") {
const jwt = tryDecodeAsJWT(obj);
if (jwt.jwt) {
results = new Set([...results, ...extractStringsFromObject(jwt.object)]);
results = new Set([
...results,
...extractStringsFromUserInput(jwt.object),
]);
} else {
results.add(obj);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Agent } from "../../agent/Agent";
import { Context } from "../../agent/Context";
import { Source, friendlyName } from "../../agent/Source";
import { extractStringsFromObject } from "../../helpers/extractStringsFromObjects";
import { extractStringsFromUserInput } from "../../helpers/extractStringsFromUserInput";

/* We make use of double backslashes to create a single backslash in the RegEx
* SQL Operators : = ! ; + - * / % & | ^ > <
Expand Down Expand Up @@ -149,7 +149,7 @@ export function checkContextForSqlInjection(
) {
for (const source of ["body", "query", "headers", "cookies"] as Source[]) {
if (request[source]) {
const userInput = extractStringsFromObject(request[source]);
const userInput = extractStringsFromUserInput(request[source]);
for (const str of userInput) {
if (detectSQLInjection(sql, str)) {
agent.onDetectedAttack({
Expand Down

0 comments on commit c093d02

Please sign in to comment.