@contrast/common 1.1.1 → 1.1.3

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.
@@ -20,12 +20,13 @@ export declare enum Rule {
20
20
  NOSQL_INJECTION = "nosql-injection",
21
21
  NOSQL_INJECTION_MONGO = "nosql-injection-mongo",
22
22
  PATH_TRAVERSAL = "path-traversal",
23
+ PATH_TRAVERSAL_SEMANTIC_FILE_SECURITY_BYPASS = "path-traversal-semantic-file-security-bypass",
23
24
  REFLECTED_XSS = "reflected-xss",
24
25
  SQL_INJECTION = "sql-injection",
25
26
  SSJS_INJECTION = "ssjs-injection",
26
- VIRTUAL_PATCH = "virtual-patch",
27
- UNTRUSTED_DESERIALIZATION = "untrusted-deserialization",
28
27
  UNSAFE_FILE_UPLOAD = "unsafe-file-upload",
28
+ UNTRUSTED_DESERIALIZATION = "untrusted-deserialization",
29
+ VIRTUAL_PATCH = "virtual-patch",
29
30
  XXE = "xxe"
30
31
  }
31
32
  export declare enum InputType {
package/lib/constants.js CHANGED
@@ -40,12 +40,13 @@ var Rule;
40
40
  Rule["NOSQL_INJECTION"] = "nosql-injection";
41
41
  Rule["NOSQL_INJECTION_MONGO"] = "nosql-injection-mongo";
42
42
  Rule["PATH_TRAVERSAL"] = "path-traversal";
43
+ Rule["PATH_TRAVERSAL_SEMANTIC_FILE_SECURITY_BYPASS"] = "path-traversal-semantic-file-security-bypass";
43
44
  Rule["REFLECTED_XSS"] = "reflected-xss";
44
45
  Rule["SQL_INJECTION"] = "sql-injection";
45
46
  Rule["SSJS_INJECTION"] = "ssjs-injection";
46
- Rule["VIRTUAL_PATCH"] = "virtual-patch";
47
- Rule["UNTRUSTED_DESERIALIZATION"] = "untrusted-deserialization";
48
47
  Rule["UNSAFE_FILE_UPLOAD"] = "unsafe-file-upload";
48
+ Rule["UNTRUSTED_DESERIALIZATION"] = "untrusted-deserialization";
49
+ Rule["VIRTUAL_PATCH"] = "virtual-patch";
49
50
  Rule["XXE"] = "xxe";
50
51
  })(Rule = exports.Rule || (exports.Rule = {}));
51
52
  var InputType;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAEH,IAAY,KAIX;AAJD,WAAY,KAAK;IACf,0BAAiB,CAAA;IACjB,4BAAmB,CAAA;IACnB,0DAAiD,CAAA;AACnD,CAAC,EAJW,KAAK,GAAL,aAAK,KAAL,aAAK,QAIhB;AACD,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,8BAAW,CAAA;IACX,sCAAmB,CAAA;IACnB,kCAAe,CAAA;IACf,4DAAyC,CAAA;AAC3C,CAAC,EALW,eAAe,GAAf,uBAAe,KAAf,uBAAe,QAK1B;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;AAED,IAAY,SAuBX;AAvBD,WAAY,SAAS;IACnB,8CAAiC,CAAA;IACjC,0BAAa,CAAA;IACb,wCAA2B,CAAA;IAC3B,0CAA6B,CAAA;IAC7B,8BAAiB,CAAA;IACjB,8CAAiC,CAAA;IACjC,gDAAmC,CAAA;IACnC,wCAA2B,CAAA;IAC3B,wBAAW,CAAA;IACX,8BAAiB,CAAA;IACjB,sCAAyB,CAAA;IACzB,sDAAyC,CAAA;IACzC,8DAAiD,CAAA;IACjD,gDAAmC,CAAA;IACnC,0DAA6C,CAAA;IAC7C,8CAAiC,CAAA;IACjC,oCAAuB,CAAA;IACvB,oCAAuB,CAAA;IACvB,8BAAiB,CAAA;IACjB,gCAAmB,CAAA;IACnB,4CAA+B,CAAA;IAC/B,gCAAmB,CAAA;AACrB,CAAC,EAvBW,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAuBpB;AAEY,QAAA,cAAc,GAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAEH,IAAY,KAIX;AAJD,WAAY,KAAK;IACf,0BAAiB,CAAA;IACjB,4BAAmB,CAAA;IACnB,0DAAiD,CAAA;AACnD,CAAC,EAJW,KAAK,GAAL,aAAK,KAAL,aAAK,QAIhB;AACD,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,8BAAW,CAAA;IACX,sCAAmB,CAAA;IACnB,kCAAe,CAAA;IACf,4DAAyC,CAAA;AAC3C,CAAC,EALW,eAAe,GAAf,uBAAe,KAAf,uBAAe,QAK1B;AAED,IAAY,IAmBX;AAnBD,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,qGAA6F,CAAA;IAC7F,uCAA+B,CAAA;IAC/B,uCAA+B,CAAA;IAC/B,yCAAiC,CAAA;IACjC,iDAAyC,CAAA;IACzC,+DAAuD,CAAA;IACvD,uCAA+B,CAAA;IAC/B,mBAAW,CAAA;AACb,CAAC,EAnBW,IAAI,GAAJ,YAAI,KAAJ,YAAI,QAmBf;AAED,IAAY,SAuBX;AAvBD,WAAY,SAAS;IACnB,8CAAiC,CAAA;IACjC,0BAAa,CAAA;IACb,wCAA2B,CAAA;IAC3B,0CAA6B,CAAA;IAC7B,8BAAiB,CAAA;IACjB,8CAAiC,CAAA;IACjC,gDAAmC,CAAA;IACnC,wCAA2B,CAAA;IAC3B,wBAAW,CAAA;IACX,8BAAiB,CAAA;IACjB,sCAAyB,CAAA;IACzB,sDAAyC,CAAA;IACzC,8DAAiD,CAAA;IACjD,gDAAmC,CAAA;IACnC,0DAA6C,CAAA;IAC7C,8CAAiC,CAAA;IACjC,oCAAuB,CAAA;IACvB,oCAAuB,CAAA;IACvB,8BAAiB,CAAA;IACjB,gCAAmB,CAAA;IACnB,4CAA+B,CAAA;IAC/B,gCAAmB,CAAA;AACrB,CAAC,EAvBW,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAuBpB;AAEY,QAAA,cAAc,GAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC"}
package/lib/types.d.ts CHANGED
@@ -1,17 +1,39 @@
1
1
  /// <reference types="node" />
2
2
  import { Event, Rule, ProtectRuleMode } from './constants';
3
3
  import { EventEmitter } from 'events';
4
+ export interface AppInfo {
5
+ os: {
6
+ type: string;
7
+ platform: string;
8
+ architecture: string;
9
+ release: string;
10
+ };
11
+ hostname: string;
12
+ version: string;
13
+ name: string;
14
+ pkg: object;
15
+ agentVersion: string;
16
+ app_dir: string;
17
+ serverVersion: string;
18
+ node_version: string;
19
+ appPath: string;
20
+ indexFile: string;
21
+ serverName: string;
22
+ serverEnvironment: string;
23
+ }
4
24
  export declare type SemanticAnalysisRules = Rule.CMD_INJECTION_SEMANTIC_CHAINED_COMMANDS | Rule.CMD_INJECTION_COMMAND_BACKDOORS | Rule.CMD_INJECTION_SEMANTIC_DANGEROUS_PATHS;
5
25
  export interface Result {
6
26
  blocked: boolean;
7
- ruleId: Rule;
27
+ details?: any[];
28
+ idsList?: string[];
8
29
  inputType: string;
9
- path?: string[];
10
30
  key?: string;
11
- value: string;
12
- details?: any[];
31
+ mappedId: string;
13
32
  mongoExpansionResult?: boolean;
14
- idsList?: string[];
33
+ path?: string[];
34
+ ruleId: Rule;
35
+ score: number;
36
+ value: string;
15
37
  }
16
38
  export interface SemanticAnalysisResult extends Result {
17
39
  findings?: {
@@ -48,18 +70,15 @@ export interface Findings {
48
70
  trackRequest: boolean;
49
71
  securityException?: [mode: ProtectRuleMode, ruleId: string];
50
72
  bodyType?: 'json' | 'urlencoded';
51
- resultsMap: Record<Rule, Result[]>;
52
- semanticResultsMap: Record<Rule, SemanticAnalysisResult[]>;
53
- serverFeaturesResultsMap: Record<Rule, ServerFeaturePreliminaryResult[]>;
54
- hardeningResultsMap: Record<Rule, HardeningResult[]>;
55
- }
56
- export interface RequestStore {
57
- protect?: ProtectMessage;
73
+ resultsMap: Partial<Record<Rule, Result[]>>;
74
+ semanticResultsMap: Partial<Record<Rule, SemanticAnalysisResult[]>>;
75
+ serverFeaturesResultsMap: Partial<Record<Rule, ServerFeaturePreliminaryResult[]>>;
76
+ hardeningResultsMap: Partial<Record<Rule, HardeningResult[]>>;
58
77
  }
59
78
  export interface ProtectMessage {
60
79
  reqData: ReqData;
61
80
  block: (mode: string, ruleId: string) => void;
62
- policy: any;
81
+ policy: Partial<Record<Rule, ProtectRuleMode>>;
63
82
  exclusions: any[];
64
83
  virtualPatches: any[];
65
84
  findings: Findings;
@@ -68,16 +87,26 @@ export interface ProtectMessage {
68
87
  parsedParams: any;
69
88
  parsedQuery: any;
70
89
  }
90
+ /**
91
+ * this is known as RequestStore even though, in the future, instrumentation
92
+ * will exist for message buses or sources other than HTTP requests. "request"
93
+ * seems generic enough that it's not hard to understand that request can mean
94
+ * an amqp message or other request to perform work that might get user input.
95
+ * additionally, at this time, the only things instrumented are HTTP requests,
96
+ * and other things are only possible extensions to the core facility. it seems
97
+ * reasonable that they will fit into the primary concept that the agent deals
98
+ * with, requests, whether from HTTP or elsewhere.
99
+ */
100
+ export interface RequestStore {
101
+ protect?: ProtectMessage;
102
+ }
71
103
  export interface Messages extends EventEmitter {
72
104
  addListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
105
+ addListener(event: Event.SERVER_SETTINGS_UPDATE, listener: (msg: Record<string, any>) => void): this;
73
106
  emit(event: Event.PROTECT, msg: RequestStore): boolean;
74
- emit(event: Event.SERVER_SETTINGS_UPDATE, msg: {
75
- [key: string]: any;
76
- }): boolean;
107
+ emit(event: Event.SERVER_SETTINGS_UPDATE, msg: Record<string, any>): boolean;
77
108
  on(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
78
- on(event: Event.SERVER_SETTINGS_UPDATE, listener: (msg: {
79
- [key: string]: any;
80
- }) => void): this;
109
+ on(event: Event.SERVER_SETTINGS_UPDATE, listener: (msg: Record<string, any>) => void): this;
81
110
  prependListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
82
111
  prependOnceListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
83
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/common",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Shared constants and utilities for all Contrast Agent modules",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
package/src/constants.ts CHANGED
@@ -36,12 +36,13 @@ export enum Rule {
36
36
  NOSQL_INJECTION = 'nosql-injection',
37
37
  NOSQL_INJECTION_MONGO = 'nosql-injection-mongo',
38
38
  PATH_TRAVERSAL = 'path-traversal',
39
+ PATH_TRAVERSAL_SEMANTIC_FILE_SECURITY_BYPASS = 'path-traversal-semantic-file-security-bypass',
39
40
  REFLECTED_XSS = 'reflected-xss',
40
41
  SQL_INJECTION = 'sql-injection',
41
42
  SSJS_INJECTION = 'ssjs-injection',
42
- VIRTUAL_PATCH = 'virtual-patch',
43
- UNTRUSTED_DESERIALIZATION = 'untrusted-deserialization',
44
43
  UNSAFE_FILE_UPLOAD = 'unsafe-file-upload',
44
+ UNTRUSTED_DESERIALIZATION = 'untrusted-deserialization',
45
+ VIRTUAL_PATCH = 'virtual-patch',
45
46
  XXE = 'xxe',
46
47
  }
47
48
 
@@ -71,4 +72,3 @@ export enum InputType {
71
72
  }
72
73
 
73
74
  export const BLOCKING_MODES = ['block', 'block_at_perimeter'];
74
-
package/src/types.ts CHANGED
@@ -16,43 +16,69 @@
16
16
  import { Event, Rule, ProtectRuleMode } from './constants';
17
17
  import { EventEmitter } from 'events';
18
18
 
19
- export type SemanticAnalysisRules = Rule.CMD_INJECTION_SEMANTIC_CHAINED_COMMANDS | Rule.CMD_INJECTION_COMMAND_BACKDOORS | Rule.CMD_INJECTION_SEMANTIC_DANGEROUS_PATHS;
19
+ export interface AppInfo {
20
+ os: {
21
+ type: string;
22
+ platform: string;
23
+ architecture: string;
24
+ release: string;
25
+ };
26
+ hostname: string;
27
+ version: string;
28
+ name: string;
29
+ pkg: object; // package.json
30
+ agentVersion: string;
31
+ app_dir: string;
32
+ serverVersion: string;
33
+ node_version: string;
34
+ appPath: string;
35
+ indexFile: string;
36
+ serverName: string;
37
+ serverEnvironment: string;
38
+ }
39
+
40
+ export type SemanticAnalysisRules =
41
+ | Rule.CMD_INJECTION_SEMANTIC_CHAINED_COMMANDS
42
+ | Rule.CMD_INJECTION_COMMAND_BACKDOORS
43
+ | Rule.CMD_INJECTION_SEMANTIC_DANGEROUS_PATHS;
20
44
 
21
45
  export interface Result {
22
46
  blocked: boolean;
23
- ruleId: Rule,
24
- inputType: string, // TODO
25
- path?: string[],
26
- key?: string,
27
- value: string,
28
- details?: any[], // TODO
29
- mongoExpansionResult?: boolean,
30
- idsList?: string[],
47
+ details?: any[]; // TODO
48
+ idsList?: string[];
49
+ inputType: string; // TODO
50
+ key?: string;
51
+ mappedId: string;
52
+ mongoExpansionResult?: boolean;
53
+ path?: string[];
54
+ ruleId: Rule;
55
+ score: number;
56
+ value: string;
31
57
  }
32
58
 
33
59
  export interface SemanticAnalysisResult extends Result {
34
60
  findings?: {
35
- command?: string
36
- }
37
- sinkContext?: any
61
+ command?: string;
62
+ };
63
+ sinkContext?: any;
38
64
  }
39
65
 
40
66
  export interface HardeningResult extends Result {
41
67
  findings?: {
42
- command?: boolean,
43
- deserializer?: string
44
- }
45
- sinkContext?: any
68
+ command?: boolean;
69
+ deserializer?: string;
70
+ };
71
+ sinkContext?: any;
46
72
  }
47
73
 
48
74
  export interface ServerFeaturePreliminaryResult {
49
- name?: string,
50
- uuid: string,
51
- ip?: string
75
+ name?: string;
76
+ uuid: string;
77
+ ip?: string;
52
78
  }
53
79
 
54
80
  export interface ServerFeatureResult extends Result {
55
- details?: ServerFeaturePreliminaryResult[]
81
+ details?: ServerFeaturePreliminaryResult[];
56
82
  }
57
83
 
58
84
  export interface ReqData {
@@ -63,38 +89,23 @@ export interface ReqData {
63
89
  contentType?: string;
64
90
  standardUrlParsing: boolean;
65
91
  ip: string;
66
- httpVersion: string,
92
+ httpVersion: string;
67
93
  }
68
94
 
69
95
  export interface Findings {
70
96
  trackRequest: boolean;
71
97
  securityException?: [mode: ProtectRuleMode, ruleId: string];
72
98
  bodyType?: 'json' | 'urlencoded';
73
- resultsMap: Record<Rule, Result[]>;
74
- semanticResultsMap: Record<Rule, SemanticAnalysisResult[]>;
75
- serverFeaturesResultsMap: Record<Rule, ServerFeaturePreliminaryResult[]>;
76
- hardeningResultsMap: Record<Rule, HardeningResult[]>;
77
- }
78
-
79
- //
80
- // this is known as RequestStore even though, in the future, instrumentation
81
- // will exist for message buses or sources other than HTTP requests. "request"
82
- // seems generic enough that it's not hard to understand that request can mean
83
- // an amqp message or other request to perform work that might get user input.
84
- // additionally, at this time, the only things instrumented are HTTP requests,
85
- // and other things are only possible extensions to the core facility. it seems
86
- // reasonable that they will fit into the primary concept that the agent deals
87
- // with, requests, whether from HTTP or elsewhere.
88
- //
89
- export interface RequestStore {
90
- // TODO: from protect/lib/make-source-context
91
- protect?: ProtectMessage;
99
+ resultsMap: Partial<Record<Rule, Result[]>>;
100
+ semanticResultsMap: Partial<Record<Rule, SemanticAnalysisResult[]>>;
101
+ serverFeaturesResultsMap: Partial<Record<Rule, ServerFeaturePreliminaryResult[]>>;
102
+ hardeningResultsMap: Partial<Record<Rule, HardeningResult[]>>;
92
103
  }
93
104
 
94
105
  export interface ProtectMessage {
95
106
  reqData: ReqData;
96
107
  block: (mode: string, ruleId: string) => void;
97
- policy: any;
108
+ policy: Partial<Record<Rule, ProtectRuleMode>>;
98
109
  exclusions: any[]; // TODO
99
110
  virtualPatches: any[]; // TODO
100
111
  findings: Findings;
@@ -104,12 +115,44 @@ export interface ProtectMessage {
104
115
  parsedQuery: any;
105
116
  }
106
117
 
118
+ /**
119
+ * this is known as RequestStore even though, in the future, instrumentation
120
+ * will exist for message buses or sources other than HTTP requests. "request"
121
+ * seems generic enough that it's not hard to understand that request can mean
122
+ * an amqp message or other request to perform work that might get user input.
123
+ * additionally, at this time, the only things instrumented are HTTP requests,
124
+ * and other things are only possible extensions to the core facility. it seems
125
+ * reasonable that they will fit into the primary concept that the agent deals
126
+ * with, requests, whether from HTTP or elsewhere.
127
+ */
128
+ export interface RequestStore {
129
+ protect?: ProtectMessage; // from protect/lib/make-source-context
130
+ }
131
+
107
132
  export interface Messages extends EventEmitter {
108
- addListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
133
+ addListener(event: Event.PROTECT,
134
+ listener: (msg: RequestStore) => void,
135
+ ): this;
136
+ addListener(
137
+ event: Event.SERVER_SETTINGS_UPDATE,
138
+ listener: (msg: Record<string, any>) => void,
139
+ ): this;
140
+
109
141
  emit(event: Event.PROTECT, msg: RequestStore): boolean;
110
- emit(event: Event.SERVER_SETTINGS_UPDATE, msg: { [key: string]: any }): boolean;
142
+ emit(event: Event.SERVER_SETTINGS_UPDATE, msg: Record<string, any>): boolean;
143
+
111
144
  on(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
112
- on(event: Event.SERVER_SETTINGS_UPDATE, listener: (msg: { [key: string]: any }) => void): this;
113
- prependListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
114
- prependOnceListener(event: Event.PROTECT, listener: (msg: RequestStore) => void): this;
145
+ on(
146
+ event: Event.SERVER_SETTINGS_UPDATE,
147
+ listener: (msg: Record<string, any>) => void,
148
+ ): this;
149
+
150
+ prependListener(
151
+ event: Event.PROTECT,
152
+ listener: (msg: RequestStore) => void,
153
+ ): this;
154
+ prependOnceListener(
155
+ event: Event.PROTECT,
156
+ listener: (msg: RequestStore) => void,
157
+ ): this;
115
158
  }