Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Canary Detections

VulnCheck Canary Intelligence provides exploitation data from globally deployed vulnerable hosts revealing the first signs of vulnerability exploitation and tracking which CVEs are being targeted in the wild, and by whom.

VulnCheck Canary Exploitation Detection Metrics

Loading...

Known Exploited Vulnerabilities Reported by VulnCheck Canaries (Source: VulnCheck KEV)

Loading...

Known Exploited Vulnerabilities Reported by VulnCheck Canaries Not Present on CISA KEV (Source: VulnCheck KEV)

Source
# Copy original dataframe
df = df_original.copy()

# --- Clean up data types ---
df['Date Added'] = pd.to_datetime(df['Date Added'], errors='coerce')
df['CISA Date Added'] = df['CISA Date Added'].replace('none', pd.NaT)
df['CISA Date Added'] = pd.to_datetime(df['CISA Date Added'], format='%Y-%m-%d', errors='coerce')

# Ensure Canary is boolean
df['Canary'] = df['Canary'].astype(bool)

# --- Filter for Canary detections not on CISA KEV ---
df_canary_not_cisa = df[(df['Canary'] == True) & (df['CISA Date Added'].isnull())]

# --- Count occurrences by Vendor and Product ---
vendor_product_counts = (
    df_canary_not_cisa
    .groupby(['Vendor', 'Product'])
    .size()
    .reset_index(name='Counts')
)

# Truncate vendor and product names for readability
vendor_product_counts['Vendor'] = vendor_product_counts['Vendor'].str.slice(0, 15)
vendor_product_counts['Product'] = vendor_product_counts['Product'].str.slice(0, 15)

# --- Create Treemap ---
fig = px.treemap(
    vendor_product_counts,
    path=['Vendor', 'Product'],
    values='Counts',
    color='Counts',
    color_continuous_scale='Viridis'
)

# --- Customize layout for dark mode ---
fig.update_layout(
    title="VulnCheck Canaries — CVEs Not Present on CISA KEV (Source: VulnCheck KEV)",
    title_font=dict(size=20, color='white'),
    title_x=0.5,
    paper_bgcolor='black',
    plot_bgcolor='black',
    margin=dict(t=50, l=25, r=25, b=25),
    width=1800,
    height=1000
)

# --- Remove color scale and style labels ---
fig.update_coloraxes(showscale=False)
fig.update_traces(
    texttemplate='%{label}<br>%{value}',
    textfont_size=16,
    textfont_color='white'
)

fig.show()
Loading...