fix: IPs IPv4 avec notation ::ffff: corrigée

🐛 PROBLÈME:
• ClickHouse stocke les IPv4 en IPv6 (::ffff:x.x.x.x)
• Les requêtes SQL utilisaient toString() → '::ffff:1.2.3.4'
• Impossible de naviguer vers /entities/ip/::ffff:1.2.3.4

 SOLUTION:
• Utilisation de IPv4NumToString(toIPv4(src_ip))
• Convertit ::ffff:x.x.x.x → x.x.x.x
• Filtre isIPv4MappedIPv6() pour les IPv4 uniquement

BACKEND:
• Requête SQL mise à jour avec IPv4NumToString()
• sample_ip retourne maintenant 'x.x.x.x' (propre)
• subnet retourne 'x.x.x.0/24' (propre)

FRONTEND:
• Suppression cleanIP() et getSampleIP() (inutiles)
• Utilisation directe: cluster.sample_ip || cluster.subnet?.split('/')[0]
• Tous les boutons utilisent la même logique

RÉSULTAT:
• Avant: /entities/ip/::ffff:176.65.132.0 
• Après: /entities/ip/176.65.132.1 

 Build: SUCCESS
 Container: restarted

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
SOC Analyst
2026-03-14 22:53:00 +01:00
parent 1e0e5d211d
commit df0fe1387b
2 changed files with 14 additions and 37 deletions

View File

@ -107,24 +107,6 @@ export function IncidentsView() {
return code.toUpperCase().replace(/./g, char => String.fromCodePoint(char.charCodeAt(0) + 127397));
};
// Nettoyer une adresse IP (enlever ::ffff: prefix)
const cleanIP = (address: string): string => {
if (!address) return '';
return address.replace(/^::ffff:/i, '');
};
// Générer une IP exemple depuis un subnet
const getSampleIP = (subnet: string): string => {
const clean = cleanIP(subnet);
const ipParts = clean.replace('/24', '').split('.');
if (ipParts.length === 4) {
// Remplacer le dernier octet par 1
ipParts[3] = '1';
return ipParts.join('.');
}
return cleanIP(subnet.split('/')[0]);
};
if (loading) {
return (
<div className="flex items-center justify-center h-64">
@ -268,7 +250,7 @@ export function IncidentsView() {
</span>
<span className="text-lg font-bold text-text-primary">{cluster.id}</span>
<span className="text-text-secondary">|</span>
<span className="font-mono text-sm text-text-primary">{cleanIP(cluster.subnet || '')}</span>
<span className="font-mono text-sm text-text-primary">{cluster.subnet || ''}</span>
</div>
<div className="flex items-center gap-4">
<div className="text-right">
@ -322,13 +304,13 @@ export function IncidentsView() {
<div className="flex gap-2">
<button
onClick={() => navigate(`/investigation/${cleanIP(cluster.sample_ip || getSampleIP(cluster.subnet || ''))}`)}
onClick={() => navigate(`/investigation/${cluster.sample_ip || cluster.subnet?.split('/')[0] || ''}`)}
className="px-3 py-1.5 bg-accent-primary text-white rounded text-sm hover:bg-accent-primary/80 transition-colors"
>
Investiguer
</button>
<button
onClick={() => navigate(`/entities/ip/${cleanIP(cluster.sample_ip || getSampleIP(cluster.subnet || ''))}`)}
onClick={() => navigate(`/entities/ip/${cluster.sample_ip || cluster.subnet?.split('/')[0] || ''}`)}
className="px-3 py-1.5 bg-background-card text-text-primary rounded text-sm hover:bg-background-card/80 transition-colors"
>
Voir détails
@ -336,7 +318,7 @@ export function IncidentsView() {
<button
onClick={() => {
// Quick classify
navigate(`/bulk-classify?ips=${encodeURIComponent(cleanIP(cluster.sample_ip || getSampleIP(cluster.subnet || '')))}`);
navigate(`/bulk-classify?ips=${encodeURIComponent(cluster.sample_ip || cluster.subnet?.split('/')[0] || '')}`);
}}
className="px-3 py-1.5 bg-background-card text-text-primary rounded text-sm hover:bg-background-card/80 transition-colors"
>
@ -351,7 +333,7 @@ export function IncidentsView() {
objects: [{
type: 'indicator',
id: `indicator--${cluster.id}`,
pattern: `[ipv4-addr:value = '${cleanIP(cluster.subnet?.split('/')[0] || '')}'`,
pattern: `[ipv4-addr:value = '${cluster.subnet?.split('/')[0] || ''}'`,
pattern_type: 'stix'
}]
};
@ -415,7 +397,7 @@ export function IncidentsView() {
>
<td className="px-4 py-3 text-text-secondary">{index + 1}</td>
<td className="px-4 py-3 font-mono text-sm text-text-primary">
{cleanIP(cluster.subnet?.split('/')[0] || 'Unknown')}
{cluster.subnet?.split('/')[0] || 'Unknown'}
</td>
<td className="px-4 py-3 text-sm text-text-secondary">IP</td>
<td className="px-4 py-3">