Skip to content

feat(scan): add requests rate limit and update pool size #254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/scan/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ Below you will find a list of parameters that can be used to configure a `Scan`:
| `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`. |
| `poolSize` | Sets the maximum concurrent requests for the scan, to control the load on your server. By default, `50`. |
| `requestsRateLimit` | Controls the rate limit for requests during the scan. By default, `0` (automatic rate limiting). Maximum value is `1000`. |
| `attackParamLocations` | Defines which part of the request to attack. By default, automatically detected based on the target (includes `body`, `query`, and `fragment` when applicable). |
| `name` | The scan name. The method and pathname by default, e.g. `GET /users/1`. |

### Defining a target for attack
Expand Down
2 changes: 2 additions & 0 deletions packages/scan/src/ScanFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class ScanFactory {
repeaterId,
smart,
poolSize,
requestsRateLimit,
skipStaticParams,
attackParamLocations
}: ScanSettings): Promise<ScanConfig> {
Expand All @@ -52,6 +53,7 @@ export class ScanFactory {
name,
smart,
poolSize,
requestsRateLimit,
skipStaticParams,
projectId: this.configuration.projectId,
entryPointIds: [entrypointId],
Expand Down
12 changes: 12 additions & 0 deletions packages/scan/src/ScanSettings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ describe('ScanSettings', () => {
poolSize: 0
},
expected: 'Invalid pool size'
},
{
input: {
requestsRateLimit: 1001
},
expected: 'Invalid requests rate limit'
},
{
input: {
requestsRateLimit: -1
},
expected: 'Invalid requests rate limit'
}
])(
'should raise the error `$expected` when invalid config ($input) is supplied',
Expand Down
20 changes: 19 additions & 1 deletion packages/scan/src/ScanSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export interface ScanSettingsOptions {
smart?: boolean;
// Pool size
poolSize?: number;
// Requests rate limit
requestsRateLimit?: number;
// Allows to skip testing static parameters.
skipStaticParams?: boolean;
// Defines which part of the request to attack
Expand Down Expand Up @@ -89,6 +91,20 @@ export class ScanSettings implements ScanSettingsOptions {
this._poolSize = value;
}

private _requestsRateLimit!: number;

get requestsRateLimit(): number {
return this._requestsRateLimit;
}

private set requestsRateLimit(value: number) {
if (!checkBoundaries(value, { min: 0, max: 1000 })) {
throw new Error('Invalid requests rate limit.');
}

this._requestsRateLimit = value;
}

private _tests!: string[];

get tests(): string[] {
Expand Down Expand Up @@ -125,14 +141,16 @@ export class ScanSettings implements ScanSettingsOptions {
target,
repeaterId,
smart = true,
poolSize = 10,
requestsRateLimit = 0, // automatic rate limiting
poolSize = 50, // up to 2x more than default pool size
skipStaticParams = true,
attackParamLocations = []
}: ScanSettingsOptions) {
this.target = target;
const { method, parsedURL } = this.target;
this.name = name || truncate(`${method} ${parsedURL.pathname}`, 200);
this.poolSize = poolSize;
this.requestsRateLimit = requestsRateLimit;
this.repeaterId = repeaterId;
this.skipStaticParams = skipStaticParams;
this.smart = smart;
Expand Down
3 changes: 1 addition & 2 deletions packages/scan/src/models/ScanConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ export interface ScanConfig {
entryPointIds: string[];
tests?: string[];
poolSize?: number;
requestsRateLimit?: number;
attackParamLocations?: AttackParamLocation[];
repeaters?: string[];
smart?: boolean;
skipStaticParams?: boolean;
slowEpTimeout?: number;
targetTimeout?: number;
}