#!/bin/bash # 16 - Business Logic & Race Conditions # Race conditions use `hey` (tight concurrency) with curl fallback (higher jitter) # HTTP/1.1, HTTP/2, and HTTP/3 protocol variants included SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../config.sh" OUT_FILE="$OUT/16_business_logic.txt" echo "=== 16. Business Logic ===" | tee "$OUT_FILE" echo "" | tee -a "$OUT_FILE" W() { printf '%s' "$1" | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))"; } # ── 1. Race Condition — Parallel Key Generation ─────────────────────────────── echo "--- Race Condition: Parallel Key Generation ---" | tee -a "$OUT_FILE" RACE_URL="$API_TARGET/generate-keys" RACE_BODY='{"algorithm":"classical"}' if command -v hey >/dev/null 2>&1; then echo " Using hey for tight concurrency (50 requests, 50 concurrent)..." | tee -a "$OUT_FILE" HEY_OUT=$(hey -n 50 -c 50 -m POST \ -H 'Content-Type: application/json' \ -d "$RACE_BODY" \ -t 15 "$RACE_URL" 2>&1) echo "$HEY_OUT" | grep -E '(Status|Responses|Requests/sec|200|429|500)' | sed 's/^/ /' | tee -a "$OUT_FILE" # Check for duplicate keys (all 200 with same response = race vuln) UNIQUE=$(echo "$HEY_OUT" | grep -c '"key"' || true) echo " hey summary complete" | tee -a "$OUT_FILE" else echo " hey not found — using curl & (higher jitter, less reliable for race detection)" | tee -a "$OUT_FILE" TMPDIR_RACE=$(mktemp -d) for i in $(seq 1 20); do curl -sk -o "$TMPDIR_RACE/r$i.txt" -w '%{http_code}' --max-time 10 \ --http2 -X POST -H 'Content-Type: application/json' \ -d "$RACE_BODY" "$RACE_URL" > "$TMPDIR_RACE/c$i.txt" 2>/dev/null & done wait declare -A RCODES for i in $(seq 1 20); do CODE=$(cat "$TMPDIR_RACE/c$i.txt" 2>/dev/null || echo "?") RCODES[$CODE]=$((${RCODES[$CODE]:-0}+1)) done for CODE in "${!RCODES[@]}"; do echo " HTTP $CODE: ${RCODES[$CODE]}x" | tee -a "$OUT_FILE" done rm -rf "$TMPDIR_RACE" fi echo "" | tee -a "$OUT_FILE" # ── 2. Race Condition — Parallel Encrypt (quota/credit abuse) ───────────────── echo "--- Race Condition: Simultaneous Encrypt (quota bypass) ---" | tee -a "$OUT_FILE" ENC_URL="$API_TARGET/encrypt" ENC_BODY='{"data":"race_test","algorithm":"classical"}' if command -v hey >/dev/null 2>&1; then HEY_ENC=$(hey -n 100 -c 100 -m POST \ -H 'Content-Type: application/json' \ -d "$ENC_BODY" -t 15 "$ENC_URL" 2>&1) echo "$HEY_ENC" | grep -E '(Status|200|429|500|Requests/sec)' | sed 's/^/ /' | tee -a "$OUT_FILE" else declare -A ECODES for i in $(seq 1 20); do CODE=$(curl -sk -o /dev/null -w '%{http_code}' --http2 --max-time 10 \ -X POST -H 'Content-Type: application/json' \ -d "$ENC_BODY" "$ENC_URL" 2>/dev/null) & ECODES[$CODE]=$((${ECODES[$CODE]:-0}+1)) done wait for CODE in "${!ECODES[@]}"; do echo " HTTP $CODE: ${ECODES[$CODE]}x" | tee -a "$OUT_FILE"; done fi echo "" | tee -a "$OUT_FILE" # ── 3. Negative / Boundary Values ───────────────────────────────────────────── echo "--- Negative / Boundary Values ---" | tee -a "$OUT_FILE" for VAL in '-1' '0' '2147483648' '-2147483649' '9999999999999999999' 'null' '"Infinity"' '"NaN"' '1e308' '-1e308'; do CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 8 \ -X POST -H 'Content-Type: application/json' \ -d "{\"data\":\"test\",\"algorithm\":\"classical\",\"size\":$VAL}" \ "$API_TARGET/encrypt") echo " [$CODE] size=$VAL" | tee -a "$OUT_FILE" done echo "" | tee -a "$OUT_FILE" # ── 4. State Machine Bypass ──────────────────────────────────────────────────── echo "--- State Machine Bypass ---" | tee -a "$OUT_FILE" # Decrypt without encrypt (should fail cleanly) CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 \ -X POST -H 'Content-Type: application/json' \ -d '{"data":"dGVzdA==","algorithm":"classical","step":"decrypt"}' \ "$API_TARGET/decrypt") echo " [$CODE] Decrypt-without-encrypt (expect 400/401/422)" | tee -a "$OUT_FILE" # Skip steps — batch decrypt with no prior session CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 \ -X POST -H 'Content-Type: application/json' \ -d '{"data":"dGVzdA==","algorithm":"classical","skip_validation":"true"}' \ "$API_TARGET/decrypt") echo " [$CODE] skip_validation flag (expect 400/401/403)" | tee -a "$OUT_FILE" echo "" | tee -a "$OUT_FILE" # ── 5. Integer / Type Confusion ─────────────────────────────────────────────── echo "--- Type Confusion ---" | tee -a "$OUT_FILE" TYPE_PAYLOADS=( '{"data":12345,"algorithm":"classical"}' '{"data":true,"algorithm":"classical"}' '{"data":[],"algorithm":"classical"}' '{"data":{},"algorithm":"classical"}' '{"data":"test","algorithm":9999}' '{"data":"test","algorithm":null}' '{"data":"test","algorithm":["classical","post-quantum"]}' ) for P in "${TYPE_PAYLOADS[@]}"; do CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 8 \ -X POST -H 'Content-Type: application/json' -d "$P" "$API_TARGET/encrypt") echo " [$CODE] $P" | tee -a "$OUT_FILE" done echo "" | tee -a "$OUT_FILE" # ── 6. HTTP Protocol Variant — Business Logic Consistency ───────────────────── echo "--- Protocol Consistency (same logic over HTTP/1.1, HTTP/2) ---" | tee -a "$OUT_FILE" for PROTO_FLAG in "--http1.1" "--http2"; do CODE=$(curl -sk $PROTO_FLAG -o /dev/null -w '%{http_code}' --max-time 10 \ -X POST -H 'Content-Type: application/json' \ -d '{"data":"test","algorithm":"INVALID_ALGO_XYZ"}' \ "$API_TARGET/encrypt") echo " [$CODE] Invalid algo via $PROTO_FLAG (should be 400 on both)" | tee -a "$OUT_FILE" done echo "" | tee -a "$OUT_FILE" echo "=== 16. Business Logic COMPLETE ===" | tee -a "$OUT_FILE"