Sql Injection in APIs

What is Sql Injection?

SQL Injection (SQLi) is a code injection technique where an attacker inserts malicious SQL code into queries, causing the application to execute unintended database commands. This occurs when user input is concatenated directly into SQL queries without proper sanitization or parameterization.

Consider this vulnerable API endpoint:

app.get('/api/users', (req, res) => {
  const userId = req.query.id;
  const query = `SELECT * FROM users WHERE id = ${userId}`;
  db.query(query, (err, results) => {
    res.json(results);
  });
});

If an attacker requests /api/users?id=1 OR 1=1, the resulting query becomes:

SELECT * FROM users WHERE id = 1 OR 1=1

The OR 1=1 condition is always true, returning all user records. More sophisticated attacks can extract data, modify records, or even drop entire tables.

How Sql Injection Affects APIs

API endpoints are particularly vulnerable to SQL Injection because they often expose database operations directly to client requests. Attackers can exploit this to:

  • Extract sensitive data (PII, credentials, financial information)
  • Modify or delete database records
  • Elevate privileges by manipulating authentication queries
  • Execute administrative database commands
  • Access other databases on the same server

A common API attack pattern involves manipulating search parameters. For example, a product search endpoint:

/api/products?search=shoes' UNION SELECT username, password, 1, 1 FROM users--

This payload appends a UNION query to extract user credentials, with the -- commenting out the rest of the original query.

SQL Injection in APIs can also lead to remote code execution in certain database configurations. PostgreSQL's COPY command or MySQL's LOAD_FILE() can be abused to read arbitrary files or execute system commands.

How to Detect Sql Injection

Detecting SQL Injection requires both static analysis and dynamic testing. Key indicators include:

  • Direct string concatenation in SQL query construction
  • Dynamic SQL generation based on user input
  • Database errors returned in API responses
  • Unusual timing patterns in responses

middleBrick scans APIs for SQL Injection by testing common injection patterns across all endpoints. The scanner automatically:

  • Tests for boolean-based injection (e.g., ' OR 1=1--)
  • Tests for error-based injection to trigger database error messages
  • Tests for time-based injection to detect delayed responses
  • Analyzes error responses for SQL syntax or database engine fingerprints

The scanner also examines the API's OpenAPI specification to identify endpoints that accept parameters likely to be used in database queries, then focuses testing on those parameters. For example, endpoints with search, filter, id, or query parameters receive additional scrutiny.

middleBrick reports findings with severity levels and specific remediation guidance, helping developers understand exactly which endpoints are vulnerable and how to fix them.

Prevention & Remediation

The most effective prevention is using parameterized queries or prepared statements. These separate SQL code from data, preventing injection:

// Vulnerable
const query = `SELECT * FROM users WHERE id = ${userId}`;

// Secure
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId], (err, results) => {
  res.json(results);
});

ORMs and query builders provide additional protection by abstracting SQL construction:

// Using an ORM
const user = await User.findOne({ where: { id: req.query.id } });
res.json(user);

Other critical prevention measures:

  • Input validation and sanitization for expected data types
  • Least privilege database accounts with minimal permissions
  • Web Application Firewall (WAF) rules for SQLi patterns
  • Regular security testing and code reviews

For existing vulnerable code, remediation involves identifying all database query construction points and converting them to use parameterized queries. This includes stored procedures, dynamic queries, and any code that builds SQL strings from user input.

middleBrick's reports include specific line-by-line remediation guidance for each finding, showing exactly how to convert vulnerable code to secure parameterized queries.

Real-World Impact

SQL Injection remains one of the most dangerous and prevalent API vulnerabilities. The 2019 breach of a major financial services company exposed 100+ million customer records through SQL Injection in their API endpoints. Attackers exploited unvalidated input parameters to extract sensitive financial data over several months.

The 2020 CVE-2020-5398 in a popular e-commerce platform allowed attackers to bypass authentication and access admin functionality through SQL Injection in API endpoints. This vulnerability affected thousands of online stores and led to unauthorized administrative access.

SQL Injection's impact extends beyond data theft. In 2021, attackers used SQL Injection to modify pricing data in a retail API, allowing them to purchase high-value items at drastically reduced prices. The company lost over $1 million before detecting the breach.

According to OWASP, SQL Injection accounts for approximately 30% of all web application attacks and remains in their Top 10 API Security Risks. The average cost of a SQL Injection breach is estimated at $4.5 million, including data loss, remediation, and reputational damage.

middleBrick helps prevent these costly breaches by automatically detecting SQL Injection vulnerabilities before they reach production. With continuous monitoring in the Pro plan, APIs are scanned regularly as code changes, ensuring new vulnerabilities are caught early in the development lifecycle.

Frequently Asked Questions

What's the difference between SQL Injection and NoSQL Injection?
SQL Injection targets relational databases using SQL syntax, while NoSQL Injection targets non-relational databases like MongoDB or Cassandra. NoSQL injection often involves manipulating query objects or operators rather than SQL syntax. For example, MongoDB injection might involve crafting objects that exploit the database's query language, such as { $where: "this.user == '