npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sectester/scan

v0.33.3

Published

The package defines a simple public API to manage scans and their expectations.

Downloads

632

Readme

@sectester/scan

Maintainability Test Coverage Build Status NPM Downloads

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.