Skip to content

Commit

Permalink
Merge branch 'main' of github.com:AikidoSec/node-RASP into add-commen…
Browse files Browse the repository at this point in the history
…ts-for-regex-escape

* 'main' of github.com:AikidoSec/node-RASP:
  Move to separate file
  Remove typedoc
  Split regex up into different smaller regex strings
  Add comments to regex
  Remove some comments
  • Loading branch information
hansott committed Feb 27, 2024
2 parents 42aff2f + 4cdf0c7 commit a1d85db
Show file tree
Hide file tree
Showing 19 changed files with 76 additions and 187 deletions.
4 changes: 0 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ lambda-mongodb-nosql-injection:
lambda-mongodb-safe:
cd sample-apps/lambda-mongodb && npx serverless invoke local --function login --path payloads/safe-request.json

.PHONY: docs
docs:
npx typedoc

.PHONY: install
install:
npm install --workspaces
Expand Down
22 changes: 17 additions & 5 deletions benchmarks/sql-injection/benchmark.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* Runs benchmarks for the detection of SQL Injections
* @module
*/
const fs = require("fs");
const path = require("path");
Expand All @@ -23,6 +22,7 @@ function main() {
);
}
}

main();

function runBenchmark(sql, input) {
Expand Down Expand Up @@ -55,19 +55,31 @@ function getAvgBenchmark() {
*/
function fetchSqlStatements() {
const auth_bypass_txt = fs.readFileSync(
path.join(__dirname, "./../../library/testing/sql-injection-payloads/Auth_Bypass.txt"),
path.join(
__dirname,
"./../../library/testing/sql-injection-payloads/Auth_Bypass.txt"
),
"utf-8"
);
const postgres_txt = fs.readFileSync(
path.join(__dirname, "./../../library/testing/sql-injection-payloads/postgres.txt"),
path.join(
__dirname,
"./../../library/testing/sql-injection-payloads/postgres.txt"
),
"utf-8"
);
const mysql_txt = fs.readFileSync(
path.join(__dirname, "./../../library/testing/sql-injection-payloads/mysql.txt"),
path.join(
__dirname,
"./../../library/testing/sql-injection-payloads/mysql.txt"
),
"utf-8"
);
const mssql_and_db2_txt = fs.readFileSync(
path.join(__dirname, "./../../library/testing/sql-injection-payloads/mssql_and_db2.txt"),
path.join(
__dirname,
"./../../library/testing/sql-injection-payloads/mssql_and_db2.txt"
),
"utf-8"
);

Expand Down
5 changes: 0 additions & 5 deletions library/src/agent/AgentSingleton.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* This module contains a variable instance, and methods to get and set the current agent
* @module agent/AgentSingleton
*/

import { Agent } from "./Agent";

let instance: Agent | undefined = undefined;
Expand Down
6 changes: 0 additions & 6 deletions library/src/agent/Logger.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
/**
* Exports 2 classes related to logging
* + Type definition Logger
* @module agent/Logger
*/

export interface Logger {
log(message: string): void;
}
Expand Down
5 changes: 0 additions & 5 deletions library/src/agent/Source.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* Exports type def Source but mainly the function {@link friendlyName}
* @module agent/Source
*/

export type Source = "query" | "body" | "headers" | "cookies";

/**
Expand Down
5 changes: 0 additions & 5 deletions library/src/agent/Wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* Type definitions
* @module agent/Wrapper
*/

export interface Wrapper {
wrap(): void;
}
5 changes: 0 additions & 5 deletions library/src/helpers/getOptions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* This module contains the default options and the function {@link getOptions}
* @module helpers/getOptions
*/

/**
* It gets the options for an Agent
* @param partialOptions Your own values which will overwrite the default options
Expand Down
5 changes: 0 additions & 5 deletions library/src/helpers/getPackageVersion.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* The getPackageVersion module exports only one function : {@link getPackageVersion}
* @module helpers/getPackageVersion
*/

/**
* Get the installed version of a package
* @param pkg A package name
Expand Down
1 change: 0 additions & 1 deletion library/src/helpers/isPlainObject.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* Grabbed from https://github.com/jonschlinkert/is-plain-object
* @module helpers/isPlainObject
*/

function isObject(o: unknown) {
Expand Down
5 changes: 0 additions & 5 deletions library/src/helpers/satisfiesVersion.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* The satisfiesVersion module exports only one function with the same name : satisfiesVersion
* @module helpers/satisfiesVersion
*/

/**
* This function checks if a certain version satisfies a version range.
* @param range A range of versions written in semver
Expand Down
5 changes: 0 additions & 5 deletions library/src/helpers/tryDecodeAsJWT.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* The JWT module only exports one function : tryDecodeAsJWT
* @module helpers/JWT
*/

/**
* This function tries to decode your input as if it is a JSON Web Token, if it fails to do so it returns {jwt: false}.
* @param jwt A (possible) JWT
Expand Down
17 changes: 17 additions & 0 deletions library/src/vulnerabilities/sql-injection/dangerousCharsInInput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { SQL_DANGEROUS_IN_STRING } from "./config";

const dangerousInStringRegex = new RegExp(
SQL_DANGEROUS_IN_STRING.join("|"),
"im"
);

/**
* This function is the second step to determine if an SQL Injection is happening,
* If the user input contains characters that should never end up in a query, not
* even in a string, this function returns true.
* @param userInput The user input you want to check
* @returns True if characters are present
*/
export function dangerousCharsInInput(userInput: string): boolean {
return dangerousInStringRegex.test(userInput);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as t from "tap";
import * as fs from "fs";
import * as path from "path";
import { dangerousCharsInInput } from "./dangerousCharsInInput";
import {
dangerousCharsInInput,
detectSQLInjection,
userInputOccurrencesSafelyEncapsulated,
queryContainsUserInput,
Expand Down
49 changes: 4 additions & 45 deletions library/src/vulnerabilities/sql-injection/detectSQLInjection.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { Agent } from "../../agent/Agent";
import { Context } from "../../agent/Context";
import { Source, friendlyName } from "../../agent/Source";
import { friendlyName, Source } from "../../agent/Source";
import { extractStringsFromUserInput } from "../../helpers/extractStringsFromUserInput";

import {
SQL_KEYWORDS,
SQL_OPERATORS,
SQL_DANGEROUS_IN_STRING,
SQL_STRING_CHARS,
} from "./config";
import { SQL_STRING_CHARS } from "./config";
import { dangerousCharsInInput } from "./dangerousCharsInInput";
import { userInputContainsSQLSyntax } from "./userInputContainsSQLSyntax";

/**
* This function executes 2 checks to see if something is or is not an SQL Injection :
Expand Down Expand Up @@ -46,33 +43,6 @@ export function detectSQLInjection(query: string, userInput: string) {
return userInputContainsSQLSyntax(userInput);
}

const dangerousInStringRegex = new RegExp(
SQL_DANGEROUS_IN_STRING.join("|"),
"im"
);

const possibleSqlRegex = new RegExp(
"(?<![a-z])(" +
SQL_KEYWORDS.join("|") +
")(?![a-z])|(" +
SQL_OPERATORS.join("|") +
")|(?<=([\\s|.|" +
SQL_OPERATORS.join("|") +
"]|^)+)([a-z0-9_-]+)(?=[\\s]*\\()",
"im"
);

/**
* This function is the first check in order to determine if a SQL injection is happening,
* If the user input contains the necessary characters or words for a SQL injection, this
* function returns true.
* @param userInput The user input you want to check
* @returns True when this is a possible SQL Injection
*/
export function userInputContainsSQLSyntax(userInput: string): boolean {
return possibleSqlRegex.test(userInput);
}

/**
* This function is the first step to determine if an SQL Injection is happening,
* If the sql statement contains user input, this function returns true (case-insensitive)
Expand All @@ -87,17 +57,6 @@ export function queryContainsUserInput(query: string, userInput: string) {
return lowercaseSql.includes(lowercaseInput);
}

/**
* This function is the second step to determine if an SQL Injection is happening,
* If the user input contains characters that should never end up in a query, not
* even in a string, this function returns true.
* @param userInput The user input you want to check
* @returns True if characters are present
*/
export function dangerousCharsInInput(userInput: string): boolean {
return dangerousInStringRegex.test(userInput);
}

/**
* This function is the third step to determine if an SQL Injection is happening,
* This checks if **all** occurrences of our input are encapsulated as strings.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { SQL_KEYWORDS, SQL_OPERATORS } from "./config";

const matchSqlKeywords =
"(?<![a-z])(" + // Lookbehind : if the keywords are preceded by one or more letters, it should not match
SQL_KEYWORDS.join("|") + // Look for SQL Keywords
")(?![a-z])"; // Lookahead : if the keywords are followed by one or more letters, it should not match

const matchSqlOperators = `(${SQL_OPERATORS.join("|")})`;

const matchSqlFunctions =
"(?<=([\\s|.|" + // Lookbehind : A sql function should be preceded by spaces, dots,
SQL_OPERATORS.join("|") + // Or sql operators
"]|^)+)" +
"([a-z0-9_-]+)" + // The name of a sql function can include letters, numbers, "_" and "-"
"(?=[\\s]*\\()"; // Lookahead : A sql function should be followed by a "(" , spaces are allowed.

const possibleSqlRegex = new RegExp(
// Match one or more of : sql keywords, sql operators, sql functions
`${matchSqlKeywords}|${matchSqlOperators}|${matchSqlFunctions}`,
"im"
);

/**
* This function is the first check in order to determine if a SQL injection is happening,
* If the user input contains the necessary characters or words for a SQL injection, this
* function returns true.
* @param userInput The user input you want to check
* @returns True when this is a possible SQL Injection
*/
export function userInputContainsSQLSyntax(userInput: string): boolean {
return possibleSqlRegex.test(userInput);
}
5 changes: 2 additions & 3 deletions library/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
"outDir": "./dist",
"declaration": true,
"strict": true,
"allowJs": false,
"resolveJsonModule": true,
"allowJs": false
},
"include": ["src"],
"exclude": ["**/*.test.ts"],
"exclude": ["**/*.test.ts"]
}
Loading

0 comments on commit a1d85db

Please sign in to comment.