0
0
ExpressDebug / FixBeginner · 4 min read

How to Prevent SQL Injection in Express Apps Securely

To prevent SQL injection in Express, always use parameterized queries or prepared statements instead of string concatenation when building SQL commands. Use libraries like mysql2 or pg that support safe query placeholders to keep user input separate from SQL code.
🔍

Why This Happens

SQL injection happens when user input is directly added into SQL commands as plain text. Attackers can insert malicious SQL code that changes the query's meaning, leading to data leaks or damage.

javascript
const express = require('express');
const mysql = require('mysql2');
const app = express();

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'testdb'
});

app.get('/user', (req, res) => {
  const userId = req.query.id;
  const query = `SELECT * FROM users WHERE id = ${userId}`; // Unsafe string concatenation
  connection.query(query, (err, results) => {
    if (err) return res.status(500).send('Database error');
    res.json(results);
  });
});

app.listen(3000);
Output
If user sends /user?id=1 OR 1=1, the query becomes: SELECT * FROM users WHERE id = 1 OR 1=1 This returns all users, showing SQL injection vulnerability.
🔧

The Fix

Use parameterized queries to separate user input from SQL commands. This way, the database treats input only as data, never as code. Most database libraries support placeholders like ? for this.

javascript
const express = require('express');
const mysql = require('mysql2');
const app = express();

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'testdb'
});

app.get('/user', (req, res) => {
  const userId = req.query.id;
  const query = 'SELECT * FROM users WHERE id = ?';
  connection.query(query, [userId], (err, results) => {
    if (err) return res.status(500).send('Database error');
    res.json(results);
  });
});

app.listen(3000);
Output
If user sends /user?id=1 OR 1=1, the query safely searches for a user with id literally '1 OR 1=1', returning no unintended data.
🛡️

Prevention

Always use parameterized queries or prepared statements for all database access. Avoid building SQL commands by concatenating strings with user input. Use ORM libraries like Sequelize or TypeORM that handle this automatically. Validate and sanitize inputs as an extra safety layer. Enable linting rules that warn about unsafe query patterns.

⚠️

Related Errors

Other common security mistakes include:

  • Cross-Site Scripting (XSS): Injecting malicious scripts in web pages.
  • Broken Authentication: Poor session or password handling.
  • Improper Input Validation: Allowing unexpected data types or formats.

Fixes involve input validation, escaping output, and using secure authentication libraries.

Key Takeaways

Always use parameterized queries to separate user input from SQL commands.
Never build SQL queries by concatenating strings with user data.
Use trusted database libraries that support safe query placeholders.
Validate and sanitize all user inputs before using them.
Consider using ORMs to reduce manual query risks.