<?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: ALI MANSOOR</title>
    <description>The latest articles on Forem by ALI MANSOOR (@theali711).</description>
    <link>https://forem.com/theali711</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%2F712760%2F2ca1acf5-3641-4b88-9aaf-1e21b2d28107.jpeg</url>
      <title>Forem: ALI MANSOOR</title>
      <link>https://forem.com/theali711</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/theali711"/>
    <language>en</language>
    <item>
      <title>Inside a Real Production Server Breach</title>
      <dc:creator>ALI MANSOOR</dc:creator>
      <pubDate>Sun, 24 May 2026 14:10:40 +0000</pubDate>
      <link>https://forem.com/theali711/inside-a-real-production-server-breach-ncj</link>
      <guid>https://forem.com/theali711/inside-a-real-production-server-breach-ncj</guid>
      <description>&lt;p&gt;Just a normal day.&lt;br&gt;
23rd May, 2026.&lt;/p&gt;

&lt;p&gt;Wake up in the morning, pick up my friend from his house, head to the gym.&lt;/p&gt;

&lt;p&gt;Somewhere between sets, he casually mentions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"One of my client's apps went down. I've been awake for the last 2-3 hours trying to fix it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We start discussing it casually.&lt;/p&gt;

&lt;p&gt;He tells me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git status&lt;/code&gt; showed a huge number of untracked files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;index.php&lt;/code&gt; had been replaced&lt;/li&gt;
&lt;li&gt;he quickly stashed changes&lt;/li&gt;
&lt;li&gt;restarted &lt;code&gt;apache2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the app came back online&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point, it was obvious:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Someone had access to the server.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  The Investigation Begins
&lt;/h2&gt;

&lt;p&gt;Fast forward to the evening.&lt;/p&gt;

&lt;p&gt;We hop on a call and start investigating properly.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 1 — Check for Suspicious Processes
&lt;/h2&gt;

&lt;p&gt;First thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux &lt;span class="nt"&gt;--sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-%mem | &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





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

&lt;/div&gt;





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

&lt;/div&gt;



&lt;p&gt;We also checked for suspicious network connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netstat &lt;span class="nt"&gt;-antp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing unusual.&lt;/p&gt;

&lt;p&gt;No obvious crypto miners.&lt;br&gt;
No rogue reverse shells.&lt;br&gt;
No suspicious high CPU usage.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 2 — Check Active Users &amp;amp; Login History
&lt;/h2&gt;

&lt;p&gt;Now we move toward authentication logs.&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="nb"&gt;who&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;last &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





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

&lt;/div&gt;



&lt;p&gt;Then:&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="nb"&gt;cat&lt;/span&gt; /var/log/auth.log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Accepted"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there it was.&lt;/p&gt;

&lt;p&gt;A suspicious login around the exact same time the server went down.&lt;/p&gt;

&lt;p&gt;Even more interesting:&lt;/p&gt;

&lt;p&gt;The attacker was exploring the server manually.&lt;/p&gt;

&lt;p&gt;We saw commands like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wasn't automated malware blindly running.&lt;/p&gt;

&lt;p&gt;Someone had interactive shell access.&lt;/p&gt;




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

&lt;p&gt;The traffic was coming from an Amazon IP address.&lt;/p&gt;

&lt;p&gt;And not just any region.&lt;/p&gt;

&lt;p&gt;It originated from the same country as the client.&lt;/p&gt;

&lt;p&gt;That initially made things confusing because AWS IPs often look "legitimate" during quick inspection.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Inspect the Web Directory
&lt;/h2&gt;

&lt;p&gt;Now we check the actual application files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Absolute chaos.&lt;/p&gt;

&lt;p&gt;Dozens of unexpected PHP files.&lt;/p&gt;

&lt;p&gt;Mostly inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/www/public_html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some had random names like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x.php
shell.php
cache.php
1index.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Classic indicators of uploaded web shells.&lt;/p&gt;

&lt;p&gt;At that moment, one thing immediately came to mind:&lt;/p&gt;

&lt;h2&gt;
  
  
  LFI / Arbitrary File Upload
&lt;/h2&gt;

&lt;p&gt;If attackers can upload executable PHP files into a web-accessible directory, game over.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Trace the Upload Vector
&lt;/h2&gt;

&lt;p&gt;I ask him:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can users upload files anywhere on the platform?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Only paid users can upload."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then adds:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"But there is a free trial."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bingo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Find the Attacker Account
&lt;/h2&gt;

&lt;p&gt;We inspect recent signups.&lt;/p&gt;

&lt;p&gt;Sure enough:&lt;/p&gt;

&lt;p&gt;A suspicious user registered around 3-4 days earlier using the free trial flow.&lt;/p&gt;

&lt;p&gt;Now we know where to look.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Check User Uploads
&lt;/h2&gt;

&lt;p&gt;We inspect the upload directories.&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="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/www/assets/uploads/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /var/www/assets/uploads &lt;span class="nt"&gt;-type&lt;/span&gt; f | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;".php"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there it was.&lt;/p&gt;

&lt;p&gt;A PHP script uploaded directly into the user's upload directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/assets/uploads/1234/xannyanaxium.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The attacker was simply visiting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/assets/uploads/1234/xannyanaxium.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it presented with a kind of a control panel, to upload further files, execute commands and whatnot.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Happened
&lt;/h2&gt;

&lt;p&gt;The application allowed users to upload files.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;file extensions were not validated properly&lt;/li&gt;
&lt;li&gt;uploaded files were stored in a publicly accessible directory&lt;/li&gt;
&lt;li&gt;PHP execution was allowed inside uploads&lt;/li&gt;
&lt;li&gt;attackers could execute arbitrary code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This resulted in:&lt;/p&gt;

&lt;h2&gt;
  
  
  Remote Code Execution (RCE)
&lt;/h2&gt;

&lt;p&gt;Once the attacker uploaded a PHP web shell, they effectively had server access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example of a Dangerous Upload
&lt;/h2&gt;

&lt;p&gt;A minimal malicious PHP shell can be as small as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'cmd'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which allows attackers to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shell.php?cmd=id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or worse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shell.php?cmd=rm+-rf+/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Immediate Remediation Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Disable PHP Execution in Upload Directories
&lt;/h3&gt;

&lt;p&gt;Inside uploads directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /var/www/assets/uploads/.htaccess
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;php_flag engine &lt;span class="ss"&gt;off&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or for Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/uploads/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;\.php$&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;deny&lt;/span&gt; &lt;span class="s"&gt;all&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;h3&gt;
  
  
  2. Restrict Upload Extensions
&lt;/h3&gt;

&lt;p&gt;Allow only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jpg
jpeg
png
pdf
webp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never trust client-side validation.&lt;/p&gt;

&lt;p&gt;Validate server-side.&lt;/p&gt;

&lt;p&gt;Example in PHP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$allowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'jpg'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'jpeg'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'png'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'pdf'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nv"&gt;$ext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtolower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;pathinfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_FILES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'file'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;PATHINFO_EXTENSION&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="nb"&gt;in_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$allowed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Invalid file type"&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;h3&gt;
  
  
  3. Rename Uploaded Files
&lt;/h3&gt;

&lt;p&gt;Never preserve original filenames.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$newName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;bin2hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;random_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;".jpg"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Store Uploads Outside Web Root
&lt;/h3&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/www/public_html/uploads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/app_uploads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Serve files through application logic instead.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Hunt for Persistence
&lt;/h3&gt;

&lt;p&gt;Attackers often leave backdoors.&lt;/p&gt;

&lt;p&gt;Search aggressively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /var/www &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.php"&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;"(shell|cmd|cache|tmp)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search recently modified files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /var/www &lt;span class="nt"&gt;-mtime&lt;/span&gt; &lt;span class="nt"&gt;-7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Search suspicious functions:&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="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="s2"&gt;"system("&lt;/span&gt; /var/www
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="s2"&gt;"exec("&lt;/span&gt; /var/www
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; &lt;span class="s2"&gt;"base64_decode"&lt;/span&gt; /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  6. Rotate Everything
&lt;/h3&gt;

&lt;p&gt;Assume compromise.&lt;/p&gt;

&lt;p&gt;Rotate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH keys&lt;/li&gt;
&lt;li&gt;database passwords&lt;/li&gt;
&lt;li&gt;API keys&lt;/li&gt;
&lt;li&gt;JWT secrets&lt;/li&gt;
&lt;li&gt;cloud credentials&lt;/li&gt;
&lt;li&gt;payment provider keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything.&lt;/p&gt;




&lt;p&gt;It all came down to one thing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Never allow executable uploads into a public directory.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>cybersecurity</category>
      <category>infosec</category>
      <category>linux</category>
      <category>security</category>
    </item>
    <item>
      <title>Your Database Is Slow Because Everything Is Hot</title>
      <dc:creator>ALI MANSOOR</dc:creator>
      <pubDate>Sat, 16 May 2026 09:44:30 +0000</pubDate>
      <link>https://forem.com/theali711/your-database-is-slow-because-everything-is-hot-3b21</link>
      <guid>https://forem.com/theali711/your-database-is-slow-because-everything-is-hot-3b21</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;At some point, every growing system starts collecting ghosts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you have a job as a software engineer.&lt;/p&gt;

&lt;p&gt;You build systems. APIs. Workers. Queues. Dashboards. Databases.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Life is good.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Well... not that good.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Somewhere in your infrastructure, there’s a database table quietly growing in size every second.&lt;/p&gt;

&lt;p&gt;Maybe it's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orders&lt;/li&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;chat messages&lt;/li&gt;
&lt;li&gt;notifications&lt;/li&gt;
&lt;li&gt;webhook events&lt;/li&gt;
&lt;li&gt;analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;In the beginning, everything is beautiful.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your queries are fast.&lt;br&gt;
Your CPU is relaxed.&lt;br&gt;
Your dashboards load instantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fiob2waod4tsbmp1dwx4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fiob2waod4tsbmp1dwx4w.png" alt=" " width="503" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then the data grows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzl7g77ldahth7ansccmn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzl7g77ldahth7ansccmn.png" alt=" " width="464" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good problem to have.&lt;/p&gt;

&lt;p&gt;So naturally, you do what every engineer does.&lt;/p&gt;

&lt;p&gt;You add indexes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_orders_created_at&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And suddenly:&lt;/p&gt;

&lt;p&gt;Performance returns.&lt;br&gt;
Life is good again.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then Reality Arrives&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few months later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New query patterns appear&lt;/li&gt;
&lt;li&gt;More indexes get added&lt;/li&gt;
&lt;li&gt;Old indexes become useless&lt;/li&gt;
&lt;li&gt;Write performance starts dropping&lt;/li&gt;
&lt;li&gt;Backups start dragging&lt;/li&gt;
&lt;li&gt;CPU usage spikes&lt;/li&gt;
&lt;li&gt;RAM usage starts looking offensive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the database begins cursing at you in 0's and 1's.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Internet Tells You To Shard Everything&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So you go searching for answers.&lt;/p&gt;

&lt;p&gt;Maybe you ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChatGPT&lt;/li&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;Meta AI (I'm not judging)&lt;/li&gt;
&lt;li&gt;that one senior engineer who says "just use Cassandra" (he's right tho)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And suddenly the suggestions begin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;partition the data&lt;/li&gt;
&lt;li&gt;shard the database&lt;/li&gt;
&lt;li&gt;horizontal scaling&lt;/li&gt;
&lt;li&gt;replicas&lt;/li&gt;
&lt;li&gt;sacrifice a goat to Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ughhh.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmgv3jsjkcs6bkisvc5mv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmgv3jsjkcs6bkisvc5mv.png" alt=" " width="462" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;maybe the issue is temperature...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most Data Is Cold&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the important realization.&lt;/p&gt;

&lt;p&gt;A lot of production systems only actively use recent data.&lt;/p&gt;

&lt;p&gt;Do you really need a 3-year-old webhook event sitting inside your primary production table?&lt;/p&gt;

&lt;p&gt;Probably not.&lt;/p&gt;

&lt;p&gt;But...&lt;/p&gt;

&lt;p&gt;You still need to keep it.&lt;/p&gt;

&lt;p&gt;For:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compliance&lt;/li&gt;
&lt;li&gt;finance&lt;/li&gt;
&lt;li&gt;legal&lt;/li&gt;
&lt;li&gt;audits&lt;/li&gt;
&lt;li&gt;analytics&lt;/li&gt;
&lt;li&gt;"just in case"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It needs to go away (not actually go away, but still go away)&lt;/p&gt;

&lt;p&gt;so what do you do?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freeze The Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzu2rhmvjnmn6gy92ri49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzu2rhmvjnmn6gy92ri49.png" alt=" " width="557" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The solution is surprisingly simple.&lt;/p&gt;

&lt;p&gt;You stop treating old data like active data.&lt;/p&gt;

&lt;p&gt;You freeze it.&lt;/p&gt;

&lt;p&gt;Meaning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep recent data queryable&lt;/li&gt;
&lt;li&gt;move old data elsewhere&lt;/li&gt;
&lt;li&gt;reduce table size&lt;/li&gt;
&lt;li&gt;reduce index size&lt;/li&gt;
&lt;li&gt;reduce backup size&lt;/li&gt;
&lt;li&gt;reduce IO pressure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your database becomes smaller again.&lt;/p&gt;

&lt;p&gt;Smaller databases are faster databases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Do You Mean Freeze It? Where Does Cold Data Go?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1 — Archive Tables&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;orders
orders_archive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple and effective.&lt;/p&gt;

&lt;p&gt;Good when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;same database&lt;/li&gt;
&lt;li&gt;rare access needed&lt;/li&gt;
&lt;li&gt;low operational overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option 2 — Data Warehouse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Perfect for:&lt;/p&gt;

&lt;p&gt;BI teams&lt;br&gt;
analytics&lt;br&gt;
finance reporting&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BigQuery&lt;/li&gt;
&lt;li&gt;Snowflake&lt;/li&gt;
&lt;li&gt;ClickHouse&lt;/li&gt;
&lt;li&gt;Redshift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option 3 — Object Storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Honestly?&lt;/p&gt;

&lt;p&gt;Sometimes CSV files in S3 are enough.&lt;/p&gt;

&lt;p&gt;Especially for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;audit trails&lt;/li&gt;
&lt;li&gt;compliance archives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can export:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;CSV&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cheap. Durable. Simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Migration Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So how do you do this?&lt;br&gt;
If you dont know, I am worried about you....&lt;/p&gt;

&lt;p&gt;You write a cron, it moves data which has surpassed the ttl to cold storage.&lt;/p&gt;

&lt;p&gt;Do not move everything at once.&lt;/p&gt;

&lt;p&gt;That is how you create incidents.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;small batches&lt;/li&gt;
&lt;li&gt;gradual movement&lt;/li&gt;
&lt;li&gt;continuous cleanup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the beginning:&lt;/p&gt;

&lt;p&gt;Run the cron every hour.&lt;/p&gt;

&lt;p&gt;Move:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;5k records&lt;/li&gt;
&lt;li&gt;maybe 10k&lt;/li&gt;
&lt;li&gt;maybe less&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lock times&lt;/li&gt;
&lt;li&gt;replication lag&lt;/li&gt;
&lt;li&gt;CPU spikes&lt;/li&gt;
&lt;li&gt;IO usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then gradually increase retention movement.&lt;/p&gt;

&lt;p&gt;Eventually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;daily jobs&lt;/li&gt;
&lt;li&gt;weekly jobs&lt;/li&gt;
&lt;li&gt;biweekly jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your system stabilizes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fqmvx2xqp5esm5u8wnd6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fqmvx2xqp5esm5u8wnd6x.png" alt=" " width="402" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referential Integrity Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data is usually connected.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;orders&lt;br&gt;
 ├── payments&lt;br&gt;
 ├── invoices&lt;br&gt;
 ├── shipment_logs&lt;br&gt;
 └── audit_events&lt;/p&gt;

&lt;p&gt;Moving only the parent record can create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orphaned rows&lt;/li&gt;
&lt;li&gt;broken analytics&lt;/li&gt;
&lt;li&gt;failed joins&lt;/li&gt;
&lt;li&gt;compliance problems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Archive related entities together.&lt;/p&gt;

&lt;p&gt;I'll be back again (don't know when, to share some more insights...maybe another problem to solve)&lt;/p&gt;

</description>
      <category>database</category>
      <category>performance</category>
    </item>
    <item>
      <title>Implementing K-Means Clustering from scratch in Python</title>
      <dc:creator>ALI MANSOOR</dc:creator>
      <pubDate>Mon, 02 May 2022 10:21:23 +0000</pubDate>
      <link>https://forem.com/theali711/implementing-k-means-clustering-from-scratch-in-python-5fo6</link>
      <guid>https://forem.com/theali711/implementing-k-means-clustering-from-scratch-in-python-5fo6</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Disclaimer! I am a student learning Datascience, Machine Learning. What I write here might have mistakes, do point them out in comments or reach out directly to me at my &lt;a href="https://www.linkedin.com/in/ali-mansoor-0140a81bb/"&gt;linkedin&lt;/a&gt; account.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is K-Means Clustering?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;k-means clustering is a method of vector quantization, originally from signal processing, that aims to partition n observations into k clusters in which each observation belongs to the cluster with the nearest mean (cluster centers or cluster centroid), serving as a prototype of the cluster. This results in a partitioning of the data space into Voronoi cells. - Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you did not understand this wikipedia definition like me, let me explain it in simpler terms.&lt;br&gt;
In K-means clustering we divide n number of observations into k groups/clusters in such a way that the observations similar to each other are linked in one group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YIRupOD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mk1853guk7qe0d61tmo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YIRupOD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mk1853guk7qe0d61tmo.gif" alt="K-Means Convergence" width="220" height="214"&gt;&lt;/a&gt;&lt;br&gt;
Image Credits: &lt;a href="https://en.wikipedia.org/wiki/K-means_clustering"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps for K-Means Clustering
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Decide the value of k, which is the number of groups to divide your observations into.&lt;/li&gt;
&lt;li&gt;Select k random points C (aka centroids) for each cluster within your observations.&lt;/li&gt;
&lt;li&gt;Calculate absolute difference of each point from all centroids.
&lt;code&gt;|X-C|&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Put the observation in the cluster which has the closest centroid. &lt;/li&gt;
&lt;li&gt;Calculate new centroid for each cluster by taking average of all observations in that cluster.&lt;/li&gt;
&lt;li&gt;Repeat step 3-5 until the centroids stop changing.&lt;/li&gt;
&lt;li&gt;You have successfully organized n observations in k clusters.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have also &lt;a href="https://github.com/TheAli711/datascience/tree/main/k-means-clustering"&gt;written the python code&lt;/a&gt; from scratch to implement k-means clustering for n-clusters, it currently works for 2-4 clusters(limited color values) but sometimes goes into infinite loop. if given n values of colors, it can work for n clusters&lt;/p&gt;

&lt;p&gt;Github: &lt;a href="https://github.com/TheAli711/datascience/tree/main/k-means-clustering"&gt;https://github.com/TheAli711/datascience/tree/main/k-means-clustering&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See you guys in the next article :)&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>datascience</category>
      <category>python</category>
    </item>
    <item>
      <title>Automatically deploy your react site with GitHub and Netlify</title>
      <dc:creator>ALI MANSOOR</dc:creator>
      <pubDate>Sat, 02 Apr 2022 03:48:44 +0000</pubDate>
      <link>https://forem.com/theali711/automatically-deploy-your-react-site-with-github-and-netlify-5d00</link>
      <guid>https://forem.com/theali711/automatically-deploy-your-react-site-with-github-and-netlify-5d00</guid>
      <description>&lt;p&gt;Hi guys, this is my first article on &lt;a href="//dev.to"&gt;Dev.to&lt;/a&gt; platform&lt;br&gt;
Today I am going to show you how you can automate your ReactJS deployments on Netlify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NPM and NodeJS installed.&lt;/li&gt;
&lt;li&gt;Understanding of React.&lt;/li&gt;
&lt;li&gt;Understanding of git and GitHub.&lt;/li&gt;
&lt;li&gt;Free Netlify and GitHub accounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Setup ReactJS app
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app my-portfolio&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  NPX
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;npx is a CLI tool whose purpose is to make it easy to install and manage dependencies hosted in the NPM registry. This is awesome because sometimes you just want to use some CLI tools but you don’t want to install them globally just to test them out. This means you can save some disk space and simply run them only when you need them. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2: Set up GitHub repository
&lt;/h2&gt;

&lt;p&gt;Login to your GitHub account and create a new repository, in the &lt;strong&gt;Initialize this repository with&lt;/strong&gt; section leave everything unchecked&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Link your local code to GitHub repository
&lt;/h2&gt;

&lt;p&gt;Go to the my-portfolio folder created earlier and do the following:&lt;br&gt;
Rename local master branch to main:&lt;br&gt;
&lt;code&gt;git branch -M main&lt;/code&gt;&lt;br&gt;
Add remote repository:&lt;br&gt;
&lt;code&gt;git remote add origin YourGithubRepoUrlHere&lt;/code&gt;&lt;br&gt;
Push local code to GitHub:&lt;br&gt;
&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Link Netlify to GitHub repository
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Login to your Netlify account.&lt;/li&gt;
&lt;li&gt;Go to the Sites tab and click on Add New Site button.&lt;/li&gt;
&lt;li&gt;Select Import existing project.&lt;/li&gt;
&lt;li&gt;Select GitHub in &lt;strong&gt;Connect to Git Providers&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Pick the newly created repository.&lt;/li&gt;
&lt;li&gt;Make sure that the branch to deploy is main&lt;/li&gt;
&lt;li&gt;Click deploy site
Your site will be deployed and now whenever there is any change main branch of GitHub, Netlify will automatically build and deploy your site with latest changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus: Set up dev branch so you can create merge requests and get preview before deploying on the url
&lt;/h2&gt;

&lt;p&gt;We can create a development branch in the repository where we can do all the changes and when we are confident with our code, we can create a merge request from development branch to main branch, before merging, Netlify will provide us with a deploy preview, on a separate URL, we can test it to see if our website functions as required and then can merge our code into main.&lt;/p&gt;

&lt;p&gt;That's all for this article, Goodbye :)&lt;/p&gt;

</description>
      <category>automation</category>
      <category>react</category>
      <category>github</category>
      <category>netlify</category>
    </item>
  </channel>
</rss>
