Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .brightsec/tests/get-api-deliverys-1.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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 /api/deliverys/1', { signal: AbortSignal.timeout(timeout) }, async () => {
await runner
.createScan({
tests: ['id_enumeration'],
attackParamLocations: [AttackParamLocation.PATH],
starMetadata: {
code_source: "tssbox/juice-shop:master",
databases: ["SQLite"],
user_roles: {
roles: ["customer", "deluxe", "accounting", "admin"]
}
},
poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined
})
.setFailFast(false)
.timeout(timeout)
.run({
method: HttpMethod.GET,
url: `${baseUrl}/api/Deliverys/1`,
auth: process.env.BRIGHT_AUTH_ID
});
});
42 changes: 42 additions & 0 deletions .brightsec/tests/get-rest-products-search.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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 /rest/products/search?q=:query', { signal: AbortSignal.timeout(timeout) }, async () => {
await runner
.createScan({
tests: ['sqli'],
attackParamLocations: [AttackParamLocation.QUERY],
starMetadata: {
code_source: "tssbox/juice-shop:master",
databases: ["SQLite"],
user_roles: {
roles: ["customer", "deluxe", "accounting", "admin"]
}
},
poolSize: +process.env.SECTESTER_SCAN_POOL_SIZE || undefined
})
.setFailFast(false)
.timeout(timeout)
.run({
method: HttpMethod.GET,
url: `${baseUrl}/rest/products/search?q=apple`,
auth: process.env.BRIGHT_AUTH_ID
});
});
63 changes: 63 additions & 0 deletions .github/workflows/bright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Bright

on:
pull_request:
branches:
- '**'

permissions:
checks: write
contents: read
id-token: write

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4

- name: Use Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install application dependencies
run: |
npm install

- name: Start application
run: |
npm start &

- name: Probe application readiness
run: |
for i in {1..30}; do nc -z 127.0.0.1 3000 && exit 0 || sleep 5; done; exit 1

- name: Use Node.js 22.x for SecTesterJS
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Install SecTesterJS dependencies
run: |
npm i --save=false --prefix .brightsec @sectester/core @sectester/repeater @sectester/scan @sectester/runner @sectester/reporter

- name: Authenticate with Bright
uses: ./.github/workflows/composite/configure-bright-credentials
with:
BRIGHT_HOSTNAME: development.playground.brightsec.com
BRIGHT_PROJECT_ID: bSLRUwVyZ9aMHv4S9BrwaW
BRIGHT_TOKEN: ${{ secrets.BRIGHT_TOKEN }}

- name: Run security tests
env:
BRIGHT_HOSTNAME: development.playground.brightsec.com
BRIGHT_PROJECT_ID: bSLRUwVyZ9aMHv4S9BrwaW
BRIGHT_AUTH_ID: ${{ vars.BRIGHT_AUTH_ID }}
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 }}
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
Original file line number Diff line number Diff line change
@@ -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
29 changes: 0 additions & 29 deletions .github/workflows/lint-fixer.yml

This file was deleted.

7 changes: 0 additions & 7 deletions .gitlab-ci.yml

This file was deleted.