# SQL Injection (CWE-89) User input is concatenated directly into SQL queries, allowing attackers to modify the query logic and access or manipulate data. This is one of the oldest and most dangerous vulnerability classes, responsible for some of the largest data breaches in history. **Stack:** JavaScript - Prevalence: Very Common OWASP Top 10 since 2010 - Impact: Critical Data breach, auth bypass, RCE - Prevention: Well understood Parameterized queries **OWASP:** Injection (A03:2021-Injection) - #3 ## Description Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data. This can be used to alter query logic to bypass security checks, or to insert additional statements that modify the back-end database. ## Prevention 4 Shoulder डिटेक्शन नियमों पर आधारित SQL Injection के लिए रोकथाम रणनीतियाँ। ### JavaScript Use parameterized queries with placeholder syntax Use Prisma.sql tagged template for parameterized raw queries instead of regular template literals Use parameterized queries with positional (?) or named (:param) placeholders instead of string interpolation **Vulnerable code:** ``` // VULNERABLE: String concatenation const query = "SELECT * FROM users WHERE id = '" + userId + "'"; db.query(query); ``` **Secure code:** ``` // SAFE: Parameterized query const query = "SELECT * FROM users WHERE id = $1"; db.query(query, [userId]); ``` ## Warning Signs - [CRITICAL] user input flowing into SQL queries without parameterization - [CRITICAL] Raw SQL query uses untrusted input without proper parameterization. Use Prisma.sql`` template tag for safe parameter bin - [CRITICAL] Raw SQL query method uses untrusted input without parameterization. Use parameterized queries with ? or $1 placeholders. - [CRITICAL] QueryBuilder clause uses string concatenation with untrusted input. Use parameter binding with :name or ? placeholders. ## Audit Steps 1. Search for db.query(), pool.query(), connection.query() 2. Check for string concatenation or template literals in queries 3. Verify all user input goes through parameterized queries 4. Review ORM usage (Sequelize, Prisma) for raw query escapes ## Consequences - एप्लिकेशन डेटा पढ़ना - एप्लिकेशन डेटा संशोधित करना - सुरक्षा तंत्र को बायपास करना - अनधिकृत कमांड निष्पादित करना ## Mitigations - पैरामीटराइज़्ड क्वेरीज़ या प्रिपेयर्ड स्टेटमेंट्स का उपयोग करें - पैरामीटराइज़्ड क्वेरीज़ के साथ संग्रहीत प्रक्रियाओं (stored procedures) का उपयोग करें - अपने डेटाबेस के लिए विशिष्ट escape रूटीन का उपयोग करके सभी उपयोगकर्ता इनपुट को escape करें ## Detection - Total rules: 7 - Critical: 6 - Languages: go, javascript, typescript, python ## Rules by Language ### Javascript (4 rules) - **SQL Injection via Database Queries** [CRITICAL]: Detects user input flowing into SQL queries without parameterization. - Remediation: Use parameterized queries with placeholders. ```javascript db.query('SELECT * FROM users WHERE id = ?', [userId]); ``` Learn more: https://shoulder.dev/learn/javascript/cwe-89/sql-injection - **Prisma Raw Query SQL Injection** [CRITICAL]: Using template literals instead of Prisma.sql`` in $queryRaw bypasses parameter binding and enables SQL injection. - Remediation: Use Prisma.sql`` template tag for parameterized raw queries. ```typescript import { Prisma } from '@prisma/client'; const users = await prisma.$queryRaw( Prisma.sql`SELECT * FROM "User" WHERE id = ${userId}` ); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-89/raw-query-injection - **TypeORM SQL Injection in Raw Query** [CRITICAL]: Raw SQL queries with string concatenation or template literals bypass TypeORM's parameterization, enabling SQL injection attacks. - Remediation: Use parameterized queries with placeholder syntax. ```typescript const users = await manager.query( 'SELECT * FROM users WHERE id = ?', [userId] ); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-89/sql-injection-raw-query - **TypeORM Query Builder SQL Injection** [CRITICAL]: QueryBuilder where clauses with template literals or concatenation bypass parameter binding, enabling SQL injection. - Remediation: Use named parameters in QueryBuilder where clauses. ```typescript const users = await repository .createQueryBuilder('user') .where('user.role = :role', { role }) .getMany(); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-89/unsafe-query-builder ### Typescript (4 rules) - **SQL Injection via Database Queries** [CRITICAL]: Detects user input flowing into SQL queries without parameterization. - Remediation: Use parameterized queries with placeholders. ```javascript db.query('SELECT * FROM users WHERE id = ?', [userId]); ``` Learn more: https://shoulder.dev/learn/javascript/cwe-89/sql-injection - **Prisma Raw Query SQL Injection** [CRITICAL]: Using template literals instead of Prisma.sql`` in $queryRaw bypasses parameter binding and enables SQL injection. - Remediation: Use Prisma.sql`` template tag for parameterized raw queries. ```typescript import { Prisma } from '@prisma/client'; const users = await prisma.$queryRaw( Prisma.sql`SELECT * FROM "User" WHERE id = ${userId}` ); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-89/raw-query-injection - **TypeORM SQL Injection in Raw Query** [CRITICAL]: Raw SQL queries with string concatenation or template literals bypass TypeORM's parameterization, enabling SQL injection attacks. - Remediation: Use parameterized queries with placeholder syntax. ```typescript const users = await manager.query( 'SELECT * FROM users WHERE id = ?', [userId] ); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-89/sql-injection-raw-query - **TypeORM Query Builder SQL Injection** [CRITICAL]: QueryBuilder where clauses with template literals or concatenation bypass parameter binding, enabling SQL injection. - Remediation: Use named parameters in QueryBuilder where clauses. ```typescript const users = await repository .createQueryBuilder('user') .where('user.role = :role', { role }) .getMany(); ``` Learn more: https://shoulder.dev/learn/typescript/cwe-89/unsafe-query-builder