@sectester/runner 0.32.0 → 0.33.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/README.md CHANGED
@@ -82,7 +82,12 @@ Below you will find a list of parameters that can be used to configure a `Scan`:
82
82
  | `targetTimeout` | Measure timeout responses from the target application globally, and stop the scan if the target is unresponsive for longer than the specified time. By default, 5min. |
83
83
  | `name` | The scan name. The method and hostname by default, e.g. `GET example.com`. |
84
84
 
85
- Finally, run a scan against your application:
85
+ #### Endpoint scan
86
+
87
+ To scan an existing endpoint in your application, invoke the run method with a `TargetOptions` argument.
88
+ For `TargetOptions` details, please refer to this [link](https://github.com/NeuraLegion/sectester-js/tree/master/packages/scan#defining-a-target-for-attack).
89
+
90
+ Example:
86
91
 
87
92
  ```ts
88
93
  await scan.run({
@@ -92,7 +97,28 @@ await scan.run({
92
97
  });
93
98
  ```
94
99
 
95
- The `run` method takes a single argument (for details, see [here](https://github.com/NeuraLegion/sectester-js/tree/master/packages/scan#defining-a-target-for-attack)), and returns promise that is resolved if scan finishes without any vulnerability found, and is rejected otherwise (on founding issue that meets threshold, on timeout, on scanning error).
100
+ #### Function scan
101
+
102
+ To focus on the security aspects of a particular function in your application, you can perform a function-specific scan.
103
+ This automatically creates an auxiliary target with a POST endpoint under the hood.
104
+
105
+ Example:
106
+
107
+ ```ts
108
+ const inputSample = {
109
+ from: '2022-11-30',
110
+ to: '2024-06-21'
111
+ };
112
+ // assuming `calculateWeekdays` is your function under test
113
+ const fn = ({ from, to }) => calculateWeekdays(from, to);
114
+
115
+ const scan = runner.createScan({ tests: [TestType.DATE_MANIPULATION] });
116
+ await scan.run({ inputSample, fn });
117
+ ```
118
+
119
+ #### Scan execution details
120
+
121
+ The `run` method returns promise that is resolved if scan finishes without any vulnerability found, and is rejected otherwise (on founding issue that meets threshold, on timeout, on scanning error).
96
122
 
97
123
  If any vulnerabilities are found, they will be pretty printed to stdout or stderr (depending on severity) by [reporter](https://github.com/NeuraLegion/sectester-js/tree/master/packages/reporter).
98
124
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sectester/runner",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "Run scanning for vulnerabilities just from your unit tests on CI phase.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,6 +33,7 @@
33
33
  "brightsec"
34
34
  ],
35
35
  "dependencies": {
36
+ "fastify": "~4.15.0",
36
37
  "tslib": "~2.6.3"
37
38
  },
38
39
  "peerDependencies": {
@@ -0,0 +1,8 @@
1
+ export declare class FunctionScanTarget {
2
+ private readonly server;
3
+ start<T>(fn: (input: T) => Promise<unknown>): Promise<{
4
+ url: string;
5
+ }>;
6
+ stop(): Promise<void>;
7
+ private handleRequest;
8
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FunctionScanTarget = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fastify_1 = tslib_1.__importDefault(require("fastify"));
6
+ class FunctionScanTarget {
7
+ constructor() {
8
+ this.server = (0, fastify_1.default)();
9
+ }
10
+ async start(fn) {
11
+ this.server.post('/', (request, reply) => this.handleRequest(request, reply, fn));
12
+ const url = await this.server.listen({ port: 0, host: '127.0.0.1' });
13
+ return { url };
14
+ }
15
+ async stop() {
16
+ await this.server.close();
17
+ }
18
+ async handleRequest(request, reply, fn) {
19
+ try {
20
+ const result = await fn(request.body);
21
+ await reply.send(result !== null && result !== void 0 ? result : '');
22
+ }
23
+ catch (err) {
24
+ await reply.status(500).send(err);
25
+ }
26
+ }
27
+ }
28
+ exports.FunctionScanTarget = FunctionScanTarget;
29
+ //# sourceMappingURL=FunctionScanTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FunctionScanTarget.js","sourceRoot":"","sources":["../../../../../packages/runner/src/lib/FunctionScanTarget.ts"],"names":[],"mappings":";;;;AAAA,8DAAgE;AAEhE,MAAa,kBAAkB;IAA/B;QACmB,WAAM,GAAG,IAAA,iBAAO,GAAE,CAAC;IA8BtC,CAAC;IA5BQ,KAAK,CAAC,KAAK,CAChB,EAAkC;QAElC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CACvC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CACvC,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QAErE,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,OAAuB,EACvB,KAAmB,EACnB,EAAkC;QAElC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAS,CAAC,CAAC;YAC3C,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;CACF;AA/BD,gDA+BC"}
@@ -1,5 +1,9 @@
1
1
  import { Formatter } from '@sectester/reporter';
2
2
  import { ScanFactory, ScanSettingsOptions, Severity, TargetOptions } from '@sectester/scan';
3
+ export interface FunctionScanOptions<T> {
4
+ inputSample: T;
5
+ fn: (input: T) => Promise<unknown>;
6
+ }
3
7
  export declare class SecScan {
4
8
  private readonly settings;
5
9
  private readonly scanFactory;
@@ -7,9 +11,10 @@ export declare class SecScan {
7
11
  private _threshold;
8
12
  private _timeout;
9
13
  constructor(settings: Omit<ScanSettingsOptions, 'target'>, scanFactory: ScanFactory, formatter: Formatter);
10
- run(target: TargetOptions): Promise<void>;
14
+ run<T>(options: TargetOptions | FunctionScanOptions<T>): Promise<void>;
11
15
  threshold(severity: Severity): SecScan;
12
16
  timeout(value: number): SecScan;
13
17
  private assert;
14
18
  private findExpectedIssue;
19
+ private isFunctionScanOptions;
15
20
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SecScan = void 0;
4
+ const FunctionScanTarget_1 = require("./FunctionScanTarget");
4
5
  const IssueFound_1 = require("./IssueFound");
5
6
  const scan_1 = require("@sectester/scan");
6
7
  class SecScan {
@@ -11,10 +12,27 @@ class SecScan {
11
12
  this._threshold = scan_1.Severity.LOW;
12
13
  this._timeout = 600000;
13
14
  }
14
- async run(target) {
15
+ async run(options) {
16
+ let functionScanTarget;
17
+ let targetOptions;
18
+ if (this.isFunctionScanOptions(options)) {
19
+ functionScanTarget = new FunctionScanTarget_1.FunctionScanTarget();
20
+ const { url } = await functionScanTarget.start(options.fn);
21
+ targetOptions = {
22
+ url,
23
+ method: 'POST',
24
+ body: options.inputSample,
25
+ ...(typeof options.inputSample === 'object'
26
+ ? { headers: { 'content-type': 'application/json' } }
27
+ : {})
28
+ };
29
+ }
30
+ else {
31
+ targetOptions = options;
32
+ }
15
33
  const scan = await this.scanFactory.createScan({
16
34
  ...this.settings,
17
- target
35
+ target: targetOptions
18
36
  }, {
19
37
  timeout: this._timeout
20
38
  });
@@ -24,6 +42,7 @@ class SecScan {
24
42
  }
25
43
  finally {
26
44
  await scan.stop();
45
+ await (functionScanTarget === null || functionScanTarget === void 0 ? void 0 : functionScanTarget.stop());
27
46
  }
28
47
  }
29
48
  threshold(severity) {
@@ -46,6 +65,9 @@ class SecScan {
46
65
  return issues.find(x => { var _a; return (_a = scan_1.severityRanges.get(this._threshold)) === null || _a === void 0 ? void 0 : _a.includes(x.severity); });
47
66
  }
48
67
  }
68
+ isFunctionScanOptions(x) {
69
+ return !!x.fn;
70
+ }
49
71
  }
50
72
  exports.SecScan = SecScan;
51
73
  //# sourceMappingURL=SecScan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SecScan.js","sourceRoot":"","sources":["../../../../../packages/runner/src/lib/SecScan.ts"],"names":[],"mappings":";;;AAAA,6CAA0C;AAE1C,0CAQyB;AAEzB,MAAa,OAAO;IAIlB,YACmB,QAA6C,EAC7C,WAAwB,EACxB,SAAoB;QAFpB,aAAQ,GAAR,QAAQ,CAAqC;QAC7C,gBAAW,GAAX,WAAW,CAAa;QACxB,cAAS,GAAT,SAAS,CAAW;QAN/B,eAAU,GAAG,eAAQ,CAAC,GAAG,CAAC;QAC1B,aAAQ,GAAG,MAAO,CAAC;IAMxB,CAAC;IAEG,KAAK,CAAC,GAAG,CAAC,MAAqB;QACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAC5C;YACE,GAAG,IAAI,CAAC,QAAQ;YAChB,MAAM;SACP,EACD;YACE,OAAO,EAAE,IAAI,CAAC,QAAQ;SACvB,CACF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAEnC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAEM,SAAS,CAAC,QAAkB;QACjC,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;QAE3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,OAAO,CAAC,KAAa;QAC1B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAEtB,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,IAAU;QAC7B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAEjD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,uBAAU,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,IAAU;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAEnC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WACrB,OAAA,MAAA,qBAAc,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,0CAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA,EAAA,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AA3DD,0BA2DC"}
1
+ {"version":3,"file":"SecScan.js","sourceRoot":"","sources":["../../../../../packages/runner/src/lib/SecScan.ts"],"names":[],"mappings":";;;AAAA,6DAA0D;AAC1D,6CAA0C;AAE1C,0CAQyB;AAOzB,MAAa,OAAO;IAIlB,YACmB,QAA6C,EAC7C,WAAwB,EACxB,SAAoB;QAFpB,aAAQ,GAAR,QAAQ,CAAqC;QAC7C,gBAAW,GAAX,WAAW,CAAa;QACxB,cAAS,GAAT,SAAS,CAAW;QAN/B,eAAU,GAAG,eAAQ,CAAC,GAAG,CAAC;QAC1B,aAAQ,GAAG,MAAO,CAAC;IAMxB,CAAC;IAEG,KAAK,CAAC,GAAG,CACd,OAA+C;QAE/C,IAAI,kBAAkD,CAAC;QAEvD,IAAI,aAA4B,CAAC;QACjC,IAAI,IAAI,CAAC,qBAAqB,CAAI,OAAO,CAAC,EAAE,CAAC;YAC3C,kBAAkB,GAAG,IAAI,uCAAkB,EAAE,CAAC;YAC9C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAI,OAAO,CAAC,EAAE,CAAC,CAAC;YAE9D,aAAa,GAAG;gBACd,GAAG;gBACH,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,OAAO,CAAC,WAAW;gBACzB,GAAG,CAAC,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ;oBACzC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE;oBACrD,CAAC,CAAC,EAAE,CAAC;aACR,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,aAAa,GAAG,OAAO,CAAC;QAC1B,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAC5C;YACE,GAAG,IAAI,CAAC,QAAQ;YAChB,MAAM,EAAE,aAAa;SACtB,EACD;YACE,OAAO,EAAE,IAAI,CAAC,QAAQ;SACvB,CACF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAEnC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,CAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,IAAI,EAAE,CAAA,CAAC;QACnC,CAAC;IACH,CAAC;IAEM,SAAS,CAAC,QAAkB;QACjC,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;QAE3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,OAAO,CAAC,KAAa;QAC1B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAEtB,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,IAAU;QAC7B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAEjD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,uBAAU,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,IAAU;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAEnC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WACrB,OAAA,MAAA,qBAAc,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,0CAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA,EAAA,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,qBAAqB,CAAI,CAAM;QACrC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChB,CAAC;CACF;AArFD,0BAqFC"}