<?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: Atena</title>
    <description>The latest articles on DEV Community by Atena (@atenahfr).</description>
    <link>https://dev.to/atenahfr</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%2F4027857%2F4e338845-528d-4217-bb88-173629257ccf.png</url>
      <title>DEV Community: Atena</title>
      <link>https://dev.to/atenahfr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/atenahfr"/>
    <language>en</language>
    <item>
      <title>I Added ML Anamoly Detection to My Cybersecurity Tool - Here's What the Numbers Actually Showed</title>
      <dc:creator>Atena</dc:creator>
      <pubDate>Sat, 15 Aug 2026 19:25:45 +0000</pubDate>
      <link>https://dev.to/atenahfr/i-added-ml-anamoly-detection-to-my-cybersecurity-tool-heres-what-the-numbers-actually-showed-4jpp</link>
      <guid>https://dev.to/atenahfr/i-added-ml-anamoly-detection-to-my-cybersecurity-tool-heres-what-the-numbers-actually-showed-4jpp</guid>
      <description>&lt;p&gt;A few weeks ago, I built Log Sentinel, a log analysis dashboard that detects brute force attacks, directory scanning, and error spikes in Apache server logs using rule-based detectors. The rules worked well, but I kept wondering: what would a machine learning model catch that my rules missed? And more importantly, would ML actually be better?&lt;/p&gt;

&lt;p&gt;I spent two weeks adding an Isolation Forest model to find out. The results were more interesting than I expected. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ML upgrade adds a second detection layer on top of the existing rule-based system. Instead of checking specific conditions like "did this IP make 10+ failed logins?", the Isolation Forest learns what normal traffic looks like from the data itself and flags anything statistically unusual.&lt;/p&gt;

&lt;p&gt;Before the model can run, I transform each IP address into a 5-feature behavioural vector:&lt;/p&gt;

&lt;p&gt;request_count — total requests made&lt;br&gt;
error_rate — fraction of requests returning 4xx or 5xx errors&lt;br&gt;
unique_paths — how many different URLs they visited&lt;br&gt;
night_traffic_ratio — fraction of requests made between midnight and 6 am&lt;br&gt;
avg_bytes — average response size&lt;/p&gt;

&lt;p&gt;All five features get normalized to mean=0, std=1 using StandardScaler. Without normalization, an IP with 1000 requests would dominate an IP with 10 requests purely because of scale.&lt;/p&gt;

&lt;p&gt;The model is configured with contamination=0.15; I tuned this by testing values from 0.05 to 0.50 and picking the one with the best F1 score on a labelled evaluation dataset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The evaluation setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To measure performance properly, I generated a labelled dataset of 230 IPs: 200 normal and 30 attackers (10 brute force, 10 directory scanners, 10 error spikers). Each IP has a ground truth label so I can compute precision, recall, and F1 for both detectors.&lt;/p&gt;

&lt;p&gt;Printing accuracy on training data proves nothing. You need labelled ground truth to know if your model actually works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Metric  Rule-Based  Isolation Forest&lt;br&gt;
Precision   1.0000  0.8571&lt;br&gt;
Recall  1.0000  1.0000&lt;br&gt;
F1 Score    1.0000  0.9231&lt;br&gt;
False Positives 0   5&lt;br&gt;
False Negatives 0   0&lt;/p&gt;

&lt;p&gt;The rule-based detectors achieved perfect scores. The Isolation Forest caught every single attacker (recall=1.0) but flagged 5 innocent IPs along the way (precision=0.857).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this actually means&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My first instinct was to be disappointed that ML didn't win. But the more I thought about it, the more interesting the result became.&lt;/p&gt;

&lt;p&gt;The rule-based detectors achieved perfect scores because the evaluation dataset contains well-defined, structured attack patterns, exactly the patterns the rules were written to catch. Of course they're perfect: I designed both the rules and the data.&lt;/p&gt;

&lt;p&gt;The Isolation Forest's false positives tell a different story. It flagged 5 normal IPs that happened to have slightly unusual behaviour; maybe they made a burst of requests, or visited an uncommon path. The model found something statistically interesting about them even though they weren't attackers.&lt;/p&gt;

&lt;p&gt;In a real production environment, this is actually the more valuable behaviour. Rules only catch what you anticipated. ML catches things you didn't think to write rules for.&lt;/p&gt;

&lt;p&gt;The real insight is that both detectors belong in the same system. Rules handle known attack signatures with zero false alarms. ML handles the unknown. My dashboard now runs both and shows you exactly where they agree and where they disagree, which is where the interesting cases live.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I'd do differently&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The biggest limitation of my evaluation is that I generated the labelled dataset myself. Real attack patterns are messier and more diverse than synthetic data. A more honest evaluation would use real labelled log data from a production environment.&lt;/p&gt;

&lt;p&gt;I'd also experiment with other unsupervised algorithms; Local Outlier Factor and One-Class SVM are worth comparing against Isolation Forest on the same dataset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The live dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both detectors run on every analysis. The dashboard has three views: rule-based results, ML results, and a comparison showing which IPs were caught by both, rules only, or ML only. There's also a Model Performance section showing the confusion matrices and F1 scores side by side.&lt;/p&gt;

&lt;p&gt;Live demo: atenahfr.github.io/log-sentinel/frontend/index.html&lt;/p&gt;

&lt;p&gt;Source code: github.com/atenahfr/log-sentinel&lt;/p&gt;

</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>cybersecurity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How I Built a Log Analysis Tool to Detect Network Anomalies</title>
      <dc:creator>Atena</dc:creator>
      <pubDate>Mon, 13 Jul 2026 22:47:52 +0000</pubDate>
      <link>https://dev.to/atenahfr/how-i-built-a-log-analysis-tool-to-detect-network-anomalies-45ed</link>
      <guid>https://dev.to/atenahfr/how-i-built-a-log-analysis-tool-to-detect-network-anomalies-45ed</guid>
      <description>&lt;p&gt;When I started this project, I wanted to build something that actually does something, not another todo app or weather widget. I'm a third-year CS student at TMU, and I wanted a portfolio project that would make a security engineer say, "Oh, that's interesting."&lt;/p&gt;

&lt;p&gt;The result is Log Sentinel, a log analysis dashboard that parses Apache server logs, detects suspicious patterns, scores threats by risk level, and explains every detection in plain English. &lt;/p&gt;

&lt;p&gt;Here's how I built it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem with most log analysis tools&lt;/strong&gt;&lt;br&gt;
Most tools tell you what was flagged. They show you a table of IPs and error codes. But they don't tell you why it's suspicious or what to do about it. &lt;/p&gt;

&lt;p&gt;I wanted Log Sentinel to be different. Every flagged event generates a plain-English explanation like:&lt;br&gt;
"This IP made 40 failed login attempts on /login. Normal users fail 1-2 times at most. This volume strongly suggests an automated brute force attack."&lt;/p&gt;

&lt;p&gt;This makes the tool readable by non-technical stakeholders, not just security engineers. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The detection logic&lt;/strong&gt;&lt;br&gt;
I built four rule-based anomaly detectors using Python and pandas:&lt;/p&gt;

&lt;p&gt;Brute force detection: if the same IP makes more than 10 failed login attempts (HTTP 401 on /login), it gets flagged. Real brute force attacks look exactly like this: hundreds of automated requests hitting the same endpoint.&lt;/p&gt;

&lt;p&gt;Directory scanning: attackers use automated tools to probe servers for hidden files like /.env, /admin, /config.php. Each probe returns a 404. I flag any IP generating more than 10 404 errors.&lt;/p&gt;

&lt;p&gt;Server error spikes: repeated 500 errors from the same IP often mean someone is sending malformed requests, possibly attempting injection attacks. I flag IPs causing more than 5 server errors.&lt;/p&gt;

&lt;p&gt;Off-hours traffic: legitimate users are rarely active at 3 am. Any traffic between midnight and 6 am gets flagged as inherently suspicious, regardless of volume. &lt;/p&gt;

&lt;p&gt;Each detector returns a pandas DataFrame with the flagged IP, the count that triggered it, and an auto-generated explanation built from the actual numbers. &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;The risk scoring system *&lt;/em&gt;&lt;br&gt;
Different attack types carry different weights. I assigned base scores based on severity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Brute force: 80 points&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server error spike: 60 points&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Directory scanning: 40 points&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Off-hours traffic: 30 points&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If one IP triggers multiple detectors, the scores stack. An IP doing brute force during off-hours gets 110 points, automatically labelled Critical. This makes the dashboard immediately scannable: biggest threats at the top, explained in plain English. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The technical stack&lt;/strong&gt;&lt;br&gt;
The backend is Python and Flask. pandas handles all the log parsing and aggregation; groupie operations make it easy to count events per IP, calculate hourly averages, and flag statistical outliers. &lt;/p&gt;

&lt;p&gt;The frontend is a single HTML file with a terminal aesthetic, matrix rain animation, monospace font, and green-on-black colour scheme. I built the timeline chart from scratch using HTML divs instead of Chart.js, which gave me more control over the animations and styling. &lt;/p&gt;

&lt;p&gt;The whole thing is deployed on Render (backend) and GitHub Pages (frontend), with a /api/demo endpoint that generates sample attack data so anyone can see it working instantly without uploading a file. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I'd build next&lt;/strong&gt;&lt;br&gt;
The rule-based detectors work well, but they have fixed thresholds. The next evolution would be replacing them with scikit-learn's Isolation Forest, an unsupervised anomaly detection algorithm that learns what "normal" traffic looks like and flags statistical outliers automatically. &lt;/p&gt;

&lt;p&gt;I'd also add an SQLite database to store analysis history, so you can track whether the same IP appears across multiple sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it yourself&lt;/strong&gt;&lt;br&gt;
The live demo is at atenahfr.github.io/log-sentinel/frontend/index.html - click Load Demo and the full threat report appears instantly. &lt;/p&gt;

&lt;p&gt;The full source code is on GitHub. &lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>flask</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
