From b814686edafc830184b5aff7223b58a4d172bad6 Mon Sep 17 00:00:00 2001 From: Viachaslau Date: Mon, 23 Feb 2026 12:12:23 +0400 Subject: [PATCH 1/5] chore: initialize workflow skip-checks:true --- .brightsec/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .brightsec/.gitkeep diff --git a/.brightsec/.gitkeep b/.brightsec/.gitkeep new file mode 100644 index 0000000..e69de29 From 4c8f913dd9f5d310c3b6489b94820d3dea1aadbf Mon Sep 17 00:00:00 2001 From: Viachaslau Date: Mon, 23 Feb 2026 12:32:57 +0400 Subject: [PATCH 2/5] ci: temporarily disable workflows while addressing security issues skip-checks:true From ff0965a97d53d64d36edc2e3c0d431fcd0748ff0 Mon Sep 17 00:00:00 2001 From: Viachaslau Date: Mon, 23 Feb 2026 12:34:51 +0400 Subject: [PATCH 3/5] test: add auto-generated e2e security tests skip-checks:true --- .brightsec/tests/delete-logout.test.ts | 40 +++++++++++++++ .brightsec/tests/delete-posts-1-json.test.ts | 41 ++++++++++++++++ .brightsec/tests/delete-posts-1.test.ts | 41 ++++++++++++++++ .brightsec/tests/delete-users-1-json.test.ts | 41 ++++++++++++++++ .brightsec/tests/delete-users-1.test.ts | 41 ++++++++++++++++ .brightsec/tests/get-login.test.ts | 40 +++++++++++++++ .brightsec/tests/get-posts-1-edit.test.ts | 40 +++++++++++++++ .brightsec/tests/get-posts-1.test.ts | 40 +++++++++++++++ .brightsec/tests/get-posts-json.test.ts | 41 ++++++++++++++++ .brightsec/tests/get-posts-search.test.ts | 41 ++++++++++++++++ .brightsec/tests/get-users-1-edit.test.ts | 40 +++++++++++++++ .brightsec/tests/get-users-1-json.test.ts | 41 ++++++++++++++++ .../tests/get-users-1-posts-new.test.ts | 40 +++++++++++++++ .brightsec/tests/get-users-1-posts.test.ts | 41 ++++++++++++++++ .brightsec/tests/get-users-1.test.ts | 40 +++++++++++++++ .brightsec/tests/get-users-new.test.ts | 40 +++++++++++++++ .brightsec/tests/get-users.test.ts | 40 +++++++++++++++ .brightsec/tests/patch-posts-1-json.test.ts | 48 ++++++++++++++++++ .brightsec/tests/patch-posts-1.test.ts | 46 +++++++++++++++++ .brightsec/tests/patch-users-1-json.test.ts | 49 +++++++++++++++++++ .brightsec/tests/patch-users-1.test.ts | 47 ++++++++++++++++++ .brightsec/tests/patch-users-123.test.ts | 47 ++++++++++++++++++ .brightsec/tests/post-posts.test.ts | 48 ++++++++++++++++++ .../tests/post-users-1-posts-json.test.ts | 48 ++++++++++++++++++ .brightsec/tests/post-users-json.test.ts | 49 +++++++++++++++++++ .brightsec/tests/post-users.test.ts | 49 +++++++++++++++++++ .brightsec/tests/put-posts-1-json.test.ts | 48 ++++++++++++++++++ .brightsec/tests/put-posts-1.test.ts | 48 ++++++++++++++++++ .brightsec/tests/put-users-1-json.test.ts | 49 +++++++++++++++++++ .brightsec/tests/put-users-1.test.ts | 47 ++++++++++++++++++ .brightsec/tests/put-users-123.test.ts | 47 ++++++++++++++++++ 31 files changed, 1358 insertions(+) create mode 100644 .brightsec/tests/delete-logout.test.ts create mode 100644 .brightsec/tests/delete-posts-1-json.test.ts create mode 100644 .brightsec/tests/delete-posts-1.test.ts create mode 100644 .brightsec/tests/delete-users-1-json.test.ts create mode 100644 .brightsec/tests/delete-users-1.test.ts create mode 100644 .brightsec/tests/get-login.test.ts create mode 100644 .brightsec/tests/get-posts-1-edit.test.ts create mode 100644 .brightsec/tests/get-posts-1.test.ts create mode 100644 .brightsec/tests/get-posts-json.test.ts create mode 100644 .brightsec/tests/get-posts-search.test.ts create mode 100644 .brightsec/tests/get-users-1-edit.test.ts create mode 100644 .brightsec/tests/get-users-1-json.test.ts create mode 100644 .brightsec/tests/get-users-1-posts-new.test.ts create mode 100644 .brightsec/tests/get-users-1-posts.test.ts create mode 100644 .brightsec/tests/get-users-1.test.ts create mode 100644 .brightsec/tests/get-users-new.test.ts create mode 100644 .brightsec/tests/get-users.test.ts create mode 100644 .brightsec/tests/patch-posts-1-json.test.ts create mode 100644 .brightsec/tests/patch-posts-1.test.ts create mode 100644 .brightsec/tests/patch-users-1-json.test.ts create mode 100644 .brightsec/tests/patch-users-1.test.ts create mode 100644 .brightsec/tests/patch-users-123.test.ts create mode 100644 .brightsec/tests/post-posts.test.ts create mode 100644 .brightsec/tests/post-users-1-posts-json.test.ts create mode 100644 .brightsec/tests/post-users-json.test.ts create mode 100644 .brightsec/tests/post-users.test.ts create mode 100644 .brightsec/tests/put-posts-1-json.test.ts create mode 100644 .brightsec/tests/put-posts-1.test.ts create mode 100644 .brightsec/tests/put-users-1-json.test.ts create mode 100644 .brightsec/tests/put-users-1.test.ts create mode 100644 .brightsec/tests/put-users-123.test.ts diff --git a/.brightsec/tests/delete-logout.test.ts b/.brightsec/tests/delete-logout.test.ts new file mode 100644 index 0000000..20359ba --- /dev/null +++ b/.brightsec/tests/delete-logout.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('DELETE /logout', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'http_method_fuzzing', 'session_fixation'], + attackParamLocations: [AttackParamLocation.HEADER], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.DELETE, + url: `${baseUrl}/logout`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/delete-posts-1-json.test.ts b/.brightsec/tests/delete-posts-1-json.test.ts new file mode 100644 index 0000000..51c9d6e --- /dev/null +++ b/.brightsec/tests/delete-posts-1-json.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('DELETE /posts/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'id_enumeration', 'sqli'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.DELETE, + url: `${baseUrl}/posts/1.json`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/delete-posts-1.test.ts b/.brightsec/tests/delete-posts-1.test.ts new file mode 100644 index 0000000..671c621 --- /dev/null +++ b/.brightsec/tests/delete-posts-1.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('DELETE /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'id_enumeration', 'sqli'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.DELETE, + url: `${baseUrl}/posts/1`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/delete-users-1-json.test.ts b/.brightsec/tests/delete-users-1-json.test.ts new file mode 100644 index 0000000..027e257 --- /dev/null +++ b/.brightsec/tests/delete-users-1-json.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('DELETE /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'id_enumeration', 'sqli', 'xss'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.DELETE, + url: `${baseUrl}/users/1.json`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/delete-users-1.test.ts b/.brightsec/tests/delete-users-1.test.ts new file mode 100644 index 0000000..9142885 --- /dev/null +++ b/.brightsec/tests/delete-users-1.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('DELETE /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'id_enumeration', 'sqli', 'xss'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.DELETE, + url: `${baseUrl}/users/1`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-login.test.ts b/.brightsec/tests/get-login.test.ts new file mode 100644 index 0000000..0210006 --- /dev/null +++ b/.brightsec/tests/get-login.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /login', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'xss', 'sqli', 'unvalidated_redirect', 'full_path_disclosure'], + attackParamLocations: [AttackParamLocation.PATH, AttackParamLocation.QUERY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/login`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-1-edit.test.ts b/.brightsec/tests/get-posts-1-edit.test.ts new file mode 100644 index 0000000..8496add --- /dev/null +++ b/.brightsec/tests/get-posts-1-edit.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /posts/1/edit', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'id_enumeration', 'sqli'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/posts/1/edit`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-1.test.ts b/.brightsec/tests/get-posts-1.test.ts new file mode 100644 index 0000000..600ddef --- /dev/null +++ b/.brightsec/tests/get-posts-1.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'id_enumeration', 'sqli', 'xss', 'bopla'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/posts/1`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-json.test.ts b/.brightsec/tests/get-posts-json.test.ts new file mode 100644 index 0000000..bde6352 --- /dev/null +++ b/.brightsec/tests/get-posts-json.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /posts.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'sqli', 'id_enumeration', 'csrf', 'xss'], + attackParamLocations: [AttackParamLocation.QUERY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/posts.json?user_id=1`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-search.test.ts b/.brightsec/tests/get-posts-search.test.ts new file mode 100644 index 0000000..01c26de --- /dev/null +++ b/.brightsec/tests/get-posts-search.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /posts/search', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['sqli', 'xss', 'csrf', 'business_constraint_bypass'], + attackParamLocations: [AttackParamLocation.QUERY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/posts/search?search_term=example`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-edit.test.ts b/.brightsec/tests/get-users-1-edit.test.ts new file mode 100644 index 0000000..2b92fe9 --- /dev/null +++ b/.brightsec/tests/get-users-1-edit.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /users/1/edit', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'id_enumeration', 'xss'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/users/1/edit`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-json.test.ts b/.brightsec/tests/get-users-1-json.test.ts new file mode 100644 index 0000000..9fed3e3 --- /dev/null +++ b/.brightsec/tests/get-users-1-json.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['id_enumeration', 'bopla', 'sqli', 'xss', 'csrf'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/users/1.json`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-posts-new.test.ts b/.brightsec/tests/get-users-1-posts-new.test.ts new file mode 100644 index 0000000..5097745 --- /dev/null +++ b/.brightsec/tests/get-users-1-posts-new.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /users/1/posts/new', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'xss', 'bopla', 'sqli'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/users/1/posts/new`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-posts.test.ts b/.brightsec/tests/get-users-1-posts.test.ts new file mode 100644 index 0000000..1f5c569 --- /dev/null +++ b/.brightsec/tests/get-users-1-posts.test.ts @@ -0,0 +1,41 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /users/1/posts', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'id_enumeration', 'sqli', 'xss'], + attackParamLocations: [AttackParamLocation.QUERY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/users/1/posts?user_id=1`, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1.test.ts b/.brightsec/tests/get-users-1.test.ts new file mode 100644 index 0000000..7ca5b69 --- /dev/null +++ b/.brightsec/tests/get-users-1.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['id_enumeration', 'bopla', 'sqli', 'xss', 'csrf'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/users/1`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-new.test.ts b/.brightsec/tests/get-users-new.test.ts new file mode 100644 index 0000000..3c7c3a2 --- /dev/null +++ b/.brightsec/tests/get-users-new.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /users/new', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'xss', 'html_injection', 'full_path_disclosure'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/users/new`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/get-users.test.ts b/.brightsec/tests/get-users.test.ts new file mode 100644 index 0000000..8139eda --- /dev/null +++ b/.brightsec/tests/get-users.test.ts @@ -0,0 +1,40 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('GET /users', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'id_enumeration', 'improper_asset_management', 'sqli', 'xss'], + attackParamLocations: [AttackParamLocation.PATH], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.GET, + url: `${baseUrl}/users`, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/patch-posts-1-json.test.ts b/.brightsec/tests/patch-posts-1-json.test.ts new file mode 100644 index 0000000..ce5e32d --- /dev/null +++ b/.brightsec/tests/patch-posts-1-json.test.ts @@ -0,0 +1,48 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PATCH /posts/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'sqli', 'xss'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PATCH, + url: `${baseUrl}/posts/1.json`, + body: { + post: { + title: 'Updated Title', + content: 'Updated content of the post.', + public: true + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/patch-posts-1.test.ts b/.brightsec/tests/patch-posts-1.test.ts new file mode 100644 index 0000000..ed2bad2 --- /dev/null +++ b/.brightsec/tests/patch-posts-1.test.ts @@ -0,0 +1,46 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PATCH /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'sqli', 'xss', 'id_enumeration'], + attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PATCH, + url: `${baseUrl}/posts/1`, + body: { + title: 'Updated Title', + content: 'Updated content of the post.', + public: true + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/patch-users-1-json.test.ts b/.brightsec/tests/patch-users-1-json.test.ts new file mode 100644 index 0000000..1c3f5dd --- /dev/null +++ b/.brightsec/tests/patch-users-1-json.test.ts @@ -0,0 +1,49 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PATCH /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'sqli', 'xss', 'id_enumeration'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PATCH, + url: `${baseUrl}/users/1.json`, + body: { + user: { + email: 'example@example.com', + password: 'securepassword', + password_digest: '$2a$12$KIXQ1Y1eY1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1', + admin: false + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/patch-users-1.test.ts b/.brightsec/tests/patch-users-1.test.ts new file mode 100644 index 0000000..227c2d0 --- /dev/null +++ b/.brightsec/tests/patch-users-1.test.ts @@ -0,0 +1,47 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PATCH /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'xss', 'sqli', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PATCH, + url: `${baseUrl}/users/1`, + body: { + email: 'newemail@example.com', + password: 'newpassword', + password_digest: 'newpassworddigest', + admin: false + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/patch-users-123.test.ts b/.brightsec/tests/patch-users-123.test.ts new file mode 100644 index 0000000..19d2767 --- /dev/null +++ b/.brightsec/tests/patch-users-123.test.ts @@ -0,0 +1,47 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PATCH /users/123', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'sqli', 'xss'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PATCH, + url: `${baseUrl}/users/123`, + body: { + email: 'newemail@example.com', + password: 'newpassword', + password_digest: 'newpassworddigest', + admin: false + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/post-posts.test.ts b/.brightsec/tests/post-posts.test.ts new file mode 100644 index 0000000..c885e64 --- /dev/null +++ b/.brightsec/tests/post-posts.test.ts @@ -0,0 +1,48 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('POST /posts', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'xss', 'sqli', 'bopla', 'osi'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/posts`, + body: { + post: { + title: 'Sample Title', + content: 'This is a sample post content.', + public: true + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/post-users-1-posts-json.test.ts b/.brightsec/tests/post-users-1-posts-json.test.ts new file mode 100644 index 0000000..6fa1cf9 --- /dev/null +++ b/.brightsec/tests/post-users-1-posts-json.test.ts @@ -0,0 +1,48 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('POST /users/1/posts.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'sqli', 'xss', 'id_enumeration'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/users/1/posts.json`, + body: { + post: { + title: 'Sample Title', + content: 'This is a sample post content.', + public: true + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/post-users-json.test.ts b/.brightsec/tests/post-users-json.test.ts new file mode 100644 index 0000000..b65aedd --- /dev/null +++ b/.brightsec/tests/post-users-json.test.ts @@ -0,0 +1,49 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('POST /users.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'sqli', 'xss', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/users.json`, + body: { + user: { + email: 'example@example.com', + password: 'password123', + password_digest: '$2a$12$KIXQ1eY5l1KIXQ1eY5l1KIXQ1eY5l1KIXQ1eY5l1KIXQ1eY5l1', + admin: false + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/post-users.test.ts b/.brightsec/tests/post-users.test.ts new file mode 100644 index 0000000..63c9687 --- /dev/null +++ b/.brightsec/tests/post-users.test.ts @@ -0,0 +1,49 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('POST /users', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'xss', 'sqli', 'bopla', 'email_injection', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.POST, + url: `${baseUrl}/users`, + body: { + user: { + email: 'example@example.com', + password: 'securepassword', + password_digest: '$2a$12$KIXQ1Y1rZ1u1u1u1u1u1uO', + admin: false + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/put-posts-1-json.test.ts b/.brightsec/tests/put-posts-1-json.test.ts new file mode 100644 index 0000000..a2e0743 --- /dev/null +++ b/.brightsec/tests/put-posts-1-json.test.ts @@ -0,0 +1,48 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PUT /posts/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['csrf', 'bopla', 'sqli', 'xss', 'id_enumeration'], + attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PUT, + url: `${baseUrl}/posts/1.json`, + body: { + post: { + title: 'Sample Title', + content: 'Sample content for the post.', + public: true + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/put-posts-1.test.ts b/.brightsec/tests/put-posts-1.test.ts new file mode 100644 index 0000000..daa3619 --- /dev/null +++ b/.brightsec/tests/put-posts-1.test.ts @@ -0,0 +1,48 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PUT /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'sqli', 'xss'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PUT, + url: `${baseUrl}/posts/1`, + body: { + post: { + title: 'Sample Title', + content: 'Sample content for the post.', + public: true + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/put-users-1-json.test.ts b/.brightsec/tests/put-users-1-json.test.ts new file mode 100644 index 0000000..2875438 --- /dev/null +++ b/.brightsec/tests/put-users-1-json.test.ts @@ -0,0 +1,49 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PUT /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'sqli', 'xss', 'unvalidated_redirect'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PUT, + url: `${baseUrl}/users/1.json`, + body: { + user: { + email: 'example@example.com', + password: 'securepassword', + password_digest: '$2a$12$KIXQ1Y1rZ1u1Z1u1Z1u1Z.1Z1u1Z1u1Z1u1Z1u1Z1u1Z1u1Z1u', + admin: false + } + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/put-users-1.test.ts b/.brightsec/tests/put-users-1.test.ts new file mode 100644 index 0000000..a3951d7 --- /dev/null +++ b/.brightsec/tests/put-users-1.test.ts @@ -0,0 +1,47 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PUT /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'sqli', 'xss', 'id_enumeration'], + attackParamLocations: [AttackParamLocation.BODY], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PUT, + url: `${baseUrl}/users/1`, + body: { + email: 'user@example.com', + password: 'securepassword', + password_digest: '$2a$12$KIXQ1Y1rZ1u1Q1', + admin: false + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file diff --git a/.brightsec/tests/put-users-123.test.ts b/.brightsec/tests/put-users-123.test.ts new file mode 100644 index 0000000..f6ec560 --- /dev/null +++ b/.brightsec/tests/put-users-123.test.ts @@ -0,0 +1,47 @@ +import { test, before, after } from 'node:test'; +import { SecRunner } from '@sectester/runner'; +import { AttackParamLocation, HttpMethod } from '@sectester/scan'; + +const timeout = 40 * 60 * 1000; +const baseUrl = process.env.BRIGHT_TARGET_URL!; + +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()); + +test('PUT /users/123', { signal: AbortSignal.timeout(timeout) }, async () => { + await runner + .createScan({ + tests: ['bopla', 'csrf', 'sqli', 'xss', 'secret_tokens'], + attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], + starMetadata: { + code_source: 'NeuraLegion/ruby-example-app:chore/docker', + databases: ['PostgreSQL'], + user_roles: ['admin'] + }, + poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined + }) + .setFailFast(false) + .timeout(timeout) + .run({ + method: HttpMethod.PUT, + url: `${baseUrl}/users/123`, + body: { + email: 'newemail@example.com', + password: 'newpassword', + password_digest: 'newpassworddigest', + admin: false + }, + headers: { 'Content-Type': 'application/json' }, + auth: process.env.BRIGHT_AUTH_ID + }); +}); \ No newline at end of file From 697eea8ed5fec6156d3dda6e16046138658537fb Mon Sep 17 00:00:00 2001 From: Viachaslau Date: Mon, 23 Feb 2026 12:35:03 +0400 Subject: [PATCH 4/5] ci: add CI workflow to run e2e security tests --- .github/workflows/bright.yml | 61 +++++++++++++++++++ .../configure-bright-credentials/action.yaml | 53 ++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 .github/workflows/bright.yml create mode 100644 .github/workflows/composite/configure-bright-credentials/action.yaml diff --git a/.github/workflows/bright.yml b/.github/workflows/bright.yml new file mode 100644 index 0000000..0ba511f --- /dev/null +++ b/.github/workflows/bright.yml @@ -0,0 +1,61 @@ +name: Bright + +on: + pull_request: + branches: + - '**' + +permissions: + checks: write + contents: read + id-token: write + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.x' + + - name: Start application + run: | + docker compose up --wait + env: + PGDATABASE: blog_development + PGHOST: db + PGPASSWORD: postgres + PGPORT: 5432 + PGUSER: postgres + RAILS_ENV: development + + - name: Wait for application to be ready + run: | + i=1; while [ "$i" -le 30 ]; do curl -sS -o /dev/null http://127.0.0.1:3000 && exit 0; sleep 5; i=$((i + 1)); done; exit 1 + + - name: Install SecTesterJS dependencies + run: | + npm i --save=false --prefix .brightsec @sectester/core@0.49.0 @sectester/repeater@0.49.0 @sectester/scan@0.49.0 @sectester/runner@0.49.0 @sectester/reporter@0.49.0 + + - name: Authenticate with Bright + uses: ./.github/workflows/composite/configure-bright-credentials + with: + BRIGHT_HOSTNAME: development.playground.brightsec.com + BRIGHT_PROJECT_ID: 5naKKxNc3e4Akp1GuEdmiK + BRIGHT_TOKEN: ${{ secrets.BRIGHT_TOKEN }} + + - name: Run security tests + run: | + node --experimental-transform-types --experimental-strip-types --experimental-detect-module --disable-warning=MODULE_TYPELESS_PACKAGE_JSON --disable-warning=ExperimentalWarning --test-force-exit --test-concurrency=4 --test .brightsec/tests/*.test.ts + env: + BRIGHT_HOSTNAME: development.playground.brightsec.com + BRIGHT_PROJECT_ID: 5naKKxNc3e4Akp1GuEdmiK + BRIGHT_AUTH_ID: m8XBzLrw8pWSjHQDhKQgCr + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRIGHT_TOKEN: ${{ env.BRIGHT_TOKEN }} + BRIGHT_TARGET_URL: http://127.0.0.1:3000 + SECTESTER_SCAN_POOL_SIZE: ${{ vars.SECTESTER_SCAN_POOL_SIZE }} \ No newline at end of file diff --git a/.github/workflows/composite/configure-bright-credentials/action.yaml b/.github/workflows/composite/configure-bright-credentials/action.yaml new file mode 100644 index 0000000..8498384 --- /dev/null +++ b/.github/workflows/composite/configure-bright-credentials/action.yaml @@ -0,0 +1,53 @@ +name: 'Configure BrightSec credentials' + +inputs: + BRIGHT_HOSTNAME: + description: 'Hostname for the BrightSec environment' + required: true + BRIGHT_PROJECT_ID: + description: 'Project ID for BrightSec' + required: true + BRIGHT_TOKEN: + description: 'Pre-configured token' + required: false + +runs: + using: 'composite' + steps: + - id: configure_env_from_input + name: 'Set existing token in env' + shell: bash + if: ${{ inputs.BRIGHT_TOKEN != '' }} + env: + BRIGHT_TOKEN: ${{ inputs.BRIGHT_TOKEN }} + run: | + echo "BRIGHT_TOKEN=${BRIGHT_TOKEN}" >> $GITHUB_ENV + + - id: configure_bright_credentials_through_oidc + name: 'Exchange OIDC credentials for Bright token' + shell: bash + if: ${{ inputs.BRIGHT_TOKEN == '' }} + env: + BRIGHT_HOSTNAME: ${{ inputs.BRIGHT_HOSTNAME }} + BRIGHT_PROJECT_ID: ${{ inputs.BRIGHT_PROJECT_ID }} + run: | + # Retrieve OIDC token from GitHub + OIDC_TOKEN=$(curl -sS -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ + "${ACTIONS_ID_TOKEN_REQUEST_URL}" | jq -r '.value') + + # Post the token to BrightSec + RESPONSE=$(curl -s -X POST "https://${BRIGHT_HOSTNAME}/api/v1/projects/${BRIGHT_PROJECT_ID}/api-keys/oidc" \ + -H "Content-Type: application/json" \ + -d "{\"token\": \"${OIDC_TOKEN}\"}") + + if ! echo "$RESPONSE" | jq -e . > /dev/null 2>&1; then + echo "Error: $RESPONSE" 1>&2 + exit 1 + fi + + # Extract the pureKey + PURE_KEY=$(echo "$RESPONSE" | jq -r '.pureKey') + + # Mask and store in environment + echo "::add-mask::$PURE_KEY" + echo "BRIGHT_TOKEN=$PURE_KEY" >> $GITHUB_ENV From 5262b146cdf39faef555cb513c951341592ae602 Mon Sep 17 00:00:00 2001 From: Viachaslau Date: Mon, 23 Feb 2026 14:25:44 +0400 Subject: [PATCH 5/5] revert: restore original workflow files and remove temporary one --- .brightsec/tests/delete-logout.test.ts | 40 ------------ .brightsec/tests/delete-posts-1-json.test.ts | 41 ------------- .brightsec/tests/delete-posts-1.test.ts | 41 ------------- .brightsec/tests/delete-users-1-json.test.ts | 41 ------------- .brightsec/tests/delete-users-1.test.ts | 41 ------------- .brightsec/tests/get-login.test.ts | 40 ------------ .brightsec/tests/get-posts-1-edit.test.ts | 40 ------------ .brightsec/tests/get-posts-1.test.ts | 40 ------------ .brightsec/tests/get-posts-json.test.ts | 41 ------------- .brightsec/tests/get-posts-search.test.ts | 41 ------------- .brightsec/tests/get-users-1-edit.test.ts | 40 ------------ .brightsec/tests/get-users-1-json.test.ts | 41 ------------- .../tests/get-users-1-posts-new.test.ts | 40 ------------ .brightsec/tests/get-users-1-posts.test.ts | 41 ------------- .brightsec/tests/get-users-1.test.ts | 40 ------------ .brightsec/tests/get-users-new.test.ts | 40 ------------ .brightsec/tests/get-users.test.ts | 40 ------------ .brightsec/tests/patch-posts-1-json.test.ts | 48 --------------- .brightsec/tests/patch-posts-1.test.ts | 46 -------------- .brightsec/tests/patch-users-1-json.test.ts | 49 --------------- .brightsec/tests/patch-users-1.test.ts | 47 -------------- .brightsec/tests/patch-users-123.test.ts | 47 -------------- .brightsec/tests/post-posts.test.ts | 48 --------------- .../tests/post-users-1-posts-json.test.ts | 48 --------------- .brightsec/tests/post-users-json.test.ts | 49 --------------- .brightsec/tests/post-users.test.ts | 49 --------------- .brightsec/tests/put-posts-1-json.test.ts | 48 --------------- .brightsec/tests/put-posts-1.test.ts | 48 --------------- .brightsec/tests/put-users-1-json.test.ts | 49 --------------- .brightsec/tests/put-users-1.test.ts | 47 -------------- .brightsec/tests/put-users-123.test.ts | 47 -------------- .github/workflows/bright.yml | 61 ------------------- .../configure-bright-credentials/action.yaml | 53 ---------------- 33 files changed, 1472 deletions(-) delete mode 100644 .brightsec/tests/delete-logout.test.ts delete mode 100644 .brightsec/tests/delete-posts-1-json.test.ts delete mode 100644 .brightsec/tests/delete-posts-1.test.ts delete mode 100644 .brightsec/tests/delete-users-1-json.test.ts delete mode 100644 .brightsec/tests/delete-users-1.test.ts delete mode 100644 .brightsec/tests/get-login.test.ts delete mode 100644 .brightsec/tests/get-posts-1-edit.test.ts delete mode 100644 .brightsec/tests/get-posts-1.test.ts delete mode 100644 .brightsec/tests/get-posts-json.test.ts delete mode 100644 .brightsec/tests/get-posts-search.test.ts delete mode 100644 .brightsec/tests/get-users-1-edit.test.ts delete mode 100644 .brightsec/tests/get-users-1-json.test.ts delete mode 100644 .brightsec/tests/get-users-1-posts-new.test.ts delete mode 100644 .brightsec/tests/get-users-1-posts.test.ts delete mode 100644 .brightsec/tests/get-users-1.test.ts delete mode 100644 .brightsec/tests/get-users-new.test.ts delete mode 100644 .brightsec/tests/get-users.test.ts delete mode 100644 .brightsec/tests/patch-posts-1-json.test.ts delete mode 100644 .brightsec/tests/patch-posts-1.test.ts delete mode 100644 .brightsec/tests/patch-users-1-json.test.ts delete mode 100644 .brightsec/tests/patch-users-1.test.ts delete mode 100644 .brightsec/tests/patch-users-123.test.ts delete mode 100644 .brightsec/tests/post-posts.test.ts delete mode 100644 .brightsec/tests/post-users-1-posts-json.test.ts delete mode 100644 .brightsec/tests/post-users-json.test.ts delete mode 100644 .brightsec/tests/post-users.test.ts delete mode 100644 .brightsec/tests/put-posts-1-json.test.ts delete mode 100644 .brightsec/tests/put-posts-1.test.ts delete mode 100644 .brightsec/tests/put-users-1-json.test.ts delete mode 100644 .brightsec/tests/put-users-1.test.ts delete mode 100644 .brightsec/tests/put-users-123.test.ts delete mode 100644 .github/workflows/bright.yml delete mode 100644 .github/workflows/composite/configure-bright-credentials/action.yaml diff --git a/.brightsec/tests/delete-logout.test.ts b/.brightsec/tests/delete-logout.test.ts deleted file mode 100644 index 20359ba..0000000 --- a/.brightsec/tests/delete-logout.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('DELETE /logout', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'http_method_fuzzing', 'session_fixation'], - attackParamLocations: [AttackParamLocation.HEADER], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.DELETE, - url: `${baseUrl}/logout`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/delete-posts-1-json.test.ts b/.brightsec/tests/delete-posts-1-json.test.ts deleted file mode 100644 index 51c9d6e..0000000 --- a/.brightsec/tests/delete-posts-1-json.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('DELETE /posts/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'id_enumeration', 'sqli'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.DELETE, - url: `${baseUrl}/posts/1.json`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/delete-posts-1.test.ts b/.brightsec/tests/delete-posts-1.test.ts deleted file mode 100644 index 671c621..0000000 --- a/.brightsec/tests/delete-posts-1.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('DELETE /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'id_enumeration', 'sqli'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.DELETE, - url: `${baseUrl}/posts/1`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/delete-users-1-json.test.ts b/.brightsec/tests/delete-users-1-json.test.ts deleted file mode 100644 index 027e257..0000000 --- a/.brightsec/tests/delete-users-1-json.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('DELETE /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'id_enumeration', 'sqli', 'xss'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.DELETE, - url: `${baseUrl}/users/1.json`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/delete-users-1.test.ts b/.brightsec/tests/delete-users-1.test.ts deleted file mode 100644 index 9142885..0000000 --- a/.brightsec/tests/delete-users-1.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('DELETE /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'id_enumeration', 'sqli', 'xss'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.DELETE, - url: `${baseUrl}/users/1`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-login.test.ts b/.brightsec/tests/get-login.test.ts deleted file mode 100644 index 0210006..0000000 --- a/.brightsec/tests/get-login.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /login', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'xss', 'sqli', 'unvalidated_redirect', 'full_path_disclosure'], - attackParamLocations: [AttackParamLocation.PATH, AttackParamLocation.QUERY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/login`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-1-edit.test.ts b/.brightsec/tests/get-posts-1-edit.test.ts deleted file mode 100644 index 8496add..0000000 --- a/.brightsec/tests/get-posts-1-edit.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /posts/1/edit', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'id_enumeration', 'sqli'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/posts/1/edit`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-1.test.ts b/.brightsec/tests/get-posts-1.test.ts deleted file mode 100644 index 600ddef..0000000 --- a/.brightsec/tests/get-posts-1.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'id_enumeration', 'sqli', 'xss', 'bopla'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/posts/1`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-json.test.ts b/.brightsec/tests/get-posts-json.test.ts deleted file mode 100644 index bde6352..0000000 --- a/.brightsec/tests/get-posts-json.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /posts.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'sqli', 'id_enumeration', 'csrf', 'xss'], - attackParamLocations: [AttackParamLocation.QUERY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/posts.json?user_id=1`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-posts-search.test.ts b/.brightsec/tests/get-posts-search.test.ts deleted file mode 100644 index 01c26de..0000000 --- a/.brightsec/tests/get-posts-search.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /posts/search', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['sqli', 'xss', 'csrf', 'business_constraint_bypass'], - attackParamLocations: [AttackParamLocation.QUERY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/posts/search?search_term=example`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-edit.test.ts b/.brightsec/tests/get-users-1-edit.test.ts deleted file mode 100644 index 2b92fe9..0000000 --- a/.brightsec/tests/get-users-1-edit.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /users/1/edit', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'id_enumeration', 'xss'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/users/1/edit`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-json.test.ts b/.brightsec/tests/get-users-1-json.test.ts deleted file mode 100644 index 9fed3e3..0000000 --- a/.brightsec/tests/get-users-1-json.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['id_enumeration', 'bopla', 'sqli', 'xss', 'csrf'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/users/1.json`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-posts-new.test.ts b/.brightsec/tests/get-users-1-posts-new.test.ts deleted file mode 100644 index 5097745..0000000 --- a/.brightsec/tests/get-users-1-posts-new.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /users/1/posts/new', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'xss', 'bopla', 'sqli'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/users/1/posts/new`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1-posts.test.ts b/.brightsec/tests/get-users-1-posts.test.ts deleted file mode 100644 index 1f5c569..0000000 --- a/.brightsec/tests/get-users-1-posts.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /users/1/posts', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'id_enumeration', 'sqli', 'xss'], - attackParamLocations: [AttackParamLocation.QUERY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/users/1/posts?user_id=1`, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-1.test.ts b/.brightsec/tests/get-users-1.test.ts deleted file mode 100644 index 7ca5b69..0000000 --- a/.brightsec/tests/get-users-1.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['id_enumeration', 'bopla', 'sqli', 'xss', 'csrf'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/users/1`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-users-new.test.ts b/.brightsec/tests/get-users-new.test.ts deleted file mode 100644 index 3c7c3a2..0000000 --- a/.brightsec/tests/get-users-new.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /users/new', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'xss', 'html_injection', 'full_path_disclosure'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/users/new`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/get-users.test.ts b/.brightsec/tests/get-users.test.ts deleted file mode 100644 index 8139eda..0000000 --- a/.brightsec/tests/get-users.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('GET /users', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'id_enumeration', 'improper_asset_management', 'sqli', 'xss'], - attackParamLocations: [AttackParamLocation.PATH], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.GET, - url: `${baseUrl}/users`, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/patch-posts-1-json.test.ts b/.brightsec/tests/patch-posts-1-json.test.ts deleted file mode 100644 index ce5e32d..0000000 --- a/.brightsec/tests/patch-posts-1-json.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PATCH /posts/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'sqli', 'xss'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PATCH, - url: `${baseUrl}/posts/1.json`, - body: { - post: { - title: 'Updated Title', - content: 'Updated content of the post.', - public: true - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/patch-posts-1.test.ts b/.brightsec/tests/patch-posts-1.test.ts deleted file mode 100644 index ed2bad2..0000000 --- a/.brightsec/tests/patch-posts-1.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PATCH /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'sqli', 'xss', 'id_enumeration'], - attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PATCH, - url: `${baseUrl}/posts/1`, - body: { - title: 'Updated Title', - content: 'Updated content of the post.', - public: true - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/patch-users-1-json.test.ts b/.brightsec/tests/patch-users-1-json.test.ts deleted file mode 100644 index 1c3f5dd..0000000 --- a/.brightsec/tests/patch-users-1-json.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PATCH /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'sqli', 'xss', 'id_enumeration'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PATCH, - url: `${baseUrl}/users/1.json`, - body: { - user: { - email: 'example@example.com', - password: 'securepassword', - password_digest: '$2a$12$KIXQ1Y1eY1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1Y1', - admin: false - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/patch-users-1.test.ts b/.brightsec/tests/patch-users-1.test.ts deleted file mode 100644 index 227c2d0..0000000 --- a/.brightsec/tests/patch-users-1.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PATCH /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'xss', 'sqli', 'secret_tokens'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PATCH, - url: `${baseUrl}/users/1`, - body: { - email: 'newemail@example.com', - password: 'newpassword', - password_digest: 'newpassworddigest', - admin: false - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/patch-users-123.test.ts b/.brightsec/tests/patch-users-123.test.ts deleted file mode 100644 index 19d2767..0000000 --- a/.brightsec/tests/patch-users-123.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PATCH /users/123', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'sqli', 'xss'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PATCH, - url: `${baseUrl}/users/123`, - body: { - email: 'newemail@example.com', - password: 'newpassword', - password_digest: 'newpassworddigest', - admin: false - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/post-posts.test.ts b/.brightsec/tests/post-posts.test.ts deleted file mode 100644 index c885e64..0000000 --- a/.brightsec/tests/post-posts.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('POST /posts', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'xss', 'sqli', 'bopla', 'osi'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.POST, - url: `${baseUrl}/posts`, - body: { - post: { - title: 'Sample Title', - content: 'This is a sample post content.', - public: true - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/post-users-1-posts-json.test.ts b/.brightsec/tests/post-users-1-posts-json.test.ts deleted file mode 100644 index 6fa1cf9..0000000 --- a/.brightsec/tests/post-users-1-posts-json.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('POST /users/1/posts.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'sqli', 'xss', 'id_enumeration'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.POST, - url: `${baseUrl}/users/1/posts.json`, - body: { - post: { - title: 'Sample Title', - content: 'This is a sample post content.', - public: true - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/post-users-json.test.ts b/.brightsec/tests/post-users-json.test.ts deleted file mode 100644 index b65aedd..0000000 --- a/.brightsec/tests/post-users-json.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('POST /users.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'sqli', 'xss', 'secret_tokens'], - attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.POST, - url: `${baseUrl}/users.json`, - body: { - user: { - email: 'example@example.com', - password: 'password123', - password_digest: '$2a$12$KIXQ1eY5l1KIXQ1eY5l1KIXQ1eY5l1KIXQ1eY5l1KIXQ1eY5l1', - admin: false - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/post-users.test.ts b/.brightsec/tests/post-users.test.ts deleted file mode 100644 index 63c9687..0000000 --- a/.brightsec/tests/post-users.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('POST /users', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'xss', 'sqli', 'bopla', 'email_injection', 'secret_tokens'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.POST, - url: `${baseUrl}/users`, - body: { - user: { - email: 'example@example.com', - password: 'securepassword', - password_digest: '$2a$12$KIXQ1Y1rZ1u1u1u1u1u1uO', - admin: false - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/put-posts-1-json.test.ts b/.brightsec/tests/put-posts-1-json.test.ts deleted file mode 100644 index a2e0743..0000000 --- a/.brightsec/tests/put-posts-1-json.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PUT /posts/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['csrf', 'bopla', 'sqli', 'xss', 'id_enumeration'], - attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PUT, - url: `${baseUrl}/posts/1.json`, - body: { - post: { - title: 'Sample Title', - content: 'Sample content for the post.', - public: true - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/put-posts-1.test.ts b/.brightsec/tests/put-posts-1.test.ts deleted file mode 100644 index daa3619..0000000 --- a/.brightsec/tests/put-posts-1.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PUT /posts/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'sqli', 'xss'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PUT, - url: `${baseUrl}/posts/1`, - body: { - post: { - title: 'Sample Title', - content: 'Sample content for the post.', - public: true - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/put-users-1-json.test.ts b/.brightsec/tests/put-users-1-json.test.ts deleted file mode 100644 index 2875438..0000000 --- a/.brightsec/tests/put-users-1-json.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PUT /users/1.json', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'sqli', 'xss', 'unvalidated_redirect'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PUT, - url: `${baseUrl}/users/1.json`, - body: { - user: { - email: 'example@example.com', - password: 'securepassword', - password_digest: '$2a$12$KIXQ1Y1rZ1u1Z1u1Z1u1Z.1Z1u1Z1u1Z1u1Z1u1Z1u1Z1u1Z1u', - admin: false - } - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/put-users-1.test.ts b/.brightsec/tests/put-users-1.test.ts deleted file mode 100644 index a3951d7..0000000 --- a/.brightsec/tests/put-users-1.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PUT /users/1', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'sqli', 'xss', 'id_enumeration'], - attackParamLocations: [AttackParamLocation.BODY], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PUT, - url: `${baseUrl}/users/1`, - body: { - email: 'user@example.com', - password: 'securepassword', - password_digest: '$2a$12$KIXQ1Y1rZ1u1Q1', - admin: false - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.brightsec/tests/put-users-123.test.ts b/.brightsec/tests/put-users-123.test.ts deleted file mode 100644 index f6ec560..0000000 --- a/.brightsec/tests/put-users-123.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { test, before, after } from 'node:test'; -import { SecRunner } from '@sectester/runner'; -import { AttackParamLocation, HttpMethod } from '@sectester/scan'; - -const timeout = 40 * 60 * 1000; -const baseUrl = process.env.BRIGHT_TARGET_URL!; - -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()); - -test('PUT /users/123', { signal: AbortSignal.timeout(timeout) }, async () => { - await runner - .createScan({ - tests: ['bopla', 'csrf', 'sqli', 'xss', 'secret_tokens'], - attackParamLocations: [AttackParamLocation.BODY, AttackParamLocation.HEADER], - starMetadata: { - code_source: 'NeuraLegion/ruby-example-app:chore/docker', - databases: ['PostgreSQL'], - user_roles: ['admin'] - }, - poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined - }) - .setFailFast(false) - .timeout(timeout) - .run({ - method: HttpMethod.PUT, - url: `${baseUrl}/users/123`, - body: { - email: 'newemail@example.com', - password: 'newpassword', - password_digest: 'newpassworddigest', - admin: false - }, - headers: { 'Content-Type': 'application/json' }, - auth: process.env.BRIGHT_AUTH_ID - }); -}); \ No newline at end of file diff --git a/.github/workflows/bright.yml b/.github/workflows/bright.yml deleted file mode 100644 index 0ba511f..0000000 --- a/.github/workflows/bright.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Bright - -on: - pull_request: - branches: - - '**' - -permissions: - checks: write - contents: read - id-token: write - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Check out code - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '22.x' - - - name: Start application - run: | - docker compose up --wait - env: - PGDATABASE: blog_development - PGHOST: db - PGPASSWORD: postgres - PGPORT: 5432 - PGUSER: postgres - RAILS_ENV: development - - - name: Wait for application to be ready - run: | - i=1; while [ "$i" -le 30 ]; do curl -sS -o /dev/null http://127.0.0.1:3000 && exit 0; sleep 5; i=$((i + 1)); done; exit 1 - - - name: Install SecTesterJS dependencies - run: | - npm i --save=false --prefix .brightsec @sectester/core@0.49.0 @sectester/repeater@0.49.0 @sectester/scan@0.49.0 @sectester/runner@0.49.0 @sectester/reporter@0.49.0 - - - name: Authenticate with Bright - uses: ./.github/workflows/composite/configure-bright-credentials - with: - BRIGHT_HOSTNAME: development.playground.brightsec.com - BRIGHT_PROJECT_ID: 5naKKxNc3e4Akp1GuEdmiK - BRIGHT_TOKEN: ${{ secrets.BRIGHT_TOKEN }} - - - name: Run security tests - run: | - node --experimental-transform-types --experimental-strip-types --experimental-detect-module --disable-warning=MODULE_TYPELESS_PACKAGE_JSON --disable-warning=ExperimentalWarning --test-force-exit --test-concurrency=4 --test .brightsec/tests/*.test.ts - env: - BRIGHT_HOSTNAME: development.playground.brightsec.com - BRIGHT_PROJECT_ID: 5naKKxNc3e4Akp1GuEdmiK - BRIGHT_AUTH_ID: m8XBzLrw8pWSjHQDhKQgCr - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BRIGHT_TOKEN: ${{ env.BRIGHT_TOKEN }} - BRIGHT_TARGET_URL: http://127.0.0.1:3000 - SECTESTER_SCAN_POOL_SIZE: ${{ vars.SECTESTER_SCAN_POOL_SIZE }} \ No newline at end of file diff --git a/.github/workflows/composite/configure-bright-credentials/action.yaml b/.github/workflows/composite/configure-bright-credentials/action.yaml deleted file mode 100644 index 8498384..0000000 --- a/.github/workflows/composite/configure-bright-credentials/action.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: 'Configure BrightSec credentials' - -inputs: - BRIGHT_HOSTNAME: - description: 'Hostname for the BrightSec environment' - required: true - BRIGHT_PROJECT_ID: - description: 'Project ID for BrightSec' - required: true - BRIGHT_TOKEN: - description: 'Pre-configured token' - required: false - -runs: - using: 'composite' - steps: - - id: configure_env_from_input - name: 'Set existing token in env' - shell: bash - if: ${{ inputs.BRIGHT_TOKEN != '' }} - env: - BRIGHT_TOKEN: ${{ inputs.BRIGHT_TOKEN }} - run: | - echo "BRIGHT_TOKEN=${BRIGHT_TOKEN}" >> $GITHUB_ENV - - - id: configure_bright_credentials_through_oidc - name: 'Exchange OIDC credentials for Bright token' - shell: bash - if: ${{ inputs.BRIGHT_TOKEN == '' }} - env: - BRIGHT_HOSTNAME: ${{ inputs.BRIGHT_HOSTNAME }} - BRIGHT_PROJECT_ID: ${{ inputs.BRIGHT_PROJECT_ID }} - run: | - # Retrieve OIDC token from GitHub - OIDC_TOKEN=$(curl -sS -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ - "${ACTIONS_ID_TOKEN_REQUEST_URL}" | jq -r '.value') - - # Post the token to BrightSec - RESPONSE=$(curl -s -X POST "https://${BRIGHT_HOSTNAME}/api/v1/projects/${BRIGHT_PROJECT_ID}/api-keys/oidc" \ - -H "Content-Type: application/json" \ - -d "{\"token\": \"${OIDC_TOKEN}\"}") - - if ! echo "$RESPONSE" | jq -e . > /dev/null 2>&1; then - echo "Error: $RESPONSE" 1>&2 - exit 1 - fi - - # Extract the pureKey - PURE_KEY=$(echo "$RESPONSE" | jq -r '.pureKey') - - # Mask and store in environment - echo "::add-mask::$PURE_KEY" - echo "BRIGHT_TOKEN=$PURE_KEY" >> $GITHUB_ENV