From 544dfc359ea4573fc06b57139ea9df236b5a1964 Mon Sep 17 00:00:00 2001 From: Mohammad Reza Date: Fri, 6 Feb 2026 20:11:26 +0330 Subject: [PATCH] Solved issue #206 --- 206/app/api/dashboard.py | 17 +++++++++++++ 206/app/api/dependency_api.py | 20 +++++++++++++++ 206/app/api/internal_test.py | 12 +++++++++ 206/app/core/dependency_scan.py | 38 ++++++++++++++++++++++++++++ 206/app/core/security.py | 17 +++++++++++++ 206/app/core/security_events.py | 13 ++++++++++ 206/app/core/service_test.py | 15 +++++++++++ 206/app/main.py | 13 ++++++++++ 206/app/middleware/ids_middleware.py | 18 +++++++++++++ 206/certificates/server.crt | 0 206/certificates/server.key | 0 11 files changed, 163 insertions(+) create mode 100644 206/app/api/dashboard.py create mode 100644 206/app/api/dependency_api.py create mode 100644 206/app/api/internal_test.py create mode 100644 206/app/core/dependency_scan.py create mode 100644 206/app/core/security.py create mode 100644 206/app/core/security_events.py create mode 100644 206/app/core/service_test.py create mode 100644 206/app/main.py create mode 100644 206/app/middleware/ids_middleware.py create mode 100644 206/certificates/server.crt create mode 100644 206/certificates/server.key diff --git a/206/app/api/dashboard.py b/206/app/api/dashboard.py new file mode 100644 index 0000000..df3be61 --- /dev/null +++ b/206/app/api/dashboard.py @@ -0,0 +1,17 @@ +from fastapi import APIRouter, Depends +from app.core.security import require_admin +from app.core.security_events import get_events + +router = APIRouter() + +@router.get("/") +def dashboard(role=Depends(require_admin)): + events = get_events() + + return { + "total_events": len(events), + "dependency_alerts": [ + e for e in events if e["type"] == "DEPENDENCY_VULNERABILITY" + ], + "all_events": events + } \ No newline at end of file diff --git a/206/app/api/dependency_api.py b/206/app/api/dependency_api.py new file mode 100644 index 0000000..04ab9bf --- /dev/null +++ b/206/app/api/dependency_api.py @@ -0,0 +1,20 @@ +from fastapi import APIRouter, Depends, HTTPException +from app.core.security import require_admin +from app.core.dependency_scan import run_dependency_scan + +router = APIRouter() + +@router.get("/dependency-scan") +def dependency_scan(role=Depends(require_admin)): + result = run_dependency_scan() + + if result["status"] == "vulnerable": + raise HTTPException( + status_code=409, + detail={ + "message": "Vulnerable dependencies detected", + "vulnerabilities": result["details"] + } + ) + + return {"status": "clean"} diff --git a/206/app/api/internal_test.py b/206/app/api/internal_test.py new file mode 100644 index 0000000..5beae31 --- /dev/null +++ b/206/app/api/internal_test.py @@ -0,0 +1,12 @@ +from fastapi import APIRouter, Depends +from app.core.security import require_admin +from app.core.service_test import test_service_encryption + +router = APIRouter() +CERT_PATH = "./certificates/server.crt" + +@router.get("/test-communication") +async def test_internal_service(role_check=Depends(require_admin)): + target_url = "https://localhost:8001/internal-data" + result = test_service_encryption(target_url, CERT_PATH) + return result diff --git a/206/app/core/dependency_scan.py b/206/app/core/dependency_scan.py new file mode 100644 index 0000000..8e9a4a0 --- /dev/null +++ b/206/app/core/dependency_scan.py @@ -0,0 +1,38 @@ +import subprocess +from app.core.security_events import log_event + +def run_dependency_scan(): + try: + result = subprocess.run( + ["pip-audit", "--format", "json"], + capture_output=True, + text=True + ) + + if result.returncode != 0: + findings = result.stdout.strip() + + log_event( + "DEPENDENCY_VULNERABILITY", + { + "tool": "pip-audit", + "findings": findings + } + ) + + return { + "status": "vulnerable", + "details": findings + } + + return { + "status": "clean", + "details": [] + } + + except Exception as e: + log_event( + "DEPENDENCY_SCAN_ERROR", + {"error": str(e)} + ) + raise diff --git a/206/app/core/security.py b/206/app/core/security.py new file mode 100644 index 0000000..392aae7 --- /dev/null +++ b/206/app/core/security.py @@ -0,0 +1,17 @@ +from fastapi import Depends, HTTPException, status +from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials + +security = HTTPBearer() + +def require_admin( + credentials: HTTPAuthorizationCredentials = Depends(security) +): + token = credentials.credentials + + if token != "admin": + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Admin access required" + ) + + return token diff --git a/206/app/core/security_events.py b/206/app/core/security_events.py new file mode 100644 index 0000000..502d02c --- /dev/null +++ b/206/app/core/security_events.py @@ -0,0 +1,13 @@ +from datetime import datetime + +SECURITY_EVENTS = [] + +def log_event(event_type: str, details: dict): + SECURITY_EVENTS.append({ + "type": event_type, + "details": details, + "timestamp": datetime.utcnow().isoformat() + }) + +def get_events(): + return SECURITY_EVENTS diff --git a/206/app/core/service_test.py b/206/app/core/service_test.py new file mode 100644 index 0000000..6c0e8ce --- /dev/null +++ b/206/app/core/service_test.py @@ -0,0 +1,15 @@ +import requests +from app.core.security_events import log_event + +def test_service_encryption(target_url: str, cert_path: str): + try: + response = requests.get(target_url, verify=cert_path) + if response.status_code == 200: + log_event("INTERNAL_COMM_SECURE", {"url": target_url, "status": "TLS verified"}) + return {"status": "secure", "url": target_url} + else: + log_event("INTERNAL_COMM_ERROR", {"url": target_url, "status": response.status_code}) + return {"status": "error", "url": target_url, "code": response.status_code} + except requests.exceptions.SSLError as e: + log_event("INTERNAL_COMM_TLS_ERROR", {"url": target_url, "error": str(e)}) + return {"status": "tls_error", "url": target_url, "error": str(e)} diff --git a/206/app/main.py b/206/app/main.py new file mode 100644 index 0000000..096a4f6 --- /dev/null +++ b/206/app/main.py @@ -0,0 +1,13 @@ +from fastapi import FastAPI +from app.middleware.ids_middleware import IDSMiddleware +from app.api.dashboard import router as dashboard_router +from app.api.dependency_api import router as dependency_router +from app.api.internal_test import router as internal_test_router + +app = FastAPI(title="Security Dashboard") + +app.add_middleware(IDSMiddleware) + +app.include_router(dashboard_router, prefix="/dashboard") +app.include_router(dependency_router, prefix="/security") +app.include_router(internal_test_router, prefix="/security") diff --git a/206/app/middleware/ids_middleware.py b/206/app/middleware/ids_middleware.py new file mode 100644 index 0000000..a386041 --- /dev/null +++ b/206/app/middleware/ids_middleware.py @@ -0,0 +1,18 @@ +from starlette.middleware.base import BaseHTTPMiddleware +from fastapi import Request +from app.core.security_events import log_event + +class IDSMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next): + response = await call_next(request) + + if response.status_code == 403: + log_event( + "UNAUTHORIZED_ACCESS", + { + "path": request.url.path, + "method": request.method + } + ) + + return response diff --git a/206/certificates/server.crt b/206/certificates/server.crt new file mode 100644 index 0000000..e69de29 diff --git a/206/certificates/server.key b/206/certificates/server.key new file mode 100644 index 0000000..e69de29