Skip to content

Commit

Permalink
fix(scan): truncate a file name if length exceed the limit (#94)
Browse files Browse the repository at this point in the history
fixes #93
  • Loading branch information
derevnjuk authored May 19, 2022
1 parent 3a2adab commit 311fefd
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 5 deletions.
3 changes: 2 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export {
isPresent,
isStream,
isString,
isURLSearchParams
isURLSearchParams,
truncate
} from './utils';
1 change: 1 addition & 0 deletions packages/core/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './contains';
export * from './delay';
export * from './first';
export * from './get-type-name';
export * from './truncate';
export * from './types';
21 changes: 21 additions & 0 deletions packages/core/src/utils/truncate.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { truncate } from './truncate';

describe('truncate', () => {
it.each([
{ input: { str: 'aa', n: 2 }, expected: 'aa' },
{ input: { str: 'test', n: 2 }, expected: 't…' },
{ input: { str: '', n: 2 }, expected: '' },
{ input: { str: 'test', n: 0 }, expected: '' },
{ input: { str: 'found a new issue', n: 6 }, expected: 'found ' },
{ input: { str: '******', n: 4 }, expected: '****' }
])(
'should return "$expected" for "$input.str" when limit is $input.n',
({ input, expected }) => {
// act
const result = truncate(input.str, input.n);

// assert
expect(result).toEqual(expected);
}
);
});
2 changes: 2 additions & 0 deletions packages/core/src/utils/truncate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const truncate = (str: string, n: number) =>
str.length > n ? str.substring(0, n).replace(/\w$/gi, '…') : str;
12 changes: 12 additions & 0 deletions packages/repeater/src/lib/RepeaterFactory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,5 +190,17 @@ describe('RepeaterFactory', () => {
)
).once();
});

it('should throw an error if name prefix is too long', async () => {
const factory = new RepeaterFactory(configuration);

const res = factory.createRepeater({
namePrefix: 'foo'.repeat(50)
});

await expect(res).rejects.toThrow(
'Name prefix must be less than 44 characters.'
);
});
});
});
4 changes: 4 additions & 0 deletions packages/repeater/src/lib/RepeaterFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export class RepeaterFactory {
namePrefix: `sec-tester`
}
): Promise<Repeater> {
if (namePrefix && namePrefix.length > 44) {
throw new Error('Name prefix must be less than 44 characters.');
}

this.registerRequestRunnerOptions(requestRunnerOptions);

const { repeaterId } = await this.repeatersManager.createRepeater({
Expand Down
31 changes: 31 additions & 0 deletions packages/scan/src/ScanFactory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from 'ts-mockito';
import { Configuration } from '@sec-tester/core';
import { DependencyContainer } from 'tsyringe';
import { randomBytes } from 'crypto';

describe('ScanFactory', () => {
const scanId = 'roMq1UVuhPKkndLERNKnA8';
Expand Down Expand Up @@ -99,5 +100,35 @@ describe('ScanFactory', () => {
)
).once();
});

it('should truncate a HAR filename if it is too long', async () => {
const settings: ScanSettingsOptions = {
target: {
url: `https://subdomain-${randomBytes(200).toString(
'hex'
)}.example.com`
},
tests: [TestType.DOM_XSS]
};
when(mockedScans.uploadHar(anything())).thenResolve({ id: fileId });
when(mockedScans.createScan(anything())).thenResolve({ id: scanId });

await scanFactory.createScan(settings);

verify(
mockedScans.uploadHar(
deepEqual({
discard: true,
filename: match(/^.{0,200}-[a-z\d-]+\.har$/),
har: objectContaining({
log: {
version: '1.2',
creator: { name: 'test', version: '1.0' }
}
})
})
)
).once();
});
});
});
5 changes: 3 additions & 2 deletions packages/scan/src/ScanFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Discovery, Module, ScanConfig } from './models';
import { ScanSettings, ScanSettingsOptions } from './ScanSettings';
import { Target, TargetOptions } from './target';
import { v4 } from 'uuid';
import { Configuration } from '@sec-tester/core';
import { Configuration, truncate } from '@sec-tester/core';
import { Entry, Har } from '@har-sdk/core';
import { DependencyContainer } from 'tsyringe';

Expand Down Expand Up @@ -76,8 +76,9 @@ export class ScanFactory {

private generateFilename(url: string): string {
const { hostname } = new URL(url);
const slug = truncate(hostname, 200);

return `${hostname}-${v4()}.har`;
return `${slug}-${v4()}.har`;
}

private createHarEntry(target: Target | TargetOptions): Entry {
Expand Down
4 changes: 2 additions & 2 deletions packages/scan/src/ScanSettings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AttackParamLocation, TestType } from './models';
import { Target, TargetOptions } from './target';
import { checkBoundaries, contains } from '@sec-tester/core';
import { checkBoundaries, contains, truncate } from '@sec-tester/core';

export interface ScanSettingsOptions {
// The list of tests to be performed against the target application
Expand Down Expand Up @@ -180,7 +180,7 @@ export class ScanSettings implements ScanSettingsOptions {
this.attackParamLocations = attackParamLocations;
this.target = target;
const { method, parsedURL } = this.target;
this.name = name || `${method} ${parsedURL.hostname}`.substring(0, 200);
this.name = name || truncate(`${method} ${parsedURL.hostname}`, 200);
this.poolSize = poolSize;
this.repeaterId = repeaterId;
this.skipStaticParams = skipStaticParams;
Expand Down

0 comments on commit 311fefd

Please sign in to comment.