<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: logtriage</title>
    <description>The latest articles on DEV Community by logtriage (@logtriage).</description>
    <link>https://dev.to/logtriage</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4014883%2Fdc392349-9969-4dfd-bf9e-4e7e3525fd8d.png</url>
      <title>DEV Community: logtriage</title>
      <link>https://dev.to/logtriage</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/logtriage"/>
    <language>en</language>
    <item>
      <title>What a Single Confirmed-Malicious Threat Intel Hit Should Do to Your Risk Score</title>
      <dc:creator>logtriage</dc:creator>
      <pubDate>Mon, 21 Sep 2026 09:31:35 +0000</pubDate>
      <link>https://dev.to/logtriage/what-a-single-confirmed-malicious-threat-intel-hit-should-do-to-your-risk-score-a2a</link>
      <guid>https://dev.to/logtriage/what-a-single-confirmed-malicious-threat-intel-hit-should-do-to-your-risk-score-a2a</guid>
      <description>&lt;p&gt;A common design pattern in risk scoring is purely additive: every signal contributes some number of points, capped, and the points add up to a final score. It's simple to reason about and easy to tune — until a single very strong signal shows up, and the additive model quietly under-reacts to it.&lt;/p&gt;

&lt;p&gt;Here's a concrete version of the problem we ran into: an IP address confirmed by ThreatFox as active Cobalt Strike command-and-control infrastructure, at 100% confidence, contacting an API endpoint. Under a purely additive model, that ThreatFox match contributed a capped +30 points. Combined with a low-risk user-agent signal, the event landed at 33 out of 100 — solidly in "LOW" severity, comfortably under the threshold for deeper automated review.&lt;/p&gt;

&lt;p&gt;That's the wrong outcome. A single, independent, high-confidence confirmation that an IP is &lt;em&gt;known&lt;/em&gt; malware infrastructure shouldn't compete on equal footing with a dozen soft probabilistic signals that each nudge the score up a little. It should dominate the score, because the evidentiary weight isn't comparable — "this user-agent is unusual" and "this exact IP is a confirmed Cobalt Strike C2 node" are not the same category of evidence, even though an additive model treats them as fungible points.&lt;/p&gt;

&lt;p&gt;The fix was a floor rule, not a bigger additive weight: any single source independently confirming "this is malicious" — a ThreatFox IOC match, an OTX malicious flag, a non-RIOT GreyNoise malicious classification, AbuseIPDB confidence at or above 75%, or a malicious sandbox verdict — floors the event's score to 75, regardless of what the additive components alone produced. The same Cobalt Strike event that scored 33 before now scores 75, clears the threshold for full AI-assisted analysis, and gets treated with the urgency a confirmed C2 contact actually deserves.&lt;/p&gt;

&lt;p&gt;The general lesson generalizes past this one rule: additive scoring is a reasonable default for combining many weak-to-moderate signals, but it systematically under-weights rare, high-confidence, independent confirmations. If your scoring model has any signal that's supposed to mean "we are sure," it needs a floor, not just a point value.&lt;/p&gt;

</description>
      <category>security</category>
      <category>detection</category>
      <category>logging</category>
      <category>devops</category>
    </item>
    <item>
      <title>Detecting Impossible Travel Without Expensive UEBA Tooling</title>
      <dc:creator>logtriage</dc:creator>
      <pubDate>Fri, 18 Sep 2026 06:54:31 +0000</pubDate>
      <link>https://dev.to/logtriage/detecting-impossible-travel-without-expensive-ueba-tooling-34pe</link>
      <guid>https://dev.to/logtriage/detecting-impossible-travel-without-expensive-ueba-tooling-34pe</guid>
      <description>&lt;p&gt;Impossible travel detection has a reputation for being an enterprise-only feature, bundled into UEBA platforms that cost more than the rest of a security stack combined. The underlying math is not complicated, and most identity providers already give you everything you need in the raw sign-in log.&lt;/p&gt;

&lt;p&gt;The calculation is the haversine formula — the great-circle distance between two latitude/longitude points — divided by the elapsed time between two consecutive sign-ins for the same account. If that implied speed exceeds what's physically possible (LogTriage defaults to 500 km/h, comfortably above commercial flight speed but well below "instantaneous"), the pair gets flagged. That's the entire algorithm. No machine learning model, no behavioral baseline period, no training data.&lt;/p&gt;

&lt;p&gt;The harder part isn't the math — it's getting clean coordinates. Azure AD sign-in logs include &lt;code&gt;location.geoCoordinates&lt;/code&gt; directly, which makes this nearly free for Entra ID. For log formats that don't carry their own geolocation, the fallback is IP-based geolocation through a standard enrichment pipeline, which is noisier (VPN exits, mobile carrier NAT, and corporate proxies all distort it) but still catches the cases that matter: an account signing in from two countries within minutes is suspicious by any geolocation method, even an imprecise one.&lt;/p&gt;

&lt;p&gt;It's worth being honest about the false-positive sources too: a VPN client switching exit nodes, or a mobile user moving between cell towers near a regional border, can produce a coordinate jump that isn't actually impossible travel. A minimum-distance filter (LogTriage defaults to 100km) screens out same-metro noise, but no implementation of this check is going to be zero-false-positive — which is exactly why it should feed into an analyst's report as one risk factor among several, not an automatic account lockout trigger on its own.&lt;/p&gt;

</description>
      <category>security</category>
      <category>detection</category>
      <category>logging</category>
      <category>devops</category>
    </item>
    <item>
      <title>Why a curl User-Agent Isn't Automatically Malicious</title>
      <dc:creator>logtriage</dc:creator>
      <pubDate>Sun, 05 Jul 2026 06:38:20 +0000</pubDate>
      <link>https://dev.to/logtriage/why-a-curl-user-agent-isnt-automatically-malicious-393a</link>
      <guid>https://dev.to/logtriage/why-a-curl-user-agent-isnt-automatically-malicious-393a</guid>
      <description>&lt;p&gt;A surprising number of security tools treat user-agent strings as a static blocklist: see &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;python-requests&lt;/code&gt;, or &lt;code&gt;Go-http-client&lt;/code&gt;, raise an alert. In practice, this produces so many false positives that analysts learn to ignore the alert entirely — which defeats the purpose of having it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl&lt;/code&gt; hitting a public &lt;code&gt;/health&lt;/code&gt; endpoint is completely unremarkable; it's almost certainly a monitoring probe or a developer's smoke test. The same &lt;code&gt;curl&lt;/code&gt; user-agent posting to &lt;code&gt;/api/v1/admin/users&lt;/code&gt; or &lt;code&gt;/api/v1/beacon&lt;/code&gt; is a different story. The string itself didn't change. What changed is the &lt;em&gt;context&lt;/em&gt; — the path being accessed, the response it got, what else that source IP did in the same session.&lt;/p&gt;

&lt;p&gt;This is why context-aware risk scoring doesn't operate on the user-agent alone. A suspicious user-agent match is one signal among several: path sensitivity, ASN reputation, IP threat intelligence, and behavioral patterns from session grouping all feed into the same score. A compound-signal rule specifically rewards combinations — three or more independent high-severity indicators on the same event get a 1.25× multiplier. A &lt;code&gt;curl&lt;/code&gt; request to a low-sensitivity endpoint from a clean IP stays low risk. The same user-agent on a sensitive admin path, from an ASN already flagged in a threat intelligence feed, compounds quickly.&lt;/p&gt;

&lt;p&gt;The broader principle: a security tool that can't tell &lt;code&gt;curl&lt;/code&gt; apart by context isn't actually doing risk assessment — it's pattern matching with an extra step.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I build &lt;a href="https://logtriage.app" rel="noopener noreferrer"&gt;LogTriage&lt;/a&gt; and publish a free, validated Sigma detection-rule library — each rule tested against a real sample log before it ships: &lt;a href="https://logtriage.app/rules/" rel="noopener noreferrer"&gt;logtriage.app/rules&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
      <category>detection</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
