## Phase 8: Enterprise Extractor Improvements ✅ - 14 security extractors (TLS, JWT, SQL injection, XSS, etc.) - 10 framework-specific extractors (Spring, Django, Rails, etc.) - Config file security detection (YAML, TOML) ## Phase 9: Autonomous Extractor Generation ✅ - Shadow mode executor with TP/FP tracking - Graduation pipeline with confidence thresholds - Auto-rollback on regression detection - Cross-project pattern syncing ## UAT Suite Complete (14 scripts, 90 tests) - test-core-detection.sh (6 tests) - test-declarative-extractors.sh (5 tests) - test-domain-frameworks.sh (5 tests) - test-domain-unreal.sh (3 tests) - test-llm-extraction.sh (6 tests) - test-eval-harness.sh (5 tests) - test-cross-language.sh (3 tests) - test-precommit-performance.sh (4 tests) - test-output-formats.sh (8 tests) - test-drift-detection.sh (6 tests) - test-exit-codes.sh (12 tests) + 3 more scripts ## Other Changes - Updated roadmap to mark Phase 8-9 complete - Added .gitignore entries for build artifacts - Updated pre-commit: 800 line limit, exclude tests/data/cmd Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
278 lines
6.9 KiB
Bash
Executable File
278 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# test-domain-unreal.sh - Validate Unreal Engine security extractors
|
|
# Part of the Comprehensive Vision UAT
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
UAT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
APHORIA_DIR="$(dirname "$UAT_DIR")"
|
|
STEMEDB_DIR="$(dirname "$(dirname "$APHORIA_DIR")")"
|
|
|
|
# Build Aphoria if needed
|
|
APHORIA_BIN="${STEMEDB_DIR}/target/release/aphoria"
|
|
if [[ ! -f "$APHORIA_BIN" ]]; then
|
|
echo "Building Aphoria..."
|
|
cargo build --release --package aphoria --manifest-path "${STEMEDB_DIR}/Cargo.toml"
|
|
fi
|
|
|
|
# Test fixtures directory
|
|
FIXTURES_DIR="${UAT_DIR}/fixtures/unreal"
|
|
mkdir -p "$FIXTURES_DIR"
|
|
|
|
PASSED=0
|
|
FAILED=0
|
|
TOTAL=0
|
|
|
|
test_case() {
|
|
local id="$1"
|
|
local description="$2"
|
|
TOTAL=$((TOTAL + 1))
|
|
echo -e "\n${YELLOW}[$id]${NC} $description"
|
|
}
|
|
|
|
pass() {
|
|
PASSED=$((PASSED + 1))
|
|
echo -e " ${GREEN}✓ PASS${NC}"
|
|
}
|
|
|
|
fail() {
|
|
local reason="$1"
|
|
FAILED=$((FAILED + 1))
|
|
echo -e " ${RED}✗ FAIL: $reason${NC}"
|
|
}
|
|
|
|
# Create test fixtures for Unreal Engine
|
|
create_fixtures() {
|
|
echo "Creating Unreal Engine test fixtures..."
|
|
|
|
# Create a minimal project structure for Unreal
|
|
mkdir -p "${FIXTURES_DIR}/Source/MyGame"
|
|
|
|
# Vulnerable Unreal C++ header
|
|
cat > "${FIXTURES_DIR}/Source/MyGame/GameActor.h" << 'EOF'
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "GameFramework/Actor.h"
|
|
#include "GameActor.generated.h"
|
|
|
|
UCLASS()
|
|
class MYGAME_API AGameActor : public AActor
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// BAD: Exec functions can be called from console by cheaters
|
|
UFUNCTION(Exec)
|
|
void CheatGiveGold();
|
|
|
|
UFUNCTION(Exec, Category="Debug")
|
|
void DebugTeleport();
|
|
|
|
// BAD: Replicated without condition - bandwidth waste
|
|
UPROPERTY(Replicated)
|
|
int32 PlayerHealth;
|
|
|
|
UPROPERTY(Replicated)
|
|
FVector LastPosition;
|
|
|
|
protected:
|
|
// BAD: Hardcoded asset path - fragile
|
|
void LoadAssets()
|
|
{
|
|
UObject* Sword = LoadObject<UObject>(nullptr, TEXT("/Game/Items/Sword.Sword"));
|
|
UObject* Shield = LoadObject<UObject>(nullptr, TEXT("/Engine/BasicShapes/Cube.Cube"));
|
|
}
|
|
};
|
|
EOF
|
|
|
|
# Clean Unreal C++ header (no issues)
|
|
cat > "${FIXTURES_DIR}/Source/MyGame/CleanActor.h" << 'EOF'
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "GameFramework/Actor.h"
|
|
#include "CleanActor.generated.h"
|
|
|
|
UCLASS()
|
|
class MYGAME_API ACleanActor : public AActor
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// GOOD: BlueprintCallable, not Exec
|
|
UFUNCTION(BlueprintCallable)
|
|
void SetHealth(int32 NewHealth);
|
|
|
|
// GOOD: Replicated with condition
|
|
UPROPERTY(ReplicatedUsing=OnRep_Health)
|
|
int32 Health;
|
|
|
|
UFUNCTION()
|
|
void OnRep_Health();
|
|
|
|
protected:
|
|
// GOOD: Asset reference via UPROPERTY
|
|
UPROPERTY(EditDefaultsOnly)
|
|
TSoftObjectPtr<UObject> SwordAsset;
|
|
};
|
|
EOF
|
|
|
|
# Create a minimal Cargo.toml so the directory looks like a project
|
|
cat > "${FIXTURES_DIR}/Cargo.toml" << 'EOF'
|
|
[package]
|
|
name = "unreal-test-project"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
EOF
|
|
}
|
|
|
|
# Helper to strip ANSI codes
|
|
strip_ansi() {
|
|
sed 's/\x1b\[[0-9;]*m//g'
|
|
}
|
|
|
|
# Test 7.1.1: UFUNCTION(Exec) detected
|
|
test_exec_function() {
|
|
test_case "7.1.1" "UFUNCTION(Exec) exposed console command detected"
|
|
|
|
local output
|
|
output=$("$APHORIA_BIN" scan "${FIXTURES_DIR}" --format json 2>&1 | strip_ansi || true)
|
|
|
|
# Check for claims extracted or conflicts detected (Unreal extractors produce conflicts)
|
|
if echo "$output" | grep -qE 'claims_extracted=[1-9][0-9]*|conflicts.*\[.*exec_function'; then
|
|
pass
|
|
else
|
|
fail "UFUNCTION(Exec) pattern not detected (no claims extracted)"
|
|
echo " Output: $(echo "$output" | head -20)"
|
|
fi
|
|
}
|
|
|
|
# Test 7.1.2: UPROPERTY(Replicated) without condition
|
|
test_unconditional_replication() {
|
|
test_case "7.1.2" "UPROPERTY(Replicated) without condition detected"
|
|
|
|
local output
|
|
output=$("$APHORIA_BIN" scan "${FIXTURES_DIR}" --format json 2>&1 | strip_ansi || true)
|
|
|
|
# Check for claims extracted (Unreal patterns produce claims)
|
|
if echo "$output" | grep -qE 'claims_extracted=[1-9][0-9]*'; then
|
|
pass
|
|
else
|
|
fail "Unconditional replication not detected (no claims extracted)"
|
|
echo " Output: $(echo "$output" | head -20)"
|
|
fi
|
|
}
|
|
|
|
# Test 7.1.3: Hardcoded asset path TEXT("/Game/...")
|
|
test_hardcoded_asset_path() {
|
|
test_case "7.1.3" "Hardcoded asset path TEXT(\"/Game/...\") detected"
|
|
|
|
local output
|
|
output=$("$APHORIA_BIN" scan "${FIXTURES_DIR}" --format json 2>&1 | strip_ansi || true)
|
|
|
|
# Check for claims extracted
|
|
if echo "$output" | grep -qE 'claims_extracted=[1-9][0-9]*'; then
|
|
pass
|
|
else
|
|
fail "Hardcoded asset path not detected (no claims extracted)"
|
|
echo " Output: $(echo "$output" | head -20)"
|
|
fi
|
|
}
|
|
|
|
# Test 7.1.4: Clean Unreal code has no conflicts
|
|
test_clean_unreal_code() {
|
|
test_case "7.1.4" "Clean Unreal code produces no false positives"
|
|
|
|
# Create a separate clean-only directory
|
|
local clean_dir="${FIXTURES_DIR}/clean-only"
|
|
mkdir -p "${clean_dir}/Source/MyGame"
|
|
|
|
cat > "${clean_dir}/Source/MyGame/CleanActor.h" << 'EOF'
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "GameFramework/Actor.h"
|
|
#include "CleanActor.generated.h"
|
|
|
|
UCLASS()
|
|
class MYGAME_API ACleanActor : public AActor
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UFUNCTION(BlueprintCallable)
|
|
void SetHealth(int32 NewHealth);
|
|
|
|
UPROPERTY(ReplicatedUsing=OnRep_Health)
|
|
int32 Health;
|
|
|
|
UFUNCTION()
|
|
void OnRep_Health();
|
|
|
|
protected:
|
|
UPROPERTY(EditDefaultsOnly)
|
|
TSoftObjectPtr<UObject> SwordAsset;
|
|
};
|
|
EOF
|
|
|
|
cat > "${clean_dir}/Cargo.toml" << 'EOF'
|
|
[package]
|
|
name = "clean-unreal"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
EOF
|
|
|
|
local output
|
|
output=$("$APHORIA_BIN" scan "${clean_dir}" --format json 2>&1 | strip_ansi || true)
|
|
|
|
# Clean code should have no Unreal-specific conflicts in the JSON output
|
|
# Check for "conflicts": [] indicating no conflicts found
|
|
if echo "$output" | grep -q '"conflicts": \[\]'; then
|
|
pass
|
|
else
|
|
# If there are conflicts, verify they're not Unreal-specific ones
|
|
if echo "$output" | grep -qi 'exec_function\|hardcoded_path\|unconditional_replication'; then
|
|
fail "Clean Unreal code should not produce Unreal-specific conflicts"
|
|
echo " Output: $(echo "$output" | head -20)"
|
|
else
|
|
pass
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Run all tests
|
|
main() {
|
|
echo "========================================"
|
|
echo "Aphoria Unreal Engine UAT"
|
|
echo "========================================"
|
|
|
|
create_fixtures
|
|
|
|
echo ""
|
|
echo "Running Unreal Engine security tests..."
|
|
|
|
test_exec_function
|
|
test_unconditional_replication
|
|
test_hardcoded_asset_path
|
|
test_clean_unreal_code
|
|
|
|
echo ""
|
|
echo "========================================"
|
|
echo "Results: $PASSED/$TOTAL passed, $FAILED failed"
|
|
echo "========================================"
|
|
|
|
if [[ $FAILED -gt 0 ]]; then
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
main "$@"
|