Skip to content

Commit feecbb8

Browse files
committed
chore: improve sec. test coverage
1 parent e7c6590 commit feecbb8

File tree

4 files changed

+49
-22
lines changed

4 files changed

+49
-22
lines changed

.pentest/scripts/10_websocket_probe.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ EDGE_CASES=(
151151
"array:${WS_URL}?token[]=hack"
152152
"zero:${WS_URL}?token=0"
153153
"true:${WS_URL}?token=true"
154-
"sqlinjection:${WS_URL}?token='"'"' OR 1=1--"
154+
"sqlinjection:${WS_URL}?token=' OR 1=1--"
155155
)
156156

157157
for entry in "${EDGE_CASES[@]}"; do

config/brakeman.ignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@
1212
"fingerprint": "7bdf978768b5058d8c79ec541e68cb8643bbf19ab5ab52d60e6bd420a91bc416",
1313
"note": "False positive — safe_ids values come from Meilisearch hit IDs (internal database PKs) and are individually escaped via ActiveRecord::Base.connection.quote() before interpolation. User search query is sent only to Meilisearch, never interpolated into SQL. Reviewed 2026-02-28."
1414
},
15+
{
16+
"fingerprint": "82553a8da70acefb77b22bab7fb95616b808a9604a23dff455508e0ad77e3107",
17+
"note": "False positive — the SQL interpolation only inserts PostgreSQL numbered bind-parameter placeholders ($1, $2, ...). The actual type_names values are passed separately as exec_query bind parameters. No user input reaches this code path. Reviewed 2026-04-05."
18+
},
19+
{
20+
"fingerprint": "8273a221da2916071e72130e8e4a184b37aa96df641daff5c11d7069740e2c81",
21+
"note": "False positive — :role is a League of Legends in-game position (top/jungle/mid/adc/support), NOT a user authorization role. ScoutingTarget model has no admin/privilege-escalation fields. Reviewed 2026-04-05."
22+
},
23+
{
24+
"fingerprint": "88173572797556fd8d8d2da622fdb463673c0793a9ec10126b1803fc39f04f06",
25+
"note": "False positive — :role is a League of Legends in-game position (top/jungle/mid/adc/support), NOT a user authorization role. ScoutingTarget model has no admin/privilege-escalation fields. Reviewed 2026-04-05."
26+
},
27+
{
28+
"fingerprint": "8bf697cde545723f2f3d339a8fc87f1cbb80dccb7cc50ea42243ebde2c0d7883",
29+
"note": "False positive — safe_ids values come from Meilisearch hit IDs (internal database PKs) and are individually escaped via ActiveRecord::Base.connection.quote() before interpolation. User search query is sent only to Meilisearch, never interpolated into SQL. Reviewed 2026-04-05."
30+
},
1531
{
1632
"fingerprint": "a53e36aea1309fb0af3b08b9d5403838087ed98264a2a158a98adde5f6d496d3",
1733
"note": "False positive — :role is a League of Legends champion role (adc/jungle/mid/support/top), NOT a user authorization role. SavedBuild model has no admin/banned/account_id or privilege-escalation fields. Reviewed 2026-02-28."

security_tests/scripts/test-multi-tenancy-isolation.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ ORG1_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/auth/register" \
5353
"user": {
5454
"email": "org1-'$(date +%s)'@test.com",
5555
"password": "Test123!@#",
56-
"name": "Org1 User"
56+
"full_name": "Org1 User"
5757
},
5858
"organization": {
5959
"name": "Test Org 1",
60-
"slug": "test-org-1-'$(date +%s)'"
60+
"region": "BR"
6161
}
6262
}')
6363

@@ -73,11 +73,11 @@ ORG2_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/auth/register" \
7373
"user": {
7474
"email": "org2-'$(date +%s)'@test.com",
7575
"password": "Test123!@#",
76-
"name": "Org2 User"
76+
"full_name": "Org2 User"
7777
},
7878
"organization": {
7979
"name": "Test Org 2",
80-
"slug": "test-org-2-'$(date +%s)'"
80+
"region": "BR"
8181
}
8282
}')
8383

security_tests/scripts/test-ssrf-protection.sh

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,36 @@ test_result() {
3939
fi
4040
}
4141

42-
# Create test user and get token
42+
# Authenticate — try login with fixed test user first, register only if needed
43+
FIXED_EMAIL="${TEST_EMAIL:-sectest@prostaff-security.invalid}"
44+
FIXED_PASSWORD="${TEST_PASSWORD:-Test123!@#}"
45+
4346
echo "Setting up test user..."
44-
AUTH_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/auth/register" \
47+
AUTH_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/auth/login" \
4548
-H "Content-Type: application/json" \
46-
-d '{
47-
"user": {
48-
"email": "ssrf-test-'$(date +%s)'@test.com",
49-
"password": "Test123!@#",
50-
"name": "SSRF Test User"
51-
},
52-
"organization": {
53-
"name": "SSRF Test Org",
54-
"slug": "ssrf-test-'$(date +%s)'"
55-
}
56-
}')
57-
58-
TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data.access_token')
59-
60-
if [ "$TOKEN" = "null" ]; then
49+
-d "{\"email\":\"$FIXED_EMAIL\",\"password\":\"$FIXED_PASSWORD\"}")
50+
51+
TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data.access_token // empty')
52+
53+
if [ -z "$TOKEN" ]; then
54+
# User does not exist yet — register once
55+
AUTH_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/auth/register" \
56+
-H "Content-Type: application/json" \
57+
-d "{
58+
\"user\": {
59+
\"email\": \"$FIXED_EMAIL\",
60+
\"password\": \"$FIXED_PASSWORD\",
61+
\"full_name\": \"SSRF Test User\"
62+
},
63+
\"organization\": {
64+
\"name\": \"SSRF Test Org\",
65+
\"region\": \"BR\"
66+
}
67+
}")
68+
TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.data.access_token // empty')
69+
fi
70+
71+
if [ -z "$TOKEN" ]; then
6172
echo "FATAL: Failed to authenticate"
6273
echo "Response: $AUTH_RESPONSE"
6374
exit 1

0 commit comments

Comments
 (0)