<?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: Arun Krishna</title>
    <description>The latest articles on DEV Community by Arun Krishna (@arun_krishna_eb30887b00fb).</description>
    <link>https://dev.to/arun_krishna_eb30887b00fb</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%2F4030746%2Ffe1eed1d-d4f3-4f91-a648-9da64a3abdb9.png</url>
      <title>DEV Community: Arun Krishna</title>
      <link>https://dev.to/arun_krishna_eb30887b00fb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arun_krishna_eb30887b00fb"/>
    <language>en</language>
    <item>
      <title>Building a User-Agent Risk Scorer: Rule Engine + Threat Intel + Community Voting</title>
      <dc:creator>Arun Krishna</dc:creator>
      <pubDate>Wed, 15 Jul 2026 16:35:16 +0000</pubDate>
      <link>https://dev.to/arun_krishna_eb30887b00fb/building-a-user-agent-risk-scorer-rule-engine-threat-intel-community-voting-a48</link>
      <guid>https://dev.to/arun_krishna_eb30887b00fb/building-a-user-agent-risk-scorer-rule-engine-threat-intel-community-voting-a48</guid>
      <description>&lt;p&gt;User-Agent strings are messy, spoofable, and technically "on their way out"&lt;br&gt;
with Client Hints — but in practice, almost every bot, scraper, and piece of&lt;br&gt;
malware still sends one, and most of them get it wrong in predictable ways.&lt;br&gt;
I built &lt;a href="https://uaintel.tech" rel="noopener noreferrer"&gt;UAIntel&lt;/a&gt; to catch those mistakes and score&lt;br&gt;
any UA string 0–100 for risk. Here's how it's structured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Rule Engine
&lt;/h2&gt;

&lt;p&gt;The first pass is pure pattern matching, no external data needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Impossible OS/browser combos&lt;/strong&gt; — e.g. a UA claiming to be Safari on
Windows, which doesn't exist in the real world&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version inconsistencies&lt;/strong&gt; — internal tokens that don't match each other
(e.g. a Chrome version number that doesn't line up with its WebKit build)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation signatures&lt;/strong&gt; — Selenium, Puppeteer, HeadlessChrome, and
similar framework fingerprints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raw HTTP libraries&lt;/strong&gt; — curl, python-requests, Go-http-client — not
browsers at all, but common in scraping traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This layer is fast (no lookups) and catches the most obvious cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Threat-Intel Database Lookups
&lt;/h2&gt;

&lt;p&gt;The second layer cross-references the UA against bundled threat feeds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nginx/Apache bad-bot blocklists&lt;/li&gt;
&lt;li&gt;SecLists' UA database&lt;/li&gt;
&lt;li&gt;mthcht's malware UA intelligence&lt;/li&gt;
&lt;li&gt;Matomo's device detector bot list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These feeds refresh weekly via a Cloudflare Workers cron trigger, so the&lt;br&gt;
in-memory dataset stays current without a manual redeploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Community Voting
&lt;/h2&gt;

&lt;p&gt;Some UAs are ambiguous even after the first two layers — this is where&lt;br&gt;
community reports come in. Anyone can flag a UA as malicious, bot, or&lt;br&gt;
benign, and that feedback factors into the score for future lookups of&lt;br&gt;
the same string. It's a small signal on its own, but compounds over time&lt;br&gt;
as more people use the tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm actively looking for edge cases it gets wrong — false positives on&lt;br&gt;
legitimate automation, or malware/scrapers it's not catching yet. If you&lt;br&gt;
work with logs, WAFs, or bot mitigation and have interesting UA strings&lt;br&gt;
lying around, I'd genuinely appreciate you running them through it:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://uaintel.tech" rel="noopener noreferrer"&gt;uaintel.tech&lt;/a&gt; — free, no signup.&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments.&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
