<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Sahib Singh]]></title><description><![CDATA[Developer and Learner]]></description><link>https://blog.sahibsingh.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 19 May 2026 05:10:05 GMT</lastBuildDate><atom:link href="https://blog.sahibsingh.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Securing Node.js Applications]]></title><description><![CDATA[As developers, ensuring the security of our applications is paramount. In the world of backend development with Node.js, several key practices and tools can significantly enhance the security of your application. Let's dive into a comprehensive guide...]]></description><link>https://blog.sahibsingh.dev/securing-nodejs-applications</link><guid isPermaLink="true">https://blog.sahibsingh.dev/securing-nodejs-applications</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Security]]></category><category><![CDATA[ Best Practices for Developers]]></category><category><![CDATA[backend]]></category><dc:creator><![CDATA[Sahib Singh]]></dc:creator><pubDate>Wed, 20 Dec 2023 13:59:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1703080538254/700989c0-136a-4a18-b0bc-ff2f0e0a3540.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As developers, ensuring the security of our applications is paramount. In the world of backend development with Node.js, several key practices and tools can significantly enhance the security of your application. Let's dive into a comprehensive guide covering the essential backend security best practices.</p>
<h3 id="heading-1-secure-dependencies">1. <strong>Secure Dependencies</strong></h3>
<p>The foundation of any secure application starts with the packages it depends on. Regularly audit and fix vulnerabilities using the following commands for Yarn and NPM:</p>
<p><strong>For Yarn:</strong></p>
<pre><code class="lang-bash">yarn audit
yarn audit fix
</code></pre>
<p><strong>For NPM:</strong></p>
<pre><code class="lang-bash">npm audit
npm audit fix
</code></pre>
<h3 id="heading-2-cors-implementation">2. <strong>CORS Implementation</strong></h3>
<p>Cross-Origin Resource Sharing (CORS) is vital for controlling which origins can access your Node.js application's resources. Implement CORS using the following code snippet:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> whitelist = [<span class="hljs-string">"http://localhost:3000"</span>];
<span class="hljs-keyword">const</span> corsOptions = {
  <span class="hljs-attr">origin</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">origin, callback</span>) </span>{
    <span class="hljs-keyword">if</span> (whitelist.indexOf(origin) !== <span class="hljs-number">-1</span>) {
      callback(<span class="hljs-literal">null</span>, <span class="hljs-literal">true</span>);
    } <span class="hljs-keyword">else</span> {
      callback(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Not allowed by CORS"</span>));
    }
  },
};

app.use(cors(corsOptions));
</code></pre>
<h3 id="heading-3-helmetjs-for-http-headers">3. <strong>Helmet.js for HTTP Headers</strong></h3>
<p><a target="_blank" href="https://helmetjs.github.io/">Helmet.js</a> is an Express middleware that helps set various HTTP headers for enhanced security. Integrate it into your application with the following line:</p>
<pre><code class="lang-jsx">app.use(helmet());
</code></pre>
<h3 id="heading-4-rate-limiting">4. <strong>Rate Limiting</strong></h3>
<p>Protect your application from abuse and excessive requests with rate limiting. Define a limiter middleware, allowing exceptions for specific IPs:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> allowlist = [<span class="hljs-string">"192.168.0.56"</span>, <span class="hljs-string">"192.168.0.21"</span>]
<span class="hljs-keyword">const</span> limiter = rateLimit({
  <span class="hljs-attr">windowMs</span>: <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">// 1 minute</span>
  <span class="hljs-attr">max</span>: <span class="hljs-number">50</span>, <span class="hljs-comment">// 50 requests per IP</span>
  <span class="hljs-attr">message</span>: <span class="hljs-string">"Too many requests from this IP, please try again after 1 minute!"</span>,
  <span class="hljs-attr">skip</span>: <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> allowlist.includes(req.ip),
});

app.use(limiter);
</code></pre>
<h3 id="heading-5-request-size-limit">5. <strong>Request Size Limit</strong></h3>
<p>Implement a request size limit to prevent excessively large payloads that could lead to server issues or DoS attacks:</p>
<pre><code class="lang-jsx">app.use(express.json({ <span class="hljs-attr">limit</span>: <span class="hljs-string">'10kb'</span> }));
</code></pre>
<h3 id="heading-6-http-parameter-pollution-prevention">6. <strong>HTTP Parameter Pollution Prevention</strong></h3>
<p>It is an attack in which attackers send multiple HTTP parameters with the same name and this causes your application to interpret them unpredictably. When multiple parameter values are sent, Express populates them in an array.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Not Preferred</span>
<span class="hljs-keyword">import</span> hpp <span class="hljs-keyword">from</span> <span class="hljs-string">'hpp'</span>

app.use(hpp())
</code></pre>
<p>This import statement is very costly, as it imports a large package.</p>
<p>Solving this problem by creating a custom middleware:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Preferred</span>
<span class="hljs-keyword">const</span> hppMiddleware = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (req.query &amp;&amp; <span class="hljs-keyword">typeof</span> req.query === <span class="hljs-string">"object"</span>) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> key <span class="hljs-keyword">in</span> req.query) {
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.isArray(req.query[key])) {
        req.query[key] = req.query[key][req.query[key].length - <span class="hljs-number">1</span>];
      }
    }
  }
  next();
};

app.use(hppMiddleware);
</code></pre>
<h3 id="heading-7-logging-for-visibility">7. <strong>Logging for Visibility</strong></h3>
<p>Logging is crucial for understanding your application's behavior and diagnosing issues. Use Morgan for logging HTTP requests in the console, and Winston for more versatile logging, including file storage:</p>
<ol>
<li><p><strong>Morgan</strong>: It can be used for logging HTTP requests in the console.</p>
<p> <code>app.use(morgan('dev'))</code></p>
</li>
<li><p><strong>Winston</strong>: It can be used for logging all types of requests in a separate file or in the console or in both.</p>
<pre><code class="lang-jsx"> <span class="hljs-keyword">import</span> { createLogger, transports, format } <span class="hljs-keyword">from</span> <span class="hljs-string">"winston"</span>;

 <span class="hljs-keyword">const</span> logger = createLogger({
   <span class="hljs-attr">level</span>: <span class="hljs-string">"verbose"</span>,
   <span class="hljs-attr">format</span>: format.combine(format.timestamp(), format.json()),
   <span class="hljs-attr">transports</span>: [
     <span class="hljs-comment">// new transports.Console({</span>
     <span class="hljs-comment">//     format: format.combine(</span>
     <span class="hljs-comment">//         format.colorize(),</span>
     <span class="hljs-comment">//         format.simple()</span>
     <span class="hljs-comment">//     ),</span>
     <span class="hljs-comment">// }),</span>
     <span class="hljs-keyword">new</span> transports.File({ <span class="hljs-attr">filename</span>: <span class="hljs-string">"logs/error.log"</span>, <span class="hljs-attr">level</span>: <span class="hljs-string">"error"</span> }),
     <span class="hljs-keyword">new</span> transports.File({ <span class="hljs-attr">filename</span>: <span class="hljs-string">"logs/combined.log"</span> }),
   ],
 });
</code></pre>
<p> For using <strong>logger</strong> in each request</p>
<p> <a target="_blank" href="https://helmetjs.github.io/"><code>logger.info</code></a><code>("Request received: ${req.method} ${req.url}")</code></p>
<p> For using logger as middleware</p>
<pre><code class="lang-jsx"> <span class="hljs-keyword">const</span> loggerMiddleware = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
   logger.info(
     <span class="hljs-string">`<span class="hljs-subst">${req.method}</span> <span class="hljs-subst">${req.protocol}</span>: <span class="hljs-subst">${req.get(<span class="hljs-string">"host"</span>)}</span><span class="hljs-subst">${req.originalUrl}</span>`</span>
   );
   next();
 };

 app.use(loggerMiddleware);
</code></pre>
</li>
</ol>
<h3 id="heading-8-additional-considerations">8. <strong>Additional Considerations</strong></h3>
<p><em>We ignore them sometimes</em></p>
<ul>
<li><p><strong>Perform Input Validation</strong></p>
</li>
<li><p><strong>Only Return What Is Necessary</strong></p>
</li>
<li><p><strong>Remove Unnecessary Routes</strong></p>
</li>
<li><p><strong>Implement Captcha</strong></p>
</li>
</ul>
<h3 id="heading-some-useful-resources">Some Useful Resources</h3>
<p><a target="_blank" href="https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html#use-access-control-lists">Nodejs Security - OWASP Cheat Sheet Series</a></p>
<p><a target="_blank" href="https://nodejs.org/en/docs/guides/security">Node.js Security Best Practices | Node.js</a></p>
<p><a target="_blank" href="https://snyk.io/learn/nodejs-security-best-practice/">Top 10 Node.js Security Best Practices - Risks &amp; Prevention | Snyk</a></p>
<p><a target="_blank" href="https://www.stackhawk.com/blog/guide-to-security-in-node-js/">Guide to Security in Node.js</a></p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>By incorporating these backend security best practices, you fortify your Node.js application against common vulnerabilities. Regularly update dependencies, control resource access, set HTTP headers, and employ logging to maintain a robust and secure backend. Happy Coding🎊!!</p>
]]></content:encoded></item></channel></rss>