@echo off setlocal enabledelayedexpansion chcp 65001 >nul set PYTHONUTF8=1 set PYTHONIOENCODING=utf-8 echo ====================================================================== echo EDU-SPACE: AUTOMATED SECURITY AUDIT SUITE echo ====================================================================== echo. set ROOT_DIR=%~dp0 set VENV_PY=%ROOT_DIR%backend\venv\Scripts\python.exe set VENV_BANDIT=%ROOT_DIR%backend\venv\Scripts\bandit.exe set VENV_PIPAUDIT=%ROOT_DIR%backend\venv\Scripts\pip-audit.exe set VENV_ST=%ROOT_DIR%backend\venv\Scripts\st.exe set VENV_NJSSCAN=%ROOT_DIR%backend\venv\Scripts\njsscan.exe set OVERALL_STATUS=0 echo [1/5] Running Python SAST Analysis (Bandit)... echo ---------------------------------------------------------------------- if exist "%VENV_BANDIT%" ( call "%VENV_BANDIT%" -r "%ROOT_DIR%backend\app" -ll -ii if !ERRORLEVEL! neq 0 ( echo [!] Warning: Bandit reported potential security concerns. set OVERALL_STATUS=1 ) else ( echo [OK] Bandit scan completed cleanly - 0 Medium/High issues. ) ) else ( echo [!] Error: Bandit executable not found at "%VENV_BANDIT%". set OVERALL_STATUS=1 ) echo. echo [2/5] Running Python SCA Dependency Audit (pip-audit)... echo ---------------------------------------------------------------------- if exist "%VENV_PIPAUDIT%" ( call "%VENV_PIPAUDIT%" -s osv --progress-spinner off -r "%ROOT_DIR%backend\requirements.txt" if !ERRORLEVEL! neq 0 ( echo [i] OSV feed unreachable or returned errors. Retrying with PyPI vulnerability service... call "%VENV_PIPAUDIT%" -s pypi --progress-spinner off -r "%ROOT_DIR%backend\requirements.txt" ) if !ERRORLEVEL! neq 0 ( echo [!] Warning: pip-audit reported package vulnerabilities or service unavailable. set OVERALL_STATUS=1 ) else ( echo [OK] All Python dependencies are secure - 0 known CVEs. ) ) else ( echo [!] Error: pip-audit executable not found at "%VENV_PIPAUDIT%". set OVERALL_STATUS=1 ) echo. echo [3/5] Running Node.js SAST Analysis (njsscan)... echo ---------------------------------------------------------------------- if exist "%VENV_NJSSCAN%" ( call "%VENV_NJSSCAN%" "%ROOT_DIR%frontend\src" if !ERRORLEVEL! neq 0 ( echo [!] Warning: njsscan reported code smells or security concerns. set OVERALL_STATUS=1 ) else ( echo [OK] Node.js SAST analysis completed cleanly. ) ) else ( echo [!] Error: njsscan executable not found at "%VENV_NJSSCAN%". set OVERALL_STATUS=1 ) echo. echo [4/5] Running Node.js SCA Dependency Audit (npm audit)... echo ---------------------------------------------------------------------- cd /d "%ROOT_DIR%frontend" call cmd.exe /c npm audit if !ERRORLEVEL! neq 0 ( echo [!] Warning: npm audit reported package vulnerabilities. set OVERALL_STATUS=1 ) else ( echo [OK] All Node.js dependencies are secure - 0 vulnerabilities. ) cd /d "%ROOT_DIR%" echo. echo [5/5] Running Dynamic API Security Fuzzing (Schemathesis DAST)... echo ---------------------------------------------------------------------- set API_DOC_URL=http://127.0.0.1:5000/api/v1/openapi.json echo Checking backend availability at %API_DOC_URL%... curl.exe -s -f -o nul "%API_DOC_URL%" if !ERRORLEVEL! neq 0 ( echo [!] Warning: Local Flask backend is not responding on %API_DOC_URL% echo To run live DAST fuzzing, start the backend in another terminal: echo cd backend ^&^& venv\Scripts\flask.exe run --port=5000 echo [!] Skipping DAST fuzzing phase. ) else ( echo Target online. Running Schemathesis against OpenAPI spec... call "%VENV_ST%" run "%API_DOC_URL%" --checks not_a_server_error --max-examples=10 --no-color if !ERRORLEVEL! neq 0 ( echo [!] Warning: Schemathesis identified potential unhandled edge cases or server errors. set OVERALL_STATUS=1 ) else ( echo [OK] API DAST fuzzing passed - 0 unhandled 500 server errors. ) ) echo. echo ====================================================================== if %OVERALL_STATUS% equ 0 ( echo SECURITY AUDIT SUITE COMPLETED SUCCESSFULLY [PASS] ) else ( echo SECURITY AUDIT SUITE COMPLETED WITH WARNINGS [CHECK] ) echo ====================================================================== echo. if /I not "%~1"=="--no-pause" if /I not "%~1"=="-n" pause