diff --git a/.brightsec/tests/get-addpage.test.ts b/.brightsec/tests/get-addpage.test.ts new file mode 100644 index 00000000..63811459 --- /dev/null +++ b/.brightsec/tests/get-addpage.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /AddPage', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['xss', 'excessive_data_exposure'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/AddPage?filename=example.html&content=%3Chtml%3E%3Cbody%3EHello%20World%3C/body%3E%3C/html%3E` + }); +}); diff --git a/.brightsec/tests/get-emailcheck.test.ts b/.brightsec/tests/get-emailcheck.test.ts new file mode 100644 index 00000000..26df1642 --- /dev/null +++ b/.brightsec/tests/get-emailcheck.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /EmailCheck', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'excessive_data_exposure', 'full_path_disclosure'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/EmailCheck?email=example@example.com` + }); +}); diff --git a/.brightsec/tests/get-forwardme.test.ts b/.brightsec/tests/get-forwardme.test.ts new file mode 100644 index 00000000..af54cdc3 --- /dev/null +++ b/.brightsec/tests/get-forwardme.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /forwardme', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['unvalidated_redirect', 'xss', 'excessive_data_exposure'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/ForwardMe?location=/example/path` + }); +}); diff --git a/.brightsec/tests/get-install.test.ts b/.brightsec/tests/get-install.test.ts new file mode 100644 index 00000000..42220373 --- /dev/null +++ b/.brightsec/tests/get-install.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /install', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'open_database', 'csrf', 'excessive_data_exposure', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/install?dburl=jdbc:mysql://localhost:3306/&jdbcdriver=com.mysql.jdbc.Driver&dbuser=root&dbpass=password&dbname=javavulnerablelab&siteTitle=Java+Vulnerable+Lab&adminuser=admin&adminpass=adminpass&setup=1` + }); +}); diff --git a/.brightsec/tests/get-login-validator.test.ts b/.brightsec/tests/get-login-validator.test.ts new file mode 100644 index 00000000..67512dd2 --- /dev/null +++ b/.brightsec/tests/get-login-validator.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /LoginValidator', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'xss', 'csrf', 'unvalidated_redirect', 'excessive_data_exposure', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/LoginValidator?username=exampleUser&password=examplePass` + }); +}); diff --git a/.brightsec/tests/get-open.test.ts b/.brightsec/tests/get-open.test.ts new file mode 100644 index 00000000..a956bbe2 --- /dev/null +++ b/.brightsec/tests/get-open.test.ts @@ -0,0 +1,36 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /Open', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['unvalidated_redirect', 'xss'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/Open?url=http://example.com`, + headers: { + 'Content-Type': 'text/html;charset=UTF-8' + } + }); +}); diff --git a/.brightsec/tests/get-register.test.ts b/.brightsec/tests/get-register.test.ts new file mode 100644 index 00000000..5e2b0339 --- /dev/null +++ b/.brightsec/tests/get-register.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /register', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'xss', 'csrf', 'excessive_data_exposure', 'unvalidated_redirect'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/register` + }); +}); diff --git a/.brightsec/tests/get-usernamecheck.test.ts b/.brightsec/tests/get-usernamecheck.test.ts new file mode 100644 index 00000000..85929c43 --- /dev/null +++ b/.brightsec/tests/get-usernamecheck.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /UsernameCheck', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'excessive_data_exposure', 'full_path_disclosure'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/UsernameCheck?username=sampleUser` + }); +}); diff --git a/.brightsec/tests/get-vulnerability-send-message.test.ts b/.brightsec/tests/get-vulnerability-send-message.test.ts new file mode 100644 index 00000000..98206a48 --- /dev/null +++ b/.brightsec/tests/get-vulnerability-send-message.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /vulnerability/SendMessage.jsp', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'xss', 'excessive_data_exposure', 'sqli', 'unvalidated_redirect'], + attackParamLocations: [AttackParamLocation.QUERY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/vulnerability/SendMessage.jsp?recipient=exampleRecipient&subject=exampleSubject&msg=exampleMessage&sender=exampleSender&send=true` + }); +}); diff --git a/.brightsec/tests/get-xpathquery.test.ts b/.brightsec/tests/get-xpathquery.test.ts new file mode 100644 index 00000000..9807e68e --- /dev/null +++ b/.brightsec/tests/get-xpathquery.test.ts @@ -0,0 +1,34 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /XPathQuery', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['xpathi', 'excessive_data_exposure', 'xss', 'csrf', 'full_path_disclosure'], + attackParamLocations: [AttackParamLocation.QUERY], + skipStaticParams: false + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/XPathQuery?username=sampleUser&password=samplePass` + }); +}); diff --git a/.brightsec/tests/get-xxe.test.ts b/.brightsec/tests/get-xxe.test.ts new file mode 100644 index 00000000..f1ce77ac --- /dev/null +++ b/.brightsec/tests/get-xxe.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('GET /xxe', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['xxe'], + attackParamLocations: [AttackParamLocation.PATH] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/xxe` + }); +}); diff --git a/.brightsec/tests/post-addpage.test.ts b/.brightsec/tests/post-addpage.test.ts new file mode 100644 index 00000000..bd78351d --- /dev/null +++ b/.brightsec/tests/post-addpage.test.ts @@ -0,0 +1,37 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /AddPage', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['file_upload', 'stored_xss', 'lfi', 'osi', 'excessive_data_exposure'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/AddPage`, + body: 'filename=example.html&content=Hello World', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } + }); +}); diff --git a/.brightsec/tests/post-emailcheck.test.ts b/.brightsec/tests/post-emailcheck.test.ts new file mode 100644 index 00000000..1a699d66 --- /dev/null +++ b/.brightsec/tests/post-emailcheck.test.ts @@ -0,0 +1,37 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /EmailCheck', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'excessive_data_exposure', 'xss', 'csrf', 'open_database'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/EmailCheck`, + body: 'email=example@example.com', + headers: { + 'Content-Type': 'application/json' + } + }); +}); diff --git a/.brightsec/tests/post-forward-me.test.ts b/.brightsec/tests/post-forward-me.test.ts new file mode 100644 index 00000000..514df6c0 --- /dev/null +++ b/.brightsec/tests/post-forward-me.test.ts @@ -0,0 +1,34 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /forward-me', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['unvalidated_redirect', 'xss'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/ForwardMe`, + body: 'location=/example/path' + }); +}); diff --git a/.brightsec/tests/post-install.test.ts b/.brightsec/tests/post-install.test.ts new file mode 100644 index 00000000..51ab7ed2 --- /dev/null +++ b/.brightsec/tests/post-install.test.ts @@ -0,0 +1,44 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /install', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'csrf', 'open_database', 'xss', 'excessive_data_exposure', 'osi'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/install`, + body: { + dburl: 'jdbc:mysql://localhost:3306/', + jdbcdriver: 'com.mysql.jdbc.Driver', + dbuser: 'root', + dbpass: 'password', + dbname: 'javavulnerablelab', + siteTitle: 'Java Vulnerable Lab', + adminuser: 'admin', + adminpass: 'adminpass', + setup: '1' + } + }); +}); diff --git a/.brightsec/tests/post-login-validator.test.ts b/.brightsec/tests/post-login-validator.test.ts new file mode 100644 index 00000000..334c1ab0 --- /dev/null +++ b/.brightsec/tests/post-login-validator.test.ts @@ -0,0 +1,35 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /LoginValidator', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'csrf', 'xss', 'unvalidated_redirect', 'excessive_data_exposure', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/LoginValidator`, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: 'username=exampleUser&password=examplePass' + }); +}); diff --git a/.brightsec/tests/post-open.test.ts b/.brightsec/tests/post-open.test.ts new file mode 100644 index 00000000..7475b014 --- /dev/null +++ b/.brightsec/tests/post-open.test.ts @@ -0,0 +1,36 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /Open', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['unvalidated_redirect', 'xss'], + attackParamLocations: [AttackParamLocation.BODY], + skipStaticParams: false + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/Open`, + headers: { 'Content-Type': 'text/html;charset=UTF-8' }, + body: 'url=http://example.com' + }); +}); diff --git a/.brightsec/tests/post-register.test.ts b/.brightsec/tests/post-register.test.ts new file mode 100644 index 00000000..88a355d1 --- /dev/null +++ b/.brightsec/tests/post-register.test.ts @@ -0,0 +1,35 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /register', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'xss', 'csrf', 'excessive_data_exposure', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/register`, + body: 'username=sampleUser&password=samplePass&email=sample%40email.com&About=Sample+about+text&secret=sampleSecret', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' } + }); +}); diff --git a/.brightsec/tests/post-username-check.test.ts b/.brightsec/tests/post-username-check.test.ts new file mode 100644 index 00000000..11ebba2e --- /dev/null +++ b/.brightsec/tests/post-username-check.test.ts @@ -0,0 +1,37 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /UsernameCheck', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'excessive_data_exposure', 'full_path_disclosure'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/UsernameCheck`, + headers: { + 'Content-Type': 'application/json' + }, + body: 'username=sampleUser' + }); +}); diff --git a/.brightsec/tests/post-vulnerability-send-message.test.ts b/.brightsec/tests/post-vulnerability-send-message.test.ts new file mode 100644 index 00000000..abb3e110 --- /dev/null +++ b/.brightsec/tests/post-vulnerability-send-message.test.ts @@ -0,0 +1,34 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /vulnerability/SendMessage.jsp', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'xss', 'excessive_data_exposure', 'sqli', 'open_database'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/vulnerability/SendMessage.jsp`, + body: 'recipient=exampleRecipient&subject=exampleSubject&msg=exampleMessage&sender=exampleSender&send=true' + }); +}); diff --git a/.brightsec/tests/post-xpathquery.test.ts b/.brightsec/tests/post-xpathquery.test.ts new file mode 100644 index 00000000..82e322e3 --- /dev/null +++ b/.brightsec/tests/post-xpathquery.test.ts @@ -0,0 +1,35 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /XPathQuery', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['xpathi', 'excessive_data_exposure', 'csrf', 'full_path_disclosure'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/XPathQuery`, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: 'username=sampleUser&password=samplePass' + }); +}); diff --git a/.brightsec/tests/post-xxe.test.ts b/.brightsec/tests/post-xxe.test.ts new file mode 100644 index 00000000..17a2a1d7 --- /dev/null +++ b/.brightsec/tests/post-xxe.test.ts @@ -0,0 +1,33 @@ +import { test, before, after } from 'node:test'; +import { Severity, AttackParamLocation, HttpMethod } from '@sectester/scan'; +import { SecRunner } from '@sectester/runner'; + +let runner!: SecRunner; + +before(async () => { + runner = new SecRunner({ + hostname: process.env.BRIGHT_HOSTNAME!, + projectId: process.env.BRIGHT_PROJECT_ID! + }); + + await runner.init(); +}); + +after(() => runner.clear()); + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +test('POST /xxe', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['xxe'], + attackParamLocations: [AttackParamLocation.BODY] + }) + .threshold(Severity.CRITICAL) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/xxe` + }); +}); diff --git a/.github/workflows/bright.yml b/.github/workflows/bright.yml new file mode 100644 index 00000000..dfdd6eef --- /dev/null +++ b/.github/workflows/bright.yml @@ -0,0 +1,55 @@ +name: Security Tests + +on: + pull_request: + branches: + - '**' + +permissions: + checks: write + contents: read + +jobs: + security-tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '22' + + - name: Install SecTester dependencies + run: npm install --save-dev @sectester/core @sectester/repeater @sectester/scan @sectester/runner + + - name: Set up Docker Compose + run: docker compose up --wait + env: + MYSQL_ROOT_PASSWORD: root + + - name: Verify application readiness + run: | + until nc -zv 127.0.0.1 8080; do + echo "Waiting for application to be ready..." + sleep 5 + done + + - name: Run security tests + env: + BRIGHT_HOSTNAME: ${{ vars.BRIGHT_HOSTNAME }} + BRIGHT_PROJECT_ID: ${{ vars.BRIGHT_PROJECT_ID }} + BRIGHT_TOKEN: ${{ secrets.BRIGHT_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRIGHT_TARGET_URL: http://127.0.0.1:8080 + run: | + node --experimental-transform-types \ + --experimental-strip-types \ + --experimental-detect-module \ + --disable-warning=MODULE_TYPELESS_PACKAGE_JSON \ + --disable-warning=ExperimentalWarning \ + --test-force-exit \ + --test .brightsec/tests/*.test.ts \ + --test-concurrency=4 \ No newline at end of file