security: fix 3 medium-severity vulnerabilities (Fase 3 partial)
MEDIUM-SEVERITY FIXES: 1. Mock Data em Produção (Vulnerabilidade 3.2) - Mock data apenas em desenvolvimento (import.meta.env.DEV) - Produção mostra erro claro: "Não foi possível carregar os dados" - Estado de erro com UI para retry - Import AlertCircle icon 2. Tipo 'any' em Catch Blocks (Vulnerabilidade 3.4 - partial) - api/routes/wp-monitor.ts: catch (error: unknown) - Type guard: error instanceof Error - Mensagens seguras sem vazamento de stack trace 3. Algoritmos SSH Legacy (Vulnerabilidade 3.6) - Adicionados: curve25519-sha256, curve25519-sha256@libssh.org - Removidos: diffie-hellman-group14-sha1 (legacy) - Removidos: diffie-hellman-group1-sha1 (INSEGURO) - Mantidos apenas SHA256+ algorithms FILES CHANGED: - src/App.tsx - Error state + mock data apenas em dev - api/routes/wp-monitor.ts - Tipos unknown em catch - api/services/server-metrics.ts - Algoritmos SSH modernos PROGRESS: - Vulnerabilidade 3.2: ✅ FIXED - Vulnerabilidade 3.4: 🔄 IN PROGRESS (2/10 files) - Vulnerabilidade 3.6: ✅ FIXED Related: AUDIT-REPORT.md vulnerabilities 3.2, 3.4, 3.6 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -58,9 +58,10 @@ router.get('/', validateApiKey, async (req: Request, res: Response) => {
|
||||
total: result.length,
|
||||
timestamp: new Date().toISOString()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('WP Monitor GET error:', error)
|
||||
res.status(500).json({ error: 'Database error', message: (error as Error).message })
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
console.error('WP Monitor GET error:', message)
|
||||
res.status(500).json({ error: 'Database error', message })
|
||||
}
|
||||
})
|
||||
|
||||
@@ -105,9 +106,10 @@ router.post('/', validateApiKey, validateRequest(wpMonitorSchema), async (req: R
|
||||
status,
|
||||
timestamp: new Date().toISOString()
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('WP Monitor POST error:', error)
|
||||
res.status(500).json({ error: 'Database error', message: (error as Error).message })
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof Error ? error.message : 'Unknown error'
|
||||
console.error('WP Monitor POST error:', message)
|
||||
res.status(500).json({ error: 'Database error', message })
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -136,13 +136,15 @@ function executeSSH(server: SSHServer, command: string): Promise<string> {
|
||||
readyTimeout: 15000,
|
||||
algorithms: {
|
||||
kex: [
|
||||
// Algoritmos modernos (Vulnerabilidade 3.6)
|
||||
'curve25519-sha256',
|
||||
'curve25519-sha256@libssh.org',
|
||||
'ecdh-sha2-nistp256',
|
||||
'ecdh-sha2-nistp384',
|
||||
'ecdh-sha2-nistp521',
|
||||
'diffie-hellman-group-exchange-sha256',
|
||||
'diffie-hellman-group14-sha256',
|
||||
'diffie-hellman-group14-sha1',
|
||||
'diffie-hellman-group1-sha1'
|
||||
'diffie-hellman-group14-sha256'
|
||||
// REMOVIDOS (inseguros): diffie-hellman-group14-sha1, diffie-hellman-group1-sha1
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
39
src/App.tsx
39
src/App.tsx
@@ -4,6 +4,7 @@ import {
|
||||
Calendar,
|
||||
CalendarDays,
|
||||
AlertTriangle,
|
||||
AlertCircle,
|
||||
Clock,
|
||||
Zap,
|
||||
RefreshCw,
|
||||
@@ -420,6 +421,7 @@ function App() {
|
||||
const [data, setData] = useState<DashboardData | null>(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [refreshing, setRefreshing] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
@@ -431,7 +433,13 @@ function App() {
|
||||
setData(json)
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch dashboard data:', error)
|
||||
setData(getMockData())
|
||||
|
||||
// Mock data apenas em desenvolvimento (Vulnerabilidade 3.2)
|
||||
if (import.meta.env.DEV) {
|
||||
setData(getMockData())
|
||||
} else {
|
||||
setError('Não foi possível carregar os dados. Tente novamente.')
|
||||
}
|
||||
} finally {
|
||||
setLoading(false)
|
||||
setRefreshing(false)
|
||||
@@ -470,6 +478,35 @@ function App() {
|
||||
)
|
||||
}
|
||||
|
||||
// Error state (Vulnerabilidade 3.2)
|
||||
if (error) {
|
||||
return (
|
||||
<div className="min-h-screen bg-mesh flex items-center justify-center">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="text-center max-w-md mx-auto px-6"
|
||||
>
|
||||
<div className="w-20 h-20 rounded-2xl bg-red-500/10 flex items-center justify-center mx-auto mb-6 border border-red-500/20">
|
||||
<AlertCircle className="w-10 h-10 text-red-500" />
|
||||
</div>
|
||||
<h2 className="text-xl font-semibold text-white mb-2">Erro ao Carregar</h2>
|
||||
<p className="text-zinc-400 mb-6">{error}</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
setError(null)
|
||||
setLoading(true)
|
||||
fetchData()
|
||||
}}
|
||||
className="px-6 py-3 bg-brand-500 hover:bg-brand-600 text-white rounded-xl transition-colors"
|
||||
>
|
||||
Tentar Novamente
|
||||
</button>
|
||||
</motion.div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!data) return null
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user