JavaScript Security: Protection from SQL Injections and XSS — A Complete Developer's Guide
\n\nHave you ever wondered why hackers love web applications so much? The answer is simple: developers often leave the "doors" open. The two most popular loopholes are SQL injections and XSS (Cross-Site Scripting). Even if you write in JavaScript, it doesn't mean you are protected from server-side attacks. In this article, we will break down how to recognize vulnerabilities and, most importantly, how to close them using modern security practices.
\n\nWhy should a JavaScript developer think about security?
\nMany beginners think: "I write on the frontend, I don't touch databases — nothing threatens me." This is a dangerous misconception. JavaScript works everywhere today: on the client (browser), on the server (Node.js), and even in databases (MongoDB). This means the responsibility for security falls on you. SQL injections and XSS are not just boring terms from textbooks; they are real threats that can destroy your project by stealing user data or turning your site into a virus breeding ground.
\n\nSQL Injections: An Invisible Threat to Your Database
\nAn SQL injection is an attack where an attacker "injects" malicious SQL code through input fields (forms, URLs, headers). If you use Node.js with PostgreSQL, MySQL, or any other relational database, you are at risk.
\n\nWhat does an SQL injection look like in JavaScript?
\nImagine you have a login form, and you write the query like this:
\n// ❌ DANGEROUS: vulnerable to SQL injection\nconst username = req.body.username;\nconst password = req.body.password;\nconst query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;\nNow imagine an attacker enters in the username field: admin' --. The query becomes:
SELECT * FROM users WHERE username = 'admin' --' AND password = '';\n-- is a comment in SQL. Everything after it is ignored. The hacker logs in as admin without a password. And if they enter '; DROP TABLE users; --? You will lose your entire users table.
Protection: Parameterized Queries (Prepared Statements)
\nThe best way to protect against SQL injections is to never insert user data directly into a query string. Use parameterized queries. Here's how it's done in Node.js with the pg library (PostgreSQL):
// ✅ SAFE: parameterized query\nconst { Pool } = require('pg');\nconst pool = new Pool();\n\napp.post('/login', async (req, res) => {\n const { username, password } = req.body;\n \n // The $1 and $2 signs are placeholders\n const query = 'SELECT * FROM users WHERE username = $1 AND password = $2';\n const values = [username, password];\n \n try {\n const result = await pool.query(query, values);\n // handle the result...\n } catch (error) {\n console.error('Query error:', error);\n }\n});\nThe library escapes the values itself. Even if an attacker passes admin' --, it will be treated as a regular string, not an SQL command.
Additional Security Measures
\n- \n
- Server-side validation: check the type and length of input data. If an email is expected, make sure it is actually an email. \n
- Principle of least privilege: do not use the database root user in the application. Create a separate user with permissions only on the necessary tables. \n
- ORM libraries: use Prisma, Sequelize, or TypeORM. They automate parameterization, but remember that you can still write unsafe code in them (for example, using
sequelize.querywith concatenation). \n
XSS (Cross-Site Scripting): When Your Site Attacks Itself
\nXSS is an attack where an attacker injects malicious JavaScript code onto a page, whi