Files
werkzeuge/teamleader_test/archive/review-2025-12-04/CRITICAL_FIXES.md
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

326 lines
9.0 KiB
Markdown

# CRITICAL FIXES - Quick Reference
## 🔴 BLOCKERS THAT PREVENT THE TOOL FROM WORKING
### 1. Frontend Dependencies Missing
```bash
cd frontend
npm install
```
**Why**: 537 TypeScript errors preventing compilation
---
### 2. Frontend Type Mismatches
**File**: `frontend/src/types/api.ts`
Replace lines 5-46 with:
```typescript
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
}
export interface Host {
id: number;
ip_address: string;
hostname: string | null;
mac_address: string | null;
status: 'online' | 'offline' | 'scanning'; // ← WRONG: was 'up' | 'down'
last_seen: string;
first_seen: string;
scan_id: number | null;
}
export interface Scan {
id: number;
network_range: string; // ← WRONG: was 'target'
scan_type: 'quick' | 'standard' | 'deep' | 'custom';
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
progress: number;
hosts_found: number; // ← WRONG: was 'total_hosts'
ports_scanned: number; // ← WRONG: was 'hosts_scanned'
started_at: string; // ← WRONG: was 'start_time'
completed_at: string | null; // ← WRONG: was 'end_time'
error_message: string | null;
}
```
**Why**: Frontend will crash at runtime when API returns data
---
### 3. Database Session Leaks in Background Tasks
**File**: `app/api/endpoints/scans.py`
Replace the `start_scan` function (lines 19-52) with:
```python
@router.post("/start", response_model=ScanStartResponse, status_code=202)
async def start_scan(
config: ScanConfigRequest,
background_tasks: BackgroundTasks,
db: Session = Depends(get_db)
):
"""Start a new network scan."""
try:
scan_service = ScanService(db)
scan = scan_service.create_scan(config)
# Schedule background execution with fresh session
async def run_scan():
fresh_db = SessionLocal()
try:
fresh_service = ScanService(fresh_db)
await fresh_service.execute_scan(scan.id, config)
finally:
fresh_db.close()
background_tasks.add_task(run_scan)
logger.info(f"Started scan {scan.id} for {config.network_range}")
return ScanStartResponse(
scan_id=scan.id,
message=f"Scan started for network {config.network_range}",
status=ScanStatusEnum.PENDING
)
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Error starting scan: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to start scan")
```
**Why**: Current code passes db session that closes before scan executes
---
### 4. WebSocket Not Connected to Scan Updates
**File**: `app/services/scan_service.py`
Add import at top (line 5):
```python
from app.api.endpoints.websocket import broadcast_scan_update
```
Replace the progress callbacks (around lines 302-322) with:
```python
def _on_host_progress(
self,
scan_id: int,
host: str,
progress: float,
callback: Optional[callable]
) -> None:
"""Handle host discovery progress."""
# Broadcast via WebSocket
asyncio.run_coroutine_threadsafe(
broadcast_scan_update(scan_id, 'scan_progress', {
'progress': progress * 0.5,
'current_host': host
}),
asyncio.get_event_loop()
)
def _on_port_progress(
self,
scan_id: int,
host: str,
port: int,
progress: float,
callback: Optional[callable]
) -> None:
"""Handle port scanning progress."""
asyncio.run_coroutine_threadsafe(
broadcast_scan_update(scan_id, 'scan_progress', {
'progress': 0.5 + (progress * 0.5),
'current_host': host,
'current_port': port
}),
asyncio.get_event_loop()
)
```
**Why**: Users won't see real-time scan progress
---
### 5. WebSocket Thread Safety Issue
**File**: `app/api/endpoints/websocket.py`
Replace the `ConnectionManager` class (lines 8-56) with:
```python
class ConnectionManager:
"""Manager for WebSocket connections."""
def __init__(self):
"""Initialize connection manager."""
self.active_connections: Set[WebSocket] = set()
self.lock = asyncio.Lock()
async def connect(self, websocket: WebSocket):
"""Accept and register a new WebSocket connection."""
await websocket.accept()
async with self.lock:
self.active_connections.add(websocket)
logger.info(f"WebSocket connected. Total: {len(self.active_connections)}")
def disconnect(self, websocket: WebSocket):
"""Remove a WebSocket connection."""
self.active_connections.discard(websocket)
logger.info(f"WebSocket disconnected. Total: {len(self.active_connections)}")
async def send_personal_message(self, message: dict, websocket: WebSocket):
"""Send message to specific WebSocket."""
try:
await websocket.send_json(message)
except Exception as e:
logger.error(f"Error sending message: {e}")
self.disconnect(websocket)
async def broadcast(self, message: dict):
"""Broadcast message to all connected WebSockets."""
disconnected = set()
# Make a copy under lock
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:
logger.error(f"Error broadcasting: {e}")
disconnected.add(connection)
# Clean up disconnected
for connection in disconnected:
self.disconnect(connection)
```
**Why**: Race conditions can lose connections or cause crashes
---
### 6. Frontend Environment Variables
**Create file**: `frontend/.env.example`
```env
VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000
```
**Create file**: `frontend/.env`
```env
VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000
```
**Why**: Frontend can't connect to backend without these
---
### 7. Port Range Validation
**File**: `app/scanner/port_scanner.py`
Replace `parse_port_range` method (lines 128-157) with:
```python
def parse_port_range(self, port_range: str) -> List[int]:
"""Parse port range string to list of ports."""
ports = set()
try:
for part in port_range.split(','):
part = part.strip()
if not part:
continue
try:
if '-' in part:
# Range like "8000-8100"
parts = part.split('-')
if len(parts) != 2:
logger.error(f"Invalid range format: {part}")
continue
start, end = int(parts[0].strip()), int(parts[1].strip())
if not (1 <= start <= end <= 65535):
logger.error(f"Port range out of bounds: {start}-{end}")
continue
ports.update(range(start, end + 1))
else:
# Single port
port = int(part)
if not (1 <= port <= 65535):
logger.error(f"Port out of range: {port}")
continue
ports.add(port)
except ValueError as e:
logger.error(f"Invalid port specification: {part}")
continue
return sorted(list(ports))
except Exception as e:
logger.error(f"Error parsing port range '{port_range}': {e}")
return []
```
**Why**: Invalid port ranges cause uncaught exceptions
---
### 8. Search Input Validation
**File**: `app/api/endpoints/hosts.py`
Update line 20:
```python
search: Optional[str] = Query(None, max_length=100, description="Search by IP or hostname"),
```
**Why**: Prevents DoS with huge search strings
---
## Testing Verification
Run these to verify fixes work:
```bash
# Backend
python -c "from app.database import init_db; init_db(); print('✅ DB OK')"
python -c "from app.api.endpoints.websocket import manager; print('✅ WebSocket OK')"
# Frontend
cd frontend && npm install && npm run build
# Should complete without errors
```
---
## Deploy Checklist After Fixes
- [ ] Backend starts without errors: `python main.py`
- [ ] Frontend builds: `cd frontend && npm run build`
- [ ] API responds: `curl http://localhost:8000/health`
- [ ] WebSocket connects: Check browser console
- [ ] Can start scan via API
- [ ] Real-time updates in WebSocket
- [ ] Frontend shows scan progress
- [ ] Hosts display correctly
---
**Estimated Time to Fix**: 2-3 hours for experienced developer