@contrast/common 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/constants.d.ts +23 -0
- package/lib/constants.js +29 -0
- package/lib/constants.js.map +1 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +33 -0
- package/lib/index.js.map +1 -0
- package/lib/types/index.d.ts +50 -0
- package/lib/types/index.js +3 -0
- package/lib/types/index.js.map +1 -0
- package/package.json +18 -0
- package/src/constants.ts +24 -0
- package/src/index.ts +15 -0
- package/src/types/index.ts +64 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare enum Event {
|
|
2
|
+
ASSESS = "assess",
|
|
3
|
+
PROTECT = "protect"
|
|
4
|
+
}
|
|
5
|
+
export declare enum Rule {
|
|
6
|
+
BOT_BLOCKER = "bot-blocker",
|
|
7
|
+
CMD_INJECTION = "cmd-injection",
|
|
8
|
+
CMD_INJECTION_COMMAND_BACKDOORS = "cmd-injection-command-backdoors",
|
|
9
|
+
CMD_INJECTION_SEMANTIC_CHAINED_COMMANDS = "cmd-injection-semantic-chained-commands",
|
|
10
|
+
CMD_INJECTION_SEMANTIC_DANGEROUS_PATHS = "cmd-injection-semantic-dangerous-paths",
|
|
11
|
+
IP_DENYLIST = "ip-denylist",
|
|
12
|
+
METHOD_TAMPERING = "method-tampering",
|
|
13
|
+
NOSQL_INJECTION = "nosql-injection",
|
|
14
|
+
NOSQL_INJECTION_MONGO = "nosql-injection-mongo",
|
|
15
|
+
PATH_TRAVERSAL = "path-traversal",
|
|
16
|
+
REFLECTED_XSS = "reflected-xss",
|
|
17
|
+
SQL_INJECTION = "sql-injection",
|
|
18
|
+
SSJS_INJECTION = "ssjs-injection",
|
|
19
|
+
VIRTUAL_PATCH = "virtual-patch",
|
|
20
|
+
UNTRUSTED_DESERIALIZATION = "untrusted-deserialization",
|
|
21
|
+
UNSAFE_FILE_UPLOAD = "unsafe-file-upload",
|
|
22
|
+
XXE = "xxe"
|
|
23
|
+
}
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Rule = exports.Event = void 0;
|
|
4
|
+
var Event;
|
|
5
|
+
(function (Event) {
|
|
6
|
+
Event["ASSESS"] = "assess";
|
|
7
|
+
Event["PROTECT"] = "protect";
|
|
8
|
+
})(Event = exports.Event || (exports.Event = {}));
|
|
9
|
+
var Rule;
|
|
10
|
+
(function (Rule) {
|
|
11
|
+
Rule["BOT_BLOCKER"] = "bot-blocker";
|
|
12
|
+
Rule["CMD_INJECTION"] = "cmd-injection";
|
|
13
|
+
Rule["CMD_INJECTION_COMMAND_BACKDOORS"] = "cmd-injection-command-backdoors";
|
|
14
|
+
Rule["CMD_INJECTION_SEMANTIC_CHAINED_COMMANDS"] = "cmd-injection-semantic-chained-commands";
|
|
15
|
+
Rule["CMD_INJECTION_SEMANTIC_DANGEROUS_PATHS"] = "cmd-injection-semantic-dangerous-paths";
|
|
16
|
+
Rule["IP_DENYLIST"] = "ip-denylist";
|
|
17
|
+
Rule["METHOD_TAMPERING"] = "method-tampering";
|
|
18
|
+
Rule["NOSQL_INJECTION"] = "nosql-injection";
|
|
19
|
+
Rule["NOSQL_INJECTION_MONGO"] = "nosql-injection-mongo";
|
|
20
|
+
Rule["PATH_TRAVERSAL"] = "path-traversal";
|
|
21
|
+
Rule["REFLECTED_XSS"] = "reflected-xss";
|
|
22
|
+
Rule["SQL_INJECTION"] = "sql-injection";
|
|
23
|
+
Rule["SSJS_INJECTION"] = "ssjs-injection";
|
|
24
|
+
Rule["VIRTUAL_PATCH"] = "virtual-patch";
|
|
25
|
+
Rule["UNTRUSTED_DESERIALIZATION"] = "untrusted-deserialization";
|
|
26
|
+
Rule["UNSAFE_FILE_UPLOAD"] = "unsafe-file-upload";
|
|
27
|
+
Rule["XXE"] = "xxe";
|
|
28
|
+
})(Rule = exports.Rule || (exports.Rule = {}));
|
|
29
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA,IAAY,KAGX;AAHD,WAAY,KAAK;IACf,0BAAiB,CAAA;IACjB,4BAAmB,CAAA;AACrB,CAAC,EAHW,KAAK,GAAL,aAAK,KAAL,aAAK,QAGhB;AAED,IAAY,IAkBX;AAlBD,WAAY,IAAI;IACd,mCAA2B,CAAA;IAC3B,uCAA+B,CAAA;IAC/B,2EAAmE,CAAA;IACnE,2FAAmF,CAAA;IACnF,yFAAiF,CAAA;IACjF,mCAA2B,CAAA;IAC3B,6CAAqC,CAAA;IACrC,2CAAmC,CAAA;IACnC,uDAA+C,CAAA;IAC/C,yCAAiC,CAAA;IACjC,uCAA+B,CAAA;IAC/B,uCAA+B,CAAA;IAC/B,yCAAiC,CAAA;IACjC,uCAA+B,CAAA;IAC/B,+DAAuD,CAAA;IACvD,iDAAyC,CAAA;IACzC,mBAAW,CAAA;AACb,CAAC,EAlBW,IAAI,GAAJ,YAAI,KAAJ,YAAI,QAkBf"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './constants';
|
|
2
|
+
export * from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Returns true if the value passed is either a primitive string or a
|
|
5
|
+
* String object.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isString(value: unknown): value is string | String;
|
|
8
|
+
export declare function encodeString(str: string): string;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.encodeString = exports.isString = void 0;
|
|
18
|
+
__exportStar(require("./constants"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if the value passed is either a primitive string or a
|
|
22
|
+
* String object.
|
|
23
|
+
*/
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
25
|
+
function isString(value) {
|
|
26
|
+
return typeof value === 'string' || value instanceof String;
|
|
27
|
+
}
|
|
28
|
+
exports.isString = isString;
|
|
29
|
+
function encodeString(str) {
|
|
30
|
+
return Buffer.from(str).toString('base64');
|
|
31
|
+
}
|
|
32
|
+
exports.encodeString = encodeString;
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,0CAAwB;AAExB;;;GAGG;AACH,wDAAwD;AACxD,SAAgB,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,MAAM,CAAC;AAC9D,CAAC;AAFD,4BAEC;AAED,SAAgB,YAAY,CAAC,GAAW;IACtC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAFD,oCAEC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Event, Rule } from '../constants';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
export interface RuleConfig {
|
|
5
|
+
mode: 'monitor' | 'block' | 'block_at_perimeter' | 'off';
|
|
6
|
+
}
|
|
7
|
+
export interface RulesConfig extends Record<Rule, RuleConfig> {
|
|
8
|
+
}
|
|
9
|
+
export interface Result {
|
|
10
|
+
ruleId: Rule;
|
|
11
|
+
inputType: string;
|
|
12
|
+
path: string[];
|
|
13
|
+
key: string;
|
|
14
|
+
value: string;
|
|
15
|
+
details?: any[];
|
|
16
|
+
}
|
|
17
|
+
export interface RequestStore {
|
|
18
|
+
protect?: {
|
|
19
|
+
reqData: {
|
|
20
|
+
method: string;
|
|
21
|
+
headers: string[];
|
|
22
|
+
uriPath: string;
|
|
23
|
+
queries: string;
|
|
24
|
+
contentType?: string;
|
|
25
|
+
standardUrlParsing: boolean;
|
|
26
|
+
};
|
|
27
|
+
block: (mode: string, ruleId: string) => void;
|
|
28
|
+
rules: {
|
|
29
|
+
agentLibRules: RulesConfig;
|
|
30
|
+
agentLibRulesMask: number;
|
|
31
|
+
agentRules: RulesConfig;
|
|
32
|
+
};
|
|
33
|
+
exclusions: any[];
|
|
34
|
+
virtualPatches: any[];
|
|
35
|
+
findings: {
|
|
36
|
+
trackRequest: boolean;
|
|
37
|
+
securityException?: [mode: string, ruleId: string];
|
|
38
|
+
bodyType?: 'json' | 'urlencoded';
|
|
39
|
+
resultsMap: Record<Rule, Result[]>;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface Messages extends EventEmitter {
|
|
44
|
+
addListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
45
|
+
emit(event: Event.PROTECT, msg: RequestStore): boolean;
|
|
46
|
+
on(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
47
|
+
once(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
48
|
+
prependListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
49
|
+
prependOnceListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@contrast/common",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared constants and utilities for all Contrast Agent modules",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"types": "lib/index.d.ts",
|
|
9
|
+
"engines": {
|
|
10
|
+
"npm": ">= 8.4.0",
|
|
11
|
+
"node": ">= 14.15.0"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc --build src/",
|
|
15
|
+
"test": "../scripts/test.sh"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {}
|
|
18
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export enum Event {
|
|
2
|
+
ASSESS = 'assess',
|
|
3
|
+
PROTECT = 'protect',
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export enum Rule {
|
|
7
|
+
BOT_BLOCKER = 'bot-blocker',
|
|
8
|
+
CMD_INJECTION = 'cmd-injection',
|
|
9
|
+
CMD_INJECTION_COMMAND_BACKDOORS = 'cmd-injection-command-backdoors',
|
|
10
|
+
CMD_INJECTION_SEMANTIC_CHAINED_COMMANDS = 'cmd-injection-semantic-chained-commands',
|
|
11
|
+
CMD_INJECTION_SEMANTIC_DANGEROUS_PATHS = 'cmd-injection-semantic-dangerous-paths',
|
|
12
|
+
IP_DENYLIST = 'ip-denylist',
|
|
13
|
+
METHOD_TAMPERING = 'method-tampering',
|
|
14
|
+
NOSQL_INJECTION = 'nosql-injection',
|
|
15
|
+
NOSQL_INJECTION_MONGO = 'nosql-injection-mongo',
|
|
16
|
+
PATH_TRAVERSAL = 'path-traversal',
|
|
17
|
+
REFLECTED_XSS = 'reflected-xss',
|
|
18
|
+
SQL_INJECTION = 'sql-injection',
|
|
19
|
+
SSJS_INJECTION = 'ssjs-injection',
|
|
20
|
+
VIRTUAL_PATCH = 'virtual-patch',
|
|
21
|
+
UNTRUSTED_DESERIALIZATION = 'untrusted-deserialization',
|
|
22
|
+
UNSAFE_FILE_UPLOAD = 'unsafe-file-upload',
|
|
23
|
+
XXE = 'xxe',
|
|
24
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './constants';
|
|
2
|
+
export * from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns true if the value passed is either a primitive string or a
|
|
6
|
+
* String object.
|
|
7
|
+
*/
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
9
|
+
export function isString(value: unknown): value is string | String {
|
|
10
|
+
return typeof value === 'string' || value instanceof String;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function encodeString(str: string): string {
|
|
14
|
+
return Buffer.from(str).toString('base64');
|
|
15
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Event, Rule } from '../constants';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
|
|
4
|
+
export interface RuleConfig {
|
|
5
|
+
mode: 'monitor' | 'block' | 'block_at_perimeter' | 'off';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface RulesConfig extends Record<Rule, RuleConfig> {}
|
|
9
|
+
|
|
10
|
+
export interface Result {
|
|
11
|
+
ruleId: Rule,
|
|
12
|
+
inputType: string, // TODO
|
|
13
|
+
path: string[],
|
|
14
|
+
key: string,
|
|
15
|
+
value: string,
|
|
16
|
+
details?: any[],
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//
|
|
20
|
+
// this is known as RequestStore even though, in the future, instrumentation
|
|
21
|
+
// will exist for message buses or sources other than HTTP requests. "request"
|
|
22
|
+
// seems generic enough that it's not hard to understand that request can mean
|
|
23
|
+
// an amqp message or other request to perform work that might get user input.
|
|
24
|
+
// additionally, at this time, the only things instrumented are HTTP requests,
|
|
25
|
+
// and other things are only possible extensions to the core facility. it seems
|
|
26
|
+
// reasonable that they will fit into the primary concept that the agent deals
|
|
27
|
+
// with, requests, whether from HTTP or elsewhere.
|
|
28
|
+
//
|
|
29
|
+
export interface RequestStore {
|
|
30
|
+
// TODO: from protect/lib/make-source-context
|
|
31
|
+
protect?: {
|
|
32
|
+
reqData: {
|
|
33
|
+
method: string;
|
|
34
|
+
headers: string[];
|
|
35
|
+
uriPath: string;
|
|
36
|
+
queries: string;
|
|
37
|
+
contentType?: string;
|
|
38
|
+
standardUrlParsing: boolean;
|
|
39
|
+
};
|
|
40
|
+
block: (mode: string, ruleId: string) => void;
|
|
41
|
+
rules: {
|
|
42
|
+
agentLibRules: RulesConfig;
|
|
43
|
+
agentLibRulesMask: number;
|
|
44
|
+
agentRules: RulesConfig;
|
|
45
|
+
};
|
|
46
|
+
exclusions: any[]; // TODO
|
|
47
|
+
virtualPatches: any[]; // TODO
|
|
48
|
+
findings: {
|
|
49
|
+
trackRequest: boolean;
|
|
50
|
+
securityException?: [mode: string, ruleId: string];
|
|
51
|
+
bodyType?: 'json' | 'urlencoded';
|
|
52
|
+
resultsMap: Record<Rule, Result[]>
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface Messages extends EventEmitter {
|
|
58
|
+
addListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
59
|
+
emit(event: Event.PROTECT, msg: RequestStore): boolean;
|
|
60
|
+
on(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
61
|
+
once(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
62
|
+
prependListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
63
|
+
prependOnceListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
|
|
64
|
+
}
|