<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gowri Shankar Balasubramaniam</title>
    <description>The latest articles on DEV Community by Gowri Shankar Balasubramaniam (@gowrishankar).</description>
    <link>https://dev.to/gowrishankar</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%2F1188599%2F726ec942-f480-496c-8371-be23c3de9764.jpeg</url>
      <title>DEV Community: Gowri Shankar Balasubramaniam</title>
      <link>https://dev.to/gowrishankar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gowrishankar"/>
    <language>en</language>
    <item>
      <title>Fixing MariaDB ERROR 2002 (HY000): TLS Handshake Fails with “Host Is Not Allowed to Connect”</title>
      <dc:creator>Gowri Shankar Balasubramaniam</dc:creator>
      <pubDate>Fri, 23 Jan 2026 14:20:47 +0000</pubDate>
      <link>https://dev.to/gowrishankar/fixing-mariadb-error-2002-hy000-tls-handshake-fails-with-host-is-not-allowed-to-connect-4h05</link>
      <guid>https://dev.to/gowrishankar/fixing-mariadb-error-2002-hy000-tls-handshake-fails-with-host-is-not-allowed-to-connect-4h05</guid>
      <description>&lt;p&gt;If you administer MariaDB in a secured environment, you may encounter the following confusing error while connecting from a remote host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR 2002 (HY000): Received error packet before completion of TLS handshake.
The authenticity of the following error cannot be verified:
1130 - Host '192.168.0.100' is not allowed to connect to this MariaDB server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this looks like a TLS/SSL issue, but the root cause is often host-based access control, not encryption. This article explains why this happens, how TLS complicates the error message, and how to fix it securely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Error Is Misleading
&lt;/h2&gt;

&lt;p&gt;The error appears during the TLS handshake phase, which causes MariaDB to suppress full reveal of server-side details. As a result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MariaDB detects that the client host is not authorized&lt;/li&gt;
&lt;li&gt;But TLS prevents full error verification&lt;/li&gt;
&lt;li&gt;You receive a generic ERROR 2002 instead of a clean access-denied message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TLS is not broken authorization is.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Common Scenarios Where This Happens
&lt;/h2&gt;

&lt;p&gt;This issue is frequently seen in environments with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enforced require_secure_transport=ON&lt;/li&gt;
&lt;li&gt;TLS-enabled clients (--ssl / --ssl-mode=REQUIRED)&lt;/li&gt;
&lt;li&gt;Remote application servers or containers&lt;/li&gt;
&lt;li&gt;Hardened MariaDB installations (PCI DSS / SOC 2 aligned)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Typical causes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client host IP is missing in mysql.user&lt;/li&gt;
&lt;li&gt;The user exists only for localhost&lt;/li&gt;
&lt;li&gt;Firewall or bind-address is not the issue (often misdiagnosed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Confirm the Server Is Reachable
&lt;/h2&gt;

&lt;p&gt;From the client host (192.168.0.100):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nc -vz mariadb-server-ip 3306
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this succeeds, networking is not the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Inspect User Host Permissions (Critical Step)
&lt;/h2&gt;

&lt;p&gt;Log in locally to the MariaDB server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check allowed hosts for the user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT User, Host FROM mysql.user WHERE User = 'appuser';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical problematic output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---------+-----------+
| User    | Host      |
+---------+-----------+
| appuser | localhost |
+---------+-----------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means &lt;strong&gt;remote connections are explicitly denied&lt;/strong&gt;, regardless of TLS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Grant Access to the Correct Host
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Option A: Allow a specific IP (recommended)&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;CREATE USER 'appuser'@'192.168.0.100'
IDENTIFIED BY 'StrongPassword'
REQUIRE SSL;

GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'192.168.0.100';
FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option B: Allow a subnet (controlled environments)&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;CREATE USER 'appuser'@'192.168.0.%'
IDENTIFIED BY 'StrongPassword'
REQUIRE SSL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ Avoid '%' unless strictly required.&lt;/p&gt;

&lt;p&gt;⚠️ You may also use the local domain name instead of the IP address when creating the database user.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 4: Verify TLS Configuration
&lt;/h2&gt;

&lt;p&gt;Check server TLS settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHOW VARIABLES LIKE 'require_secure_transport';
SHOW VARIABLES LIKE 'ssl_%';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected secure configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require_secure_transport = ON
ssl_ca   = /etc/mysql/ca.pem
ssl_cert = /etc/mysql/server-cert.pem
ssl_key  = /etc/mysql/server-key.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Test Connection Explicitly with TLS
&lt;/h2&gt;

&lt;p&gt;From the client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mariadb \
  -h mariadb-server-ip \
  -u appuser \
  -p \
  --ssl-mode=REQUIRED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the host permission is fixed, the TLS handshake will complete successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MariaDB Throws ERROR 2002 Instead of ERROR 1130
&lt;/h2&gt;

&lt;p&gt;Under non-TLS connections, you would normally see:&lt;br&gt;
&lt;/p&gt;

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

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ERROR 1130 (HY000): Host 'x.x.x.x' is not allowed to connect&lt;/p&gt;

&lt;p&gt;But when TLS is enforced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The server aborts early&lt;/li&gt;
&lt;li&gt;Detailed authentication errors are hidden&lt;/li&gt;
&lt;li&gt;MariaDB returns ERROR 2002 as a generic failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is expected behavior in hardened setups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Best Practices (Strongly Recommended)
&lt;/h2&gt;

&lt;p&gt;✔ Use host-specific users, not %&lt;br&gt;
✔ Enforce REQUIRE SSL&lt;br&gt;
✔ Keep require_secure_transport=ON&lt;br&gt;
✔ Rotate credentials after permission changes&lt;br&gt;
✔ Log connection errors via log_error_verbosity=3&lt;/p&gt;

&lt;p&gt;These align well with PCI DSS, SOC 2, and zero-trust principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This error is not a TLS failure, it is an access control failure masked by TLS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the correct host-based user permission is added, the error disappears immediately.&lt;/p&gt;

</description>
      <category>database</category>
      <category>networking</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>CRITICAL RCE ALERT: Patch CVE-2025-61932 in LANSCOPE Endpoint Manager NOW! (Actively Exploited)</title>
      <dc:creator>Gowri Shankar Balasubramaniam</dc:creator>
      <pubDate>Fri, 24 Oct 2025 08:09:49 +0000</pubDate>
      <link>https://dev.to/gowrishankar/critical-rce-alert-patch-cve-2025-61932-in-lanscope-endpoint-manager-now-actively-exploited-21ic</link>
      <guid>https://dev.to/gowrishankar/critical-rce-alert-patch-cve-2025-61932-in-lanscope-endpoint-manager-now-actively-exploited-21ic</guid>
      <description>&lt;p&gt;I have found an urgent advisory regarding &lt;strong&gt;&lt;a href="https://blog.gowrishankar.me/2025/10/23/cve-2025-61932-critical-remote-code-execution-vulnerability-in-lanscope-endpoint-manager/" rel="noopener noreferrer"&gt;CVE-2025-61932&lt;/a&gt;&lt;/strong&gt;, a critical Remote Code Execution (RCE) vulnerability discovered in &lt;strong&gt;LANSCOPE Endpoint Manager (On-Premises)&lt;/strong&gt;, developed by Motex Inc. (Japan). This advisory was published on October 20, 2025.&lt;/p&gt;

&lt;p&gt;This is a live threat: the vulnerability has been &lt;strong&gt;added to CISA’s Known Exploited Vulnerabilities (KEV) Catalog&lt;/strong&gt;, confirming that it is being &lt;strong&gt;actively exploited in the wild&lt;/strong&gt;. Organizations globally must prioritize patching this issue immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚨 Technical Summary: Severe Risk and Impact
&lt;/h2&gt;

&lt;p&gt;This vulnerability poses a grave risk, allowing remote attackers to achieve complete system compromise.&lt;/p&gt;

&lt;p&gt;The core issue stems from &lt;strong&gt;Improper Verification of Source of a Communication Channel (CWE-940)&lt;/strong&gt;. An attacker can execute arbitrary code by sending specially crafted packets to a vulnerable endpoint.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;th&gt;Source Information&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CVE Identifier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://blog.gowrishankar.me/2025/10/23/cve-2025-61932-critical-remote-code-execution-vulnerability-in-lanscope-endpoint-manager/" rel="noopener noreferrer"&gt;CVE-2025-61932&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Affected Product&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LANSCOPE Endpoint Manager (On-Premises)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Affected Components&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Client (MR) and Detection Agent (DA) components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exploit Vector&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remote, over &lt;strong&gt;TCP port 443 (HTTPS)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Criticality Score&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CVSS v4.0 Score: &lt;strong&gt;9.3 (Critical)&lt;/strong&gt;; CVSS v3.x Score: &lt;strong&gt;9.8 (Critical)&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Impact&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Complete system compromise. Confidentiality, integrity, and availability are all at high risk. Attackers gain &lt;strong&gt;full control of endpoints&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Confirmed Exploitation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;First observed exploited in the wild around &lt;strong&gt;April 2025&lt;/strong&gt;. Exploitation may be used to drop an unspecified backdoor on compromised systems.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Global Relevance and Official Directives
&lt;/h3&gt;

&lt;p&gt;While LANSCOPE is widely used in Japan and Asia for corporate IT governance, global exposure is confirmed, particularly among organizations in &lt;strong&gt;Europe (Germany, the Netherlands, and the U.K.)&lt;/strong&gt; and &lt;strong&gt;North America&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Official agencies are treating this as an emergency:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;CISA Mandate:&lt;/strong&gt; The U.S. Cybersecurity and Infrastructure Security Agency (CISA) requires all U.S. federal agencies to &lt;strong&gt;remediate CVE-2025-61932 by November 12, 2025&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Regional Confirmation:&lt;/strong&gt; The &lt;strong&gt;Japan CERT (JPCERT/CC)&lt;/strong&gt; reported confirmed cases of receiving unauthorized packet traffic in domestic customer environments consistent with the exploit.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Compliance Risks (Especially for European Organizations)
&lt;/h3&gt;

&lt;p&gt;For organizations in &lt;strong&gt;Europe, including Germany and the EU&lt;/strong&gt;, this RCE capability presents a &lt;strong&gt;severe cybersecurity and compliance risk&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GDPR Violations:&lt;/strong&gt; Unauthorized data access resulting from compromise could trigger &lt;strong&gt;GDPR violations&lt;/strong&gt;, exposing companies to heavy penalties.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Operational Risk:&lt;/strong&gt; System compromise can disrupt business operations and facilitate &lt;strong&gt;lateral movement&lt;/strong&gt; to compromise domain controllers or confidential data stores.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ Immediate Action: Mitigation and Patching Steps
&lt;/h2&gt;

&lt;p&gt;System administrators must prioritize rapid patching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Identify and Upgrade Affected Systems
&lt;/h3&gt;

&lt;p&gt;The vulnerability affects &lt;strong&gt;all versions up to 9.4.7.1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Immediately verify if &lt;strong&gt;LANSCOPE Endpoint Manager (On-Premises)&lt;/strong&gt; is deployed and check the exact version numbers.&lt;/p&gt;

&lt;p&gt;Upgrade all affected &lt;strong&gt;Client (MR)&lt;/strong&gt; and &lt;strong&gt;Detection Agent (DA)&lt;/strong&gt; components to one of the following patched versions or newer:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fixed Version List&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9.3.2.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.3.3.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.4.0.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.4.1.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.4.2.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.4.3.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.4.4.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.4.5.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9.4.6.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;9.4.7.3&lt;/strong&gt; (or later)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(Note: While the Management Server component is reported as unaffected, it is recommended to patch it as a precaution)&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Restrict Network Access (If Immediate Patching is Delayed)
&lt;/h3&gt;

&lt;p&gt;If LANSCOPE endpoints are accessible from external networks, take immediate temporary mitigation steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Limit access&lt;/strong&gt; to trusted IPs or VPN users only.&lt;/li&gt;
&lt;li&gt;  Temporarily &lt;strong&gt;disable external connectivity on TCP 443&lt;/strong&gt; until the update is confirmed and applied.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Monitoring, Validation, and Internal Communication
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Monitor:&lt;/strong&gt; Review server and endpoint logs for unusual activity. Look specifically for suspicious inbound connections or crafted HTTPS packets on port 443. Check for Indicators of Compromise (IoCs) shared by Motex or security vendors.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Validate:&lt;/strong&gt; After applying updates, test system stability and verify that no endpoints remain exposed to public access.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Strengthen Security:&lt;/strong&gt; Enforce strong authentication, least privilege configurations, endpoint firewalls, and continuous monitoring.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Communicate:&lt;/strong&gt; Notify your IT Security and Compliance teams immediately and set a clear patch deadline, preferably before November 12, 2025.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  About LANSCOPE Endpoint Manager
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LANSCOPE Endpoint Manager&lt;/strong&gt; is an enterprise endpoint management and security solution used to monitor, manage, and protect corporate devices. Developed by Motex Inc. (Japan), its key features include Asset Management, User Activity Monitoring, Patch &amp;amp; Policy Management, and Access Control &amp;amp; Device Auditing. It is vital for &lt;strong&gt;corporate IT governance&lt;/strong&gt;, &lt;strong&gt;endpoint visibility&lt;/strong&gt;, and &lt;strong&gt;data loss prevention&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CVE-2025-61932&lt;/strong&gt; is a &lt;em&gt;critical&lt;/em&gt;, &lt;em&gt;actively exploited&lt;/em&gt; vulnerability. Proactive measures, strict access control, real-time monitoring, and rapid patching are essential to prevent remote compromise and reduce exposure worldwide.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>motex</category>
      <category>vulnerabilities</category>
      <category>rce</category>
    </item>
    <item>
      <title>5 Common Security Mistakes Developers Still Make (and How to Fix Them)</title>
      <dc:creator>Gowri Shankar Balasubramaniam</dc:creator>
      <pubDate>Thu, 09 Oct 2025 15:34:58 +0000</pubDate>
      <link>https://dev.to/gowrishankar/5-common-security-mistakes-developers-still-make-and-how-to-fix-them-20m5</link>
      <guid>https://dev.to/gowrishankar/5-common-security-mistakes-developers-still-make-and-how-to-fix-them-20m5</guid>
      <description>&lt;p&gt;Hey there, fellow developers! 👋&lt;/p&gt;

&lt;p&gt;We all know security isn't just a "DevOps thing" or a "security team thing"—it's a core part of building good software. Yet, under tight deadlines or in the heat of a complex feature, it's easy to slip up. Based on what I've seen in projects big and small, there are a handful of security mistakes that just keep popping up.&lt;/p&gt;

&lt;p&gt;Let's dive into five of the most common security blunders and, more importantly, lay out the practical, code-level fixes we can implement today using Node.js examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Trusting User Input (The Classic Blunder)
&lt;/h2&gt;

&lt;p&gt;This one is ancient, but it never dies. Whether it's data from a web form, a URL parameter, or a JSON payload, all user input is hostile until proven otherwise. Failing to treat it as such is the fast track to vulnerabilities like SQL Injection or Cross-Site Scripting (XSS).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ The Fix: Parameterization and Sanitization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt;&lt;br&gt;
&lt;u&gt;Mistake 1:&lt;/u&gt; SQL Injection - Directly concatenating user input into a database query string.&lt;/p&gt;

&lt;p&gt;Solution: Use Parameterized Queries/Prepared Statements. When working with a database like PostgreSQL or MySQL in Node.js, libraries like pg or mysql2 support parameterized queries that separate the SQL logic from the data. An attacker's input is treated only as a value, not executable code.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Mistake 2:&lt;/u&gt; XSS: Displaying user-submitted text directly on a web page (e.g., a forum post).&lt;/p&gt;

&lt;p&gt;Solution: Escape Output. Before rendering user data in the browser, always escape special characters (like &amp;lt;, &amp;gt;, &amp;amp;). Use template engines that auto-escape (like Handlebars or Pug) or dedicated libraries like dompurify if you must allow some HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Code:&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;// MISTAKE: SQL Injection Risk
// const user = 'admin\' OR \'1\'=\'1'; 
// connection.query(`SELECT * FROM users WHERE username = '${user}'`, (err, results) =&amp;gt; { ... }); 

// FIX: Parameterized Query (The data is never mixed with the query structure)
const user = 'admin\' OR \'1\'=\'1'; 
const sql = 'SELECT * FROM users WHERE username = ?'; // Use a placeholder
connection.execute(sql, [user], (err, results) =&amp;gt; { 
    // The malicious input is treated as a safe string value.
    if (err) throw err;
    console.log(results); 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the single most important rule of secure coding: Input Validation, Output Encoding.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Leaving Default/Insecure Configurations in Place
&lt;/h2&gt;

&lt;p&gt;Every time you spin up a new service, a database, a cloud function, or a web framework (like Express) it comes with default settings. Often, these defaults are designed for ease of use or local development, not for production security. Things like default credentials, permissive firewall rules, or having debugging mode enabled fall into this category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ The Fix: Principle of Least Privilege &amp;amp; Hardening&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Change all Default Credentials:&lt;/strong&gt; Use a secrets manager (like HashiCorp Vault or AWS Secrets Manager) and complex, unique credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disable Unnecessary Features:&lt;/strong&gt; Turn off features you don't need. For Express apps, use the helmet middleware to set secure HTTP headers, which is a massive win for minimal effort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement the Principle of Least Privilege (PoLP):&lt;/strong&gt; Your Node.js process should only have the minimum permissions it needs to function. Don't run your application as the root user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Code Example (Node.js with Express and Helmet):&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;// Protects your app from some well-known web vulnerabilities 
// by setting HTTP headers appropriately.
const express = require('express');
const helmet = require('helmet');
const app = express();

app.use(helmet()); 
app.get('/', (req, res) =&amp;gt; {
    res.send('Hello Secure World!');
});

// A simple but critical step for web hardening!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Ignoring Dependency Vulnerabilities (The Supply Chain Risk)
&lt;/h2&gt;

&lt;p&gt;We all rely on open-source packages, it's how modern development works. But every package you add (via npm install) is a potential entry point for an attacker.&lt;/p&gt;

&lt;p&gt;You might be focused on writing secure application code, but if a third-party package you rely on has a critical vulnerability (a major issue with your node_modules!), your entire app is at risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ The Fix: Automation and Regular Audits&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Software Composition Analysis (SCA) Tools:&lt;/strong&gt; Utilize the built-in npm audit command. It automatically scans your package-lock.json against a public vulnerability database. Tools like Dependabot (for GitHub) or Snyk can also be integrated into your CI/CD pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regular Updates:&lt;/strong&gt; Make updating your dependencies a routine. Running npm audit fix regularly is much easier than scrambling when a major CVE (Common Vulnerabilities and Exposures) is announced.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete Unused Dependencies:&lt;/strong&gt; If you're not using a library anymore, run npm uninstall . Less code, less risk.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Terminal Command Example:&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;# Run this command often!
npm audit 

# To automatically fix safe vulnerabilities
npm audit fix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Storing Secrets Directly in Code (The Git Blunder)
&lt;/h2&gt;

&lt;p&gt;Storing API keys, database connection strings, or encryption keys directly in your source code is a critical mistake. It's often the first place an attacker looks after compromising a developer's machine or gaining access to a private repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ The Fix: Environment Variables and Dedicated Managers&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Environment Variables:&lt;/strong&gt; At a minimum, load secrets from environment variables using a library like dotenv. This keeps secrets out of the codebase by placing them in a .env file that is added to your .gitignore.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adopt a Secrets Manager:&lt;/strong&gt; For production, use a dedicated solution like AWS Secrets Manager, Azure Key Vault, or Kubernetes Secrets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-commit Hooks:&lt;/strong&gt; Use tools like git-secrets to scan your code before it's committed to prevent accidentally pushing sensitive information.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Code Example (Node.js with dotenv):&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;// .env file (NEVER commit this to Git)
// DB_USER="my_secure_user"
// DB_PASS="long_random_password_123"

// server.js (loads secrets from .env or system environment)
require('dotenv').config();

const dbUser = process.env.DB_USER;
const dbPass = process.env.DB_PASS;

if (!dbUser || !dbPass) {
    throw new Error("Database credentials not found in environment variables!");
}

// Now safely use dbUser and dbPass for your connection logic...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Broken Authentication/Authorization (The "Who Can Do What" Problem)
&lt;/h2&gt;

&lt;p&gt;These two are often confused:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication:&lt;/strong&gt; Who are you? (Logging in)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorization:&lt;/strong&gt; What are you allowed to do? (Accessing resources)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A common mistake is forgetting to check authorization on every server-side API endpoint. For example, an attacker might log in as a standard user, then call a backend API endpoint that's only supposed to be accessible by an &lt;strong&gt;administrator&lt;/strong&gt;. If the API doesn't have a check to see if the authenticated user has the "admin" role, you have a &lt;strong&gt;Broken Access Control&lt;/strong&gt; vulnerability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ The Fix: Deny-by-Default and Express Middleware&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deny-by-Default:&lt;/strong&gt; Structure your authorization logic so that a user is denied access unless they are explicitly granted permission.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Server-Side Checks (Always!):&lt;/strong&gt; Never rely solely on client-side (frontend) checks to hide or disable features. Your API must validate the user's rights for every resource request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Authorization Middleware:&lt;/strong&gt; Use Express middleware to check roles before the main route handler executes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Code Example (Node.js with Express Middleware):&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;// Middleware to check for the 'admin' role
const requireAdmin = (req, res, next) =&amp;gt; {
    // Assume req.user object is populated after authentication 
    // CRITICAL SERVER-SIDE CHECK
    if (req.user &amp;amp;&amp;amp; req.user.role === 'admin') {
        next(); // User is an admin, proceed to the route handler
    } else {
        // Stop the request immediately
        res.status(403).json({ message: 'Forbidden: Insufficient privileges' });
    }
};

// Apply the check to the sensitive route
app.delete('/api/users/:id', requireAdmin, (req, res) =&amp;gt; {
    // This code only runs if the user is an admin
    // ... logic to delete user ...
    res.status(204).send();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts: Shift Left and Stay Curious
&lt;/h2&gt;

&lt;p&gt;The best security practice is adopting a "&lt;strong&gt;Shift Left&lt;/strong&gt;" mentality catching these issues as early as possible. Don't wait for a penetration test; build security into your code review process and daily habits.&lt;/p&gt;

&lt;p&gt;Security is a constant learning process. What other security mistakes have you seen or fixed recently? Let me know in the comments! 👇&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>owasp</category>
      <category>programming</category>
      <category>security</category>
    </item>
  </channel>
</rss>
