惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog
人人都是产品经理
人人都是产品经理
博客园 - 聂微东
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
小众软件
小众软件
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Google DeepMind News
Google DeepMind News
Jina AI
Jina AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
宝玉的分享
宝玉的分享
有赞技术团队
有赞技术团队
J
Java Code Geeks
WordPress大学
WordPress大学
The Cloudflare Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Why your vulnerability dashboard is lying to you (and how...
Apurv Tyagi · 2026-05-23 · via DEV Community

Apurv Tyagi

You open your vulnerability dashboard on a Monday morning and see 47 critical CVEs
across 12 assets. By Thursday, your team has patched 11 of the 12 assets. But the
dashboard still shows 40 criticals. What happened?

The assets were patched. The dashboard doesn't know that, because the vulnerability
scanner sees a different record than the asset your team was tracking. The same
physical server exists in your tools as:

Tool Identifier
AWS i-0a1b2c3d4e5f
CrowdStrike prod-api-07.internal
Tenable 10.0.4.22 (scan-time IP)
Qualys 10.0.4.23 (different scan window, NATted)

When Tenable reports the CVE patched on 10.0.4.22, your dashboard doesn't
automatically know that 10.0.4.22 is the same machine as prod-api-07.internal.
So it still shows the finding as open on the CrowdStrike record.

This is the asset identity problem. Most security teams have it. Almost nobody
talks about it.

The standard approaches — and why they fall short

"We use the hostname" — Hostnames are normalized differently by every tool.
Tenable might see prod-api-07, CrowdStrike sees prod-api-07.internal,
ServiceNow has PRODAPI007 from a manual entry made 8 months ago.

"We use the IP address" — IPs change. NAT means the scanner sees a different
IP than the one the EDR agent reports. A host that was 10.0.4.22 last week might
be 10.0.4.31 today.

"We have a CMDB" — Great, how fresh is it? Most CMDBs are 30–60% stale within
6 months of implementation. And you still need to write the correlation logic to
feed it.

A layered matching approach

The core insight is that no single identifier is reliable across tools, but
combining multiple identifiers with explicit confidence scoring gets you very far.

Here's the priority order:

Layer 1 — Hard IDs (confidence: 0.95–1.0)

Match on instanceId, EDR agentId, or MAC address. These are tool-native stable
identifiers. If two records share a hard ID, they're the same asset with near-certainty.

Layer 2 — Hostname (confidence: 0.45–0.85)

Normalize first: strip .local, .internal, case-fold, drop -prod/-dev
suffixes. Then match. Confidence scales with how unique the hostname looks.

Layer 3 — IP address (confidence: 0.60–0.75)

Public IPs get higher confidence than private IPs. Apply a staleness decay: an IP
seen 30 days ago is worth less than one seen yesterday. Private IPs in NAT-heavy
environments are unreliable and scored conservatively.

Layer 4 — Metadata (confidence: up to 0.50)

OS family + cloud region + account ID. Useful as a tie-breaker. Not enough alone.

Combine layers 2 and 3: 0.60 × hostname_score + 0.40 × ip_score. Merge if the
composite score is ≥ 0.70. Flag for human review if 0.50–0.69. Create a new
canonical record if < 0.50.

The key design principle: ambiguous matches are never silently merged. A 50%
confident merge creates ghost duplicates that are worse than no merge at all.

Building the canonical record

Once you've matched records, you merge them. But "merge" has a lot of edge cases:

  • Which hostname wins when AWS says prod-api-07 and the EDR says prod-api-07.internal? Answer: EDR is more authoritative for hostnames; AWS is more authoritative for region.
  • What about IP addresses? Union them — an asset can have both a private and public IP.
  • What if two sources report different OS names? Log the conflict with both values, both sources, and the resolution taken.

Every field disagreement should be logged with full lineage. Conflicts are data.

The open-source implementation

I've been writing this glue layer at multiple companies. Last week I open-sourced it.


bash
pip install security-asset-correlator
https://github.com/apurvtyagi/security-asset-correlator

Enter fullscreen mode Exit fullscreen mode