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>
This commit is contained in:
325
teamleader_test/archive/review-2025-12-04/CRITICAL_FIXES.md
Normal file
325
teamleader_test/archive/review-2025-12-04/CRITICAL_FIXES.md
Normal file
@@ -0,0 +1,325 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user