@sectester/scan
v0.33.3
Published
The package defines a simple public API to manage scans and their expectations.
Downloads
990
Readme
@sectester/scan
The package defines a simple public API to manage scans and their expectations.
Setup
npm i -s @sectester/scan
Usage
To start scanning your application, you have to create a ScanFactory
as follows:
import { Configuration } from '@sectester/core';
import { ScanFactory } from '@sectester/scan';
const config = new Configuration({
hostname: 'app.neuralegion.com'
});
const scanFactory = new ScanFactory(config);
To create a new scan, you have to define a target first (for details, see here):
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com'
});
The factory exposes the createScan
method that returns a new Scan instance:
import { TestType } from '@sectester/scan';
const scan = await scanFactory.createScan({
target,
tests: [TestType.HEADER_SECURITY]
});
Below you will find a list of parameters that can be used to configure a Scan
:
| Option | Description |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| target
| The target that will be attacked. For details, see here. |
| tests
| The list of tests to be performed against the target application. Learn more about tests |
| repeaterId
| Connects the scan to a Repeater agent, which provides secure access to local networks. |
| smart
| Minimize scan time by using automatic smart decisions regarding parameter skipping, detection phases, etc. Enabled by default. |
| skipStaticParams
| Use an advanced algorithm to automatically determine if a parameter has any effect on the target system's behavior when changed, and skip testing such static parameters. Enabled by default. |
| poolSize
| Sets the maximum concurrent requests for the scan, to control the load on your server. By default, 10
. |
| attackParamLocations
| Defines which part of the request to attack. By default, body
, query
, and fragment
. |
| slowEpTimeout
| Automatically validate entry-point response time before initiating the vulnerability testing, and reduce scan time by skipping any entry-points that take too long to respond. By default, 1000ms. |
| 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. |
| name
| The scan name. The method and hostname by default, e.g. GET example.com
. |
Defining a target for attack
The target can accept the following options:
url
- type:
string
The server URL that will be used for the request. Usually the url
represents a WHATWG URL:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com'
});
If url
contains a query string, they will be parsed as search params:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com?foo=bar'
});
console.log(target.queryString); // foo=bar
If you pass a query
parameter, it will override these which obtained from url
:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com?foo=bar',
query: '?bar=foo'
});
console.log(target.queryString); // bar=foo
method
- type:
string | HttpMethod
The request method to be used when making the request, GET
by default:
import { Target, HttpMethod } from '@sectester/scan';
const target = new Target({
url: 'https://example.com',
method: HttpMethod.DELETE
});
query
- type:
string | URLSearchParams | Record<string, string | string[]>
The query parameters to be sent with the request:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com',
query: {
hello: 'world',
foo: '123'
}
});
console.log(target.queryString); // hello=world&foo=123
If you need to pass an array, you can do it using a URLSearchParams
instance:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com',
query: new URLSearchParams([
['key', 'a'],
['key', 'b']
])
});
console.log(target.queryString); // key=a&key=b
This will override the query string in url.
It is possible to define a custom serializer for query parameters:
import { Target } from '@sectester/scan';
import { stringify } from 'qs';
const target = new Target({
url: 'https://example.com',
query: { a: ['b', 'c', 'd'] },
serializeQuery(params: Record<string, string | string[]>): string {
return stringify(params);
}
});
console.log(target.queryString); // a[0]=b&a[1]=c&a[2]=d
headers
- type:
Record<string, string | string[]>
The HTTP headers to be sent:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com',
headers: {
'content-type': 'application/json'
}
});
body
- type:
unknown
The data to be sent as the request body. Makes sense only for POST
, PUT
, PATCH
, and DELETE
:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com',
body: {
foo: 'bar'
}
});
You can use FormData
objects, such as form-data, as request body as well:
import { Target } from '@sectester/scan';
import FormData from 'form-data';
const form = new FormData();
form.append('greeting', 'Hello, world!');
const target = new Target({
url: 'https://example.com',
body: form
});
It is possible to set a form as body using an instance of URLSearchParams
:
import { Target } from '@sectester/scan';
const target = new Target({
url: 'https://example.com',
body: new URLSearchParams('foo=bar')
});
Managing a scan
The Scan
provides a lightweight API to revise and control the status of test execution.
For instance, to get a list of found issues, you can use the issues
method:
const issues = await scan.issues();
To wait for certain conditions you can use the expect
method:
await scan.expect(Severity.HIGH);
const issues = await scan.issues();
It returns control as soon as a scan is done, timeout is gone, or an expectation is satisfied.
You can also define a custom expectation passing a function that accepts an instance of Scan
as follows:
await scan.expect((scan: Scan) => scan.done);
It might return a Promise
instance as well:
await scan.expect(async (scan: Scan) => {
const issues = await scan.issues();
return issues.length > 3;
});
You can use the status
method to obtain scan status, to ensure that the scan is done and nothing prevents the user to check for issues, or for other reasons:
for await (const state of scan.status()) {
// your code
}
This
for...of
will work while a scan is active.
To stop scan, use the stop
method:
await scan.stop();
To dispose a scan, you just need to call the dispose
method:
await scan.dispose();
License
Copyright © 2024 Bright Security.
This project is licensed under the MIT License - see the LICENSE file for details.