Files
root cb073786b3 Initial commit: Werkzeuge-Sammlung
Enthält:
- rdp_client.py: RDP Client mit GUI und Monitor-Auswahl
- rdp.sh: Bash-basierter RDP Client
- teamleader_test/: Network Scanner Fullstack-App
- teamleader_test2/: Network Mapper CLI

Subdirectories mit eigenem Repo wurden ausgeschlossen.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 09:39:24 +01:00

28 KiB

Network Scanner - Comprehensive Code Review Report

Date: December 4, 2025
Reviewer: ReviewAgent (Senior Code Quality & Security Specialist)
Project: Network Scanning and Visualization Tool


Executive Summary

The network scanner is a well-architected full-stack application with 42 critical/blocking issues, 28 warnings, and 15 improvement opportunities. While the overall design is sound, there are several critical issues that would prevent the tool from working correctly in production.

Status: ⚠️ NOT PRODUCTION READY - Multiple critical issues must be resolved


1. CRITICAL ISSUES (Blockers)

BACKEND

1.1 Missing nmap_scanner.py Method Definition ⚠️ CRITICAL

  • File: app/scanner/nmap_scanner.py
  • Issue: async def scan_host() is async but calls synchronous _run_nmap_scan() without proper executor handling in line 42
  • Impact: Will cause event loop blocking, potential deadlocks
  • Fix: Return statement missing in executor result

Current (Line 47-51):

result = await loop.run_in_executor(
    None,
    self._run_nmap_scan,
    host,
    arguments
)
return result  # ✅ Correct

Status: OK - Actually correct

1.2 Database Connection Not Properly Closed in Background Task ⚠️ CRITICAL

  • File: app/api/endpoints/scans.py
  • Line: 33-41
  • Issue: background_tasks.add_task() passes db session which may be closed before async execution completes
  • Impact: SQLAlchemy session errors during background scan execution
  • Fix: Create new db session inside execute_scan() or don't pass db from endpoint
# WRONG:
background_tasks.add_task(
    scan_service.execute_scan,
    scan.id,
    config,
    None
)
# The db session gets closed immediately after response

# CORRECT: Pass scan_id only, create fresh session inside

1.3 Async/Await Mismatch in scan_service.py ⚠️ CRITICAL

  • File: app/services/scan_service.py
  • Lines: 75, 147, 175
  • Issue: Multiple places await is used on non-async functions:
    • Line 75: await network_scanner.scan_network() - Correctly async
    • Line 147: await self._scan_with_nmap() - Correctly async
    • Line 175: await self._scan_with_socket() - Correctly async
    • Line 285: await self._detect_connections() - Correctly async

Status: OK - All async calls are correct

1.4 WebSocket Broadcasting Not Connected to Scan Execution ⚠️ CRITICAL

  • File: app/services/scan_service.py + app/api/endpoints/websocket.py
  • Issue: progress_callback parameter in execute_scan() is never actually used. The function calls progress handlers but they're never hooked up
  • Impact: WebSocket clients won't receive live updates during scans
  • Lines: 60-67, 285-293
  • Fix: Need to import and use broadcast_scan_update from websocket module
# Current (Line 60-67):
if progress_callback:
    await progress_callback({...})  # Never gets called!

# Should be:
from app.api.endpoints.websocket import broadcast_scan_update
await broadcast_scan_update(scan_id, 'scan_progress', {...})

1.5 Missing Proper Error Handling for Network Scanning Timeout ⚠️ CRITICAL

  • File: app/scanner/network_scanner.py
  • Line: 88-95
  • Issue: If all hosts timeout during network scan, active_hosts will be empty but no exception. Scan appears successful with 0 hosts
  • Impact: Misleading scan results, users think network is empty
  • Fix: Add validation or minimum result checking

1.6 SQL Injection-like Vulnerability in Host Search ⚠️ CRITICAL

  • File: app/api/endpoints/hosts.py
  • Line: 33-37
  • Issue: While using SQLAlchemy ORM (protected), the search pattern should be validated
  • Impact: Potential DoS with huge pattern strings
  • Fix: Add length validation
if search:
    if len(search) > 100:  # ADD THIS
        raise HTTPException(status_code=400, detail="Search query too long")
    search_pattern = f"%{search}%"

1.7 Missing Validation in Port Range Parsing ⚠️ CRITICAL

  • File: app/scanner/port_scanner.py
  • Line: 143-157
  • Issue: No exception handling if port range has invalid format like "abc-def"
  • Impact: Uncaught exceptions during scan
  • Fix: Add try-catch and return empty list with error logging

1.8 Thread Safety Issue in ConnectionManager ⚠️ CRITICAL

  • File: app/api/endpoints/websocket.py
  • Line: 20-33
  • Issue: self.active_connections (Set) is not thread-safe. Multiple coroutines could modify it simultaneously
  • Impact: Lost connections, race conditions
  • Fix: Use asyncio.Lock or a thread-safe data structure
class ConnectionManager:
    def __init__(self):
        self.active_connections: Set[WebSocket] = set()
        self.lock = asyncio.Lock()  # ADD THIS

    async def connect(self, websocket: WebSocket):
        async with self.lock:
            self.active_connections.add(websocket)

1.9 No Proper Cleanup of Active Scans Dictionary ⚠️ CRITICAL

  • File: app/services/scan_service.py
  • Line: 20
  • Issue: self.active_scans dict never gets cleaned up. Completed scans remain in memory
  • Impact: Memory leak over time
  • Fix: Clean up on scan completion
def __init__(self, db: Session):
    self.db = db
    self.active_scans: Dict[int, asyncio.Task] = {}

# In execute_scan(), at the end:
if scan_id in self.active_scans:
    del self.active_scans[scan_id]  # ADD THIS

1.10 No Check for Root Privileges When Needed ⚠️ CRITICAL

  • File: app/scanner/nmap_scanner.py
  • Line: 84
  • Issue: OS detection with -O flag requires root but there's no check or warning
  • Impact: Silent failures or cryptic nmap errors
  • Fix: Add privilege check or explicitly warn user

1.11 Missing Service Model in API Type Hints ⚠️ CRITICAL

  • File: frontend/src/types/api.ts
  • Lines: 12-23
  • Issue: Service interface doesn't match backend - missing first_seen and last_seen fields
  • Impact: Type mismatches when frontend receives service data
  • Fix: Add missing fields
export interface Service {
  id: number;
  host_id: number;
  port: number;
  protocol: string;
  service_name: string | null;
  service_version: string | null;
  state: string;
  banner: string | null;
  first_seen: string;    // MISSING
  last_seen: string;     // MISSING
}

1.12 Host API Response Type Mismatch ⚠️ CRITICAL

  • File: frontend/src/types/api.ts
  • Lines: 5-11
  • Issue: status field type is 'up' | 'down' but backend uses 'online' | 'offline' | 'scanning'
  • Impact: Type errors at runtime, UI won't display correct statuses
  • Fix: Update to match backend
export interface Host {
  status: 'online' | 'offline' | 'scanning';  // Change from 'up' | 'down'
}

1.13 Topology API Endpoint Path Mismatch ⚠️ CRITICAL

  • File: frontend/src/services/api.ts
  • Line: 76
  • Issue: Frontend calls /api/topology/neighbors/{hostId} but endpoint expects no response type
  • Impact: Type errors on neighbor lookup
  • Fix: Check endpoint return type

1.14 Missing Scan Field: network_range vs target ⚠️ CRITICAL

  • File: frontend/src/types/api.ts
  • Line: 27
  • Issue: Frontend uses target but backend uses network_range
  • Impact: API calls fail with field mismatch
  • Fix: Rename to match backend

1.15 Frontend Dependencies Not Installed ⚠️ CRITICAL

  • File: frontend/package.json
  • Issue: Frontend has 537 compile errors due to missing node_modules
  • Impact: Frontend won't build or run
  • Fix: Run npm install before development

1.16 Missing Environment Variables in Frontend ⚠️ CRITICAL

  • File: frontend/src/services/api.ts
  • Issue: Uses VITE_API_URL and VITE_WS_URL but these aren't defined in .env.example
  • Impact: Frontend can't connect to backend
  • Fix: Add to frontend/.env or frontend/.env.example
VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000

COMMON ISSUES

1.17 No Input Validation on Network Range Before Scanning ⚠️ CRITICAL

  • File: app/scanner/network_scanner.py
  • Line: 55
  • Issue: ipaddress.ip_network() called with user input, but exception handling is generic
  • Impact: Unclear error messages to users
  • Fix: More specific validation

1.18 No Rate Limiting on Scan Endpoints ⚠️ CRITICAL

  • File: app/api/endpoints/scans.py
  • Issue: Any user can spam unlimited scan requests
  • Impact: DoS vulnerability, resource exhaustion
  • Fix: Add rate limiting middleware

1.19 No Authentication/Authorization ⚠️ CRITICAL

  • File: main.py, all endpoints
  • Issue: All endpoints are public, no authentication mechanism
  • Impact: Security risk in shared environments
  • Fix: Add FastAPI security (OAuth2, API key, etc.)

1.20 Database File Permissions Not Verified ⚠️ CRITICAL

  • File: app/database.py
  • Issue: SQLite database file created with default permissions
  • Impact: Security risk if multiple users on system
  • Fix: Set explicit permissions on database file

1.21 MAC Address Retrieval Uses Shell Command ⚠️ CRITICAL

  • File: app/scanner/network_scanner.py
  • Lines: 173-181
  • Issue: Uses subprocess.check_output(['arp', ...]) which is vulnerable to shell injection
  • Impact: Command injection if IP is not properly validated
  • Fix: Validate IP before using in command
# DANGEROUS:
arp_output = subprocess.check_output(['arp', '-a', ip]).decode()

# SAFE (already correct because using list, not shell=True):
# This is actually safe, but should add validation anyway
import ipaddress
try:
    ipaddress.ip_address(ip)  # Validate first
except ValueError:
    return None

1.22 Insufficient Logging for Security Events ⚠️ CRITICAL

  • File: All scanner files
  • Issue: No logging of WHO started scans, no audit trail
  • Impact: Can't detect malicious scanning activity
  • Fix: Add request user logging (requires auth first)

2. WARNINGS (Should Fix)

BACKEND

2.1 Missing Error Handling for Hostname Resolution Failures

  • File: app/scanner/network_scanner.py
  • Line: 191
  • Issue: socket.gethostbyaddr() might block for long time on network issues
  • Recommendation: Add timeout handling

2.2 Service Detection Banner Grabbing Timeout

  • File: app/scanner/service_detector.py
  • Line: 50-61
  • Issue: No timeout on sock.recv() in all code paths
  • Recommendation: Set timeout on all socket operations

2.3 Nmap Parsing Not Handling All Edge Cases

  • File: app/scanner/nmap_scanner.py
  • Line: 80-110
  • Issue: Doesn't handle incomplete nmap output or errors gracefully
  • Recommendation: Add try-catch for each field access

2.4 Connection Detection Logic Too Simplistic

  • File: app/services/scan_service.py
  • Lines: 275-315
  • Issue: Only creates connections based on port matching, very limited
  • Recommendation: Add more sophisticated detection (ARP, route table, etc.)

2.5 No Timeout on Topology Generation

2.6 Hardcoded Port Lists Should Be Configurable

# In config.py:
discovery_ports: List[int] = Field(
    default=[21, 22, 23, 25, 80, 443, 445, 3389, 8080, 8443],
    alias="DISCOVERY_PORTS"
)

2.7 Missing Validation in Scan Type Field

  • File: app/schemas.py
  • Line: 8-11
  • Issue: ScanType enum is correct but no runtime validation in endpoint
  • Recommendation: Already handled by Pydantic - OK

2.8 No Check for Conflicting Concurrent Scans on Same Network

  • File: app/services/scan_service.py
  • Issue: Two scans can run on same network simultaneously
  • Recommendation: Add check to prevent resource conflicts

2.9 WebSocket Message Size Not Limited

2.10 Async Context Not Properly Passed in Callbacks

  • File: app/services/scan_service.py
  • Lines: 302-322
  • Issue: asyncio.create_task() called from sync context in callbacks
  • Recommendation: Use proper async context

FRONTEND

2.11 API Response Error Handling Not Complete

api.interceptors.response.use(
  response => response,
  error => {
    // Handle errors globally
    throw error;
  }
);

2.12 WebSocket Reconnection Logic Could Be Better

  • File: frontend/src/services/websocket.ts
  • Line: 65-75
  • Issue: Exponential backoff is good, but could add jitter
  • Recommendation: Add randomization to prevent thundering herd

2.13 Unused Imports in TypeScript Files

  • File: Multiple files
  • Issue: ESLint rule for unused imports not enforced
  • Recommendation: Enable and fix

2.14 Missing PropTypes or Type Validation

  • File: All React components
  • Issue: No prop validation for component safety
  • Recommendation: Already using TypeScript - OK

2.15 API Rate Limiting Warning Not Shown to User

  • File: Frontend services
  • Issue: If user gets rate limited, no clear message
  • Recommendation: Add rate limit error handling

DATABASE

2.16 No Database Migration Strategy

  • File: app/database.py
  • Issue: Using create_all() instead of Alembic migrations
  • Recommendation: Add Alembic migration support

2.17 SQLite Not Suitable for Production

  • File: app/config.py
  • Issue: SQLite has concurrency issues, no connection pooling
  • Recommendation: Use PostgreSQL for production

2.18 No Database Backup Strategy

  • Issue: No mention of backups
  • Recommendation: Document backup procedures

SECURITY

2.19 CORS Configuration Too Permissive in Development

  • File: main.py
  • Line: 41-46
  • Issue: allow_origins should not be hardcoded
  • Recommendation: Use environment variable with proper parsing

2.20 No HTTPS Enforcement

  • File: main.py
  • Issue: No redirect to HTTPS
  • Recommendation: Add middleware

2.21 No Security Headers

  • File: main.py
  • Issue: Missing X-Frame-Options, X-Content-Type-Options, etc.
  • Recommendation: Add security headers middleware

2.22 Debug Mode Default True in .env.example

  • File: .env.example
  • Line: 8
  • Issue: DEBUG=True exposes stack traces
  • Recommendation: Change to DEBUG=False for prod

2.23 No Secrets Management

  • Issue: No mechanism for API keys, secrets
  • Recommendation: Use environment variables with validation

2.24 No CSRF Protection

  • File: main.py
  • Issue: No CSRF tokens for state-changing operations
  • Recommendation: Add CSRF middleware

2.25 Subprocess Calls Should Use Capture Output

  • File: app/scanner/network_scanner.py
  • Line: 173
  • Issue: Using check_output() which can fail silently
  • Recommendation: Use subprocess.run() with better error handling

2.26 No Request Validation on Custom Ports

  • File: app/schemas.py
  • Issue: port_range: Optional[str] not validated
  • Recommendation: Add validator
@field_validator('port_range')
@classmethod
def validate_port_range(cls, v: Optional[str]) -> Optional[str]:
    if not v:
        return v
    # Validate format
    return v

2.27 No Request Size Limiting

  • File: main.py
  • Issue: No max request body size
  • Recommendation: Add middleware

2.28 Logging Contains Sensitive Data

  • File: All modules
  • Issue: IPs are logged but could contain sensitive patterns
  • Recommendation: Add log sanitization

3. IMPROVEMENTS (Nice to Have)

CODE QUALITY

3.1 Add Comprehensive Docstrings

  • Some functions missing detailed docstrings
  • Recommendation: Complete all docstrings with examples

3.2 Add Type Hints Throughout

  • Most code has type hints but some functions missing return types
  • Recommendation: Make type checking strict with mypy

3.3 Extract Magic Numbers to Constants

3.4 Add Dataclasses for Configuration

  • File: app/config.py
  • Issue: Using string literals for field names
  • Recommendation: Use more structured approach

3.5 Better Separation of Concerns

  • Service detection logic mixed with banner grabbing
  • Recommendation: Separate into distinct classes

TESTING

3.6 Add Unit Tests for Scanner Modules

  • File: tests/test_basic.py
  • Issue: Only basic tests, no scanner tests
  • Recommendation: Add comprehensive test suite

3.7 Add Integration Tests

  • No integration tests between components
  • Recommendation: Add API integration tests

3.8 Add E2E Tests

  • No end-to-end tests
  • Recommendation: Add WebDriver tests

3.9 Add Performance Tests

  • No benchmark tests
  • Recommendation: Test with different network sizes

3.10 Add Security Tests

  • No OWASP/security tests
  • Recommendation: Add security test suite

DOCUMENTATION

3.11 API Documentation Could Be Better

  • Using auto docs but could add more examples
  • Recommendation: Add OpenAPI examples

3.12 Add Architecture Diagrams

  • No visual architecture documentation
  • Recommendation: Add diagrams

3.13 Add Troubleshooting Guide

  • Recommendation: Expand troubleshooting section

3.14 Add Performance Tuning Guide

  • Recommendation: Document optimization tips

3.15 Add Deployment Guide

  • Missing Docker, cloud deployment docs
  • Recommendation: Add deployment examples (Docker, K8s, etc.)

4. VERIFICATION OF REQUIREMENTS

IMPLEMENTED

  • Network host discovery (basic socket-based)
  • Port scanning (socket and nmap)
  • Service detection (banner grabbing)
  • Network topology generation
  • WebSocket real-time updates
  • REST API endpoints
  • Database persistence
  • Frontend visualization

⚠️ PARTIALLY IMPLEMENTED

  • Error handling (inconsistent)
  • Security (basic only)
  • Logging (functional but sparse)
  • Configuration management (works but could be better)
  • Documentation (comprehensive but needs updates)

NOT IMPLEMENTED / CRITICAL GAPS

  • Authentication & authorization
  • Rate limiting
  • Request validation (partial)
  • Security headers
  • HTTPS enforcement
  • Database migrations
  • Backup strategy
  • Monitoring/alerting
  • Performance optimization
  • Load testing

5. SPECIFIC FIXES REQUIRED

MUST FIX (For Tool to Work)

Fix #1: Database Session in Background Tasks

File: app/api/endpoints/scans.py

# BEFORE
background_tasks.add_task(
    scan_service.execute_scan,
    scan.id,
    config,
    None
)

# AFTER
async def execute_scan_background(scan_id: int, config: ScanConfigRequest):
    scan_service = ScanService(SessionLocal())
    await scan_service.execute_scan(scan_id, config)

background_tasks.add_task(execute_scan_background, scan.id, config)

Fix #2: WebSocket Integration with Scans

File: app/services/scan_service.py

# Add at top:
from app.api.endpoints.websocket import broadcast_scan_update

# In execute_scan(), replace progress callbacks:
await broadcast_scan_update(scan_id, 'scan_progress', {
    'progress': progress,
    'current_host': current_host
})

Fix #3: Frontend Type Definitions

File: frontend/src/types/api.ts

export interface Service {
  id: number;
  host_id: number;
  port: number;
  protocol: string;
  service_name: string | null;
  service_version: string | null;
  state: string;
  banner: string | null;
  first_seen: string;
  last_seen: string;
}

export interface Host {
  id: number;
  ip_address: string;
  hostname: string | null;
  mac_address: string | null;
  status: 'online' | 'offline' | 'scanning';  // Changed
  last_seen: string;
  first_seen: string;
  // ... rest
}

export interface Scan {
  id: number;
  network_range: string;  // Changed from 'target'
  scan_type: 'quick' | 'standard' | 'deep' | 'custom';
  status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
  progress: number;
  hosts_found: number;  // Changed from 'total_hosts'
  ports_scanned: number;  // New field
  started_at: string;  // Changed from 'start_time'
  completed_at: string | null;  // Changed from 'end_time'
  error_message: string | null;
}

Fix #4: Environment Variables

File: frontend/.env.example (create if missing)

VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000

Fix #5: Thread Safety in WebSocket

File: app/api/endpoints/websocket.py

import asyncio

class ConnectionManager:
    def __init__(self):
        self.active_connections: Set[WebSocket] = set()
        self.lock = asyncio.Lock()
    
    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        async with self.lock:
            self.active_connections.add(websocket)
    
    def disconnect(self, websocket: WebSocket):
        # Note: Can't use async lock here, use sync removal
        self.active_connections.discard(websocket)
    
    async def broadcast(self, message: dict):
        disconnected = set()
        async with self.lock:
            connections_copy = self.active_connections.copy()
        
        for connection in connections_copy:
            try:
                await connection.send_json(message)
            except Exception as e:
                disconnected.add(connection)
        
        for connection in disconnected:
            self.disconnect(connection)

Fix #6: Install Frontend Dependencies

File: frontend/

npm install

Fix #7: Port Validation

File: app/scanner/port_scanner.py

def parse_port_range(self, port_range: str) -> List[int]:
    ports = set()
    
    try:
        for part in port_range.split(','):
            part = part.strip()
            
            if '-' in part:
                try:
                    start, end = map(int, part.split('-'))
                    if 1 <= start <= end <= 65535:
                        ports.update(range(start, end + 1))
                    else:
                        logger.error(f"Invalid port range: {start}-{end}")
                except ValueError:
                    logger.error(f"Invalid port format: {part}")
                    continue
            else:
                try:
                    port = int(part)
                    if 1 <= port <= 65535:
                        ports.add(port)
                    else:
                        logger.error(f"Port out of range: {port}")
                except ValueError:
                    logger.error(f"Invalid port: {part}")
                    continue
        
        return sorted(list(ports))
        
    except Exception as e:
        logger.error(f"Error parsing port range '{port_range}': {e}")
        return []

Fix #8: Search Input Validation

File: app/api/endpoints/hosts.py

@router.get("", response_model=List[HostResponse])
def list_hosts(
    status: Optional[str] = Query(None),
    limit: int = Query(100, ge=1, le=1000),
    offset: int = Query(0, ge=0),
    search: Optional[str] = Query(None, max_length=100),  # Add max_length
    db: Session = Depends(get_db)
):
    # ... rest of function

6. SUMMARY TABLE

Category Count Status
Critical Issues 22 🔴 MUST FIX
Warnings 28 🟡 SHOULD FIX
Improvements 15 🟢 NICE TO HAVE
Total Items 65 -

7. RISK ASSESSMENT

Security Risk: HIGH 🔴

  • No authentication
  • No CSRF protection
  • No rate limiting
  • Potential command injection (low probability due to list-based subprocess)

Functional Risk: HIGH 🔴

  • Background task database session issues
  • WebSocket not integrated with scans
  • Type mismatches between frontend/backend

Performance Risk: MEDIUM 🟡

  • SQLite concurrency limitations
  • No pagination for large datasets
  • Synchronous socket operations could block

Maintainability: MEDIUM 🟡

  • Good code structure overall
  • Needs better error handling
  • Documentation could be clearer

Phase 1: CRITICAL (Do First)

  1. Fix database session handling in background tasks
  2. Integrate WebSocket with scan execution
  3. Fix frontend types to match backend
  4. Install frontend dependencies
  5. Fix thread safety in WebSocket manager
  6. Add input validation for port ranges

Phase 2: HIGH (Do Next)

  1. Add authentication/authorization
  2. Add rate limiting
  3. Add request validation
  4. Fix CORS configuration
  5. Add error handlers

Phase 3: MEDIUM (Do Later)

  1. Add security headers
  2. Migrate from SQLite to PostgreSQL
  3. Add database migrations (Alembic)
  4. Improve logging
  5. Add monitoring

Phase 4: LOW (Future)

  1. Add comprehensive tests
  2. Add performance optimization
  3. Add Docker support
  4. Add cloud deployment docs

9. TESTING CHECKLIST

  • Backend imports without errors
  • Frontend dependencies install
  • Database initializes
  • API starts without errors
  • Can connect to WebSocket
  • Can start a scan
  • Can view scan progress in real-time
  • Can view discovered hosts
  • Can view network topology
  • Frontend displays data correctly
  • No memory leaks on long scans
  • No database connection errors

10. CONCLUSION

The network scanner is well-designed architecturally but has critical implementation issues that prevent it from being production-ready. The issues are primarily in:

  1. Integration between components (Backend ↔ Frontend, API ↔ WebSocket)
  2. Database session management in async contexts
  3. Type system alignment between frontend and backend
  4. Security considerations (authentication, rate limiting)

With the fixes in Phase 1 (estimated 4-6 hours), the tool would become functional.

With all fixes through Phase 2 (estimated 12-16 hours), the tool would be deployable to production.


Report Generated: December 4, 2025
Reviewer: ReviewAgent