Injection Attacks
Introduction
APIs receive data from many places. A request may include query parameters, path parameters, headers, cookies, form fields, JSON bodies, XML bodies, file names, search text, filters, sort values, and user-controlled identifiers. Every one of these inputs crosses a trust boundary. The API receives something from outside the server and must decide how to process it safely.
An injection attack happens when untrusted input is not treated as ordinary data. Instead, the backend interpreter treats that input as part of a command, query, expression, script, template, XML structure, or system instruction. This can happen in SQL databases, NoSQL databases, operating system commands, LDAP directories, XPath expressions, XML processors, template engines, log parsers, and other components that evaluate structured instructions.
Injection attacks are dangerous because they can turn a simple input field into a direct path to backend systems. A login field may alter a SQL query. A search parameter may return unauthorized records. A file name may affect an operating system command. A URL parameter may change an LDAP query. A request body may inject XML content that changes business meaning. If input is combined unsafely with backend logic, the API may execute something the developer never intended.
For API testers, injection testing is a critical part of security validation. It is not enough to test that valid names, IDs, dates, and filters work. Testers must also verify that malicious, unexpected, long, malformed, encoded, and boundary inputs are rejected or safely handled. A secure API should treat user input as data, not as executable instructions.
What Is an Injection Attack?
An Injection Attack occurs when an attacker sends malicious input that is interpreted as commands or code by the backend instead of being handled as plain data. The attacker does not necessarily need direct access to the database, operating system, or internal service. The attacker sends data to the API, and the vulnerable API passes that data into a sensitive interpreter unsafely.
A simple definition is this: an injection attack is a security vulnerability where untrusted user input is executed as a command, query, or expression by the server. The server should treat the input as a value. Instead, it accidentally gives the input power to change backend logic.
Injection is a broad category. SQL Injection is the most familiar type, but it is not the only one. APIs may also be vulnerable to NoSQL Injection, Command Injection, LDAP Injection, XPath Injection, XML Injection, Template Injection, CRLF Injection, and Expression Language Injection. The exact technology changes, but the root problem is the same: untrusted input reaches an interpreter without proper protection.
Why Injection Attacks Happen
Injection attacks usually happen because applications trust user input too much. A developer may concatenate request parameters directly into a SQL query. Another developer may build an operating system command using a file name from the request. A service may construct an LDAP filter using a username without escaping special characters. A template engine may render user-provided content as executable template syntax. Each of these patterns gives input more power than it should have.
Missing validation is another common cause. If an API expects a numeric ID, it should validate that the value is numeric and within an acceptable range. If it expects a country code, it should validate against allowed values. If it expects a date, it should validate the format and meaning. Without validation, dangerous characters and structures may reach deeper layers.
Dynamic query construction is especially risky. Code such as `"SELECT * FROM Users WHERE id=" + userId` mixes trusted SQL with untrusted input. If `userId` is not safely parameterized, the input can change the query. Similar risks appear when building NoSQL filters, shell commands, XPath expressions, LDAP filters, and dynamic templates.
User Input
|
API
|
Backend Query or Command
|
Database or System
|
Unexpected Command Executed
Common API Input Sources
Injection payloads can enter through any part of an API request. Query parameters are common because they are used for search, filtering, sorting, pagination, and lookup. Path parameters are common because they often carry IDs. Request bodies are common because they carry JSON or XML data for create and update operations. Headers and cookies can also be dangerous if backend code uses them in logs, queries, routing, authentication, or downstream service calls.
Form data and file metadata deserve attention as well. A file upload endpoint may accept a file name, content type, description, or processing option. If those values are later used in commands, file paths, metadata queries, or logs, they must be handled safely. Attackers look for any input that reaches a sensitive backend component.
The practical testing lesson is clear: do not test only the obvious text fields. Try injection-oriented values in every input location that the API accepts, within the approved test environment and scope. This includes parameters, request bodies, headers, cookies, multipart fields, and IDs.
SQL Injection
SQL Injection occurs when malicious SQL is inserted into input and executed by a relational database. It is one of the oldest and most well-known injection types, but it remains relevant because many applications still build queries incorrectly or expose complex search features without safe parameterization.
Consider a vulnerable login query:
SELECT * FROM Users
WHERE username = 'john'
AND password = 'password';
If user input is concatenated directly into this query, an attacker may provide a payload such as:
' OR '1'='1
The resulting query may become logically true in a way the developer did not intend:
SELECT * FROM Users
WHERE username = ''
OR '1'='1';
Since `'1'='1'` is always true, the query may return records or bypass checks depending on how the code is written. Modern authentication should not compare plaintext passwords in SQL like this, but the example clearly shows how query logic can be changed when input is treated as SQL.
SQL Injection in APIs
APIs commonly expose SQL Injection risk through filters, search fields, IDs, sorting parameters, and reporting endpoints. A request such as `GET /users?id=1 OR 1=1` should not alter the backend query. If the API inserts the input directly into SQL, unauthorized data may be returned.
GET /users?id=1 OR 1=1
Testing SQL Injection does not mean trying to damage a database. In a safe test environment, testers can use controlled payloads to verify that the API rejects input or safely parameterizes it. A secure API should not bypass authentication, return unintended data, expose database errors, crash, or produce long abnormal delays when it receives SQL-like input.
Signs of SQL Injection may include SQL syntax errors, table names in responses, stack traces, unexpected records, authentication bypass, inconsistent filtering, or server errors. A production API should not reveal raw database errors even when input is invalid.
NoSQL Injection
NoSQL Injection affects databases such as MongoDB and other document or key-value stores. The syntax differs from SQL, but the principle is similar. If the application passes untrusted JSON structures directly into a database query, attackers may alter query behavior.
{
"username": {
"$ne": null
}
}
In some vulnerable implementations, this kind of input can match unintended records because `$ne` means not equal. If the API expects a simple username string but accepts an object containing operators, the query may behave very differently from what the developer intended.
Testers should verify that NoSQL-backed APIs validate input types strictly. If `username` must be a string, an object should be rejected. If an ID must be a valid identifier, operator objects should not be accepted. Strong schema validation helps prevent NoSQL Injection by ensuring the API accepts the intended data shape only.
Command Injection
Command Injection happens when an API uses user input to build operating system commands. This can occur in file processing, report generation, image conversion, compression, system diagnostics, shell scripts, and legacy integrations. If input is concatenated into a command, attackers may inject shell control characters and execute unintended commands.
filename.txt && dir
On Unix-like systems, payloads may use characters such as semicolon, ampersand, pipe, backticks, or command substitution. On Windows systems, command separators and shell behavior differ, but the risk is the same: user input should not become executable system instructions.
Prevention usually means avoiding shell execution where possible. Use safe library APIs instead of shell commands. If command execution is unavoidable, use strict allow lists, fixed command arguments, safe process APIs, and never concatenate untrusted input into a shell string. Testers should verify that command-like input is treated as data and does not execute.
LDAP Injection
LDAP Injection affects applications that build LDAP queries from user input. LDAP directories are often used for enterprise identity, users, groups, and organizational information. If input is inserted into an LDAP filter without proper escaping, attackers may change the filter logic.
*)(uid=*)
A vulnerable application may accidentally broaden the search or bypass intended checks. This can affect login, user lookup, group membership checks, or internal directory searches. LDAP Injection is less commonly discussed than SQL Injection, but it matters in enterprise systems that integrate with directories.
Testers should identify APIs that authenticate against LDAP, search users, resolve groups, or query directory information. Inputs used in LDAP filters should be validated and escaped. Error responses should not reveal directory structure or filter details.
XPath and XML Injection
XPath Injection occurs when user input is concatenated into XPath expressions used to query XML documents. If input changes the expression logic, attackers may bypass checks or retrieve unintended XML nodes. A payload such as `' or '1'='1` can be dangerous if inserted into an XPath query without protection.
XML Injection happens when malicious XML content is inserted into a request or document and changes how the server processes data. For example, an attacker may try to add a role element such as:
<role>Admin</role>
If the server trusts this XML content without validation, the attacker may influence business data or processing logic. XML-related APIs should validate schemas, reject unexpected elements, disable unsafe parser features where needed, and avoid trusting client-supplied authority fields.
Template, CRLF, and Expression Injection
Template Injection occurs when user input is rendered by a template engine as template syntax instead of plain text. This can be dangerous if the template engine can evaluate expressions, access objects, or execute code. APIs that generate emails, documents, notifications, or dynamic content must avoid rendering untrusted input as executable templates.
CRLF Injection uses carriage return and line feed characters to manipulate headers, logs, or structured text. In APIs, this may appear when user input is copied into response headers, redirects, logs, or downstream requests. If line breaks are not handled safely, attackers may inject additional header-like content or corrupt logs.
Expression Language Injection occurs when user input is evaluated by an expression engine. This can happen in rules engines, search expressions, filtering DSLs, workflow systems, or template frameworks. If a user should provide data but the server evaluates it as an expression, the API may expose logic execution risk.
Real Login Example
A simple login request may look like this:
{
"username": "admin",
"password": "' OR '1'='1"
}
The expected result is `401 Unauthorized` if the password is wrong. If login succeeds, the API is vulnerable. Even if login fails, testers should inspect the response. It should not expose SQL errors, table names, stack traces, or internal authentication logic. The server should safely handle the payload as a password value, not as executable SQL.
This example also shows why injection testing should be part of authentication testing. A login endpoint may be functionally correct for valid users but still unsafe for malicious input. Security testing intentionally exercises inputs that normal business users do not send.
Signs of Injection Vulnerability
Injection vulnerabilities often reveal themselves through unusual responses. Database error messages, SQL syntax errors, stack traces, internal class names, unexpected data, authentication bypass, server errors, long response times, application crashes, and inconsistent behavior can all be warning signs. These symptoms do not prove exploitation by themselves, but they deserve investigation.
Long response times can be especially important when testing blind injection patterns. In blind injection, the API may not return visible data or errors, but payloads may affect timing or behavior. Time-based testing should be performed carefully and only in approved environments because it can create load.
Secure APIs should fail safely. Invalid input should produce controlled validation errors, not raw interpreter errors. The response should be useful enough for legitimate clients but should not reveal database names, queries, stack traces, file paths, server details, or internal architecture.
Risks of Injection Attacks
Injection attacks may lead to data theft, data modification, account takeover, privilege escalation, database deletion, remote code execution, service disruption, and complete system compromise. The exact impact depends on the interpreter being attacked and the privileges available to the application.
If SQL Injection succeeds against a database account with broad privileges, attackers may read tables, modify records, delete data, or create new accounts. If Command Injection succeeds, attackers may run system commands with the application's operating system permissions. If LDAP Injection succeeds, attackers may bypass identity checks or retrieve directory data. If Template Injection succeeds, attackers may access server-side objects or execute code depending on the engine.
Least privilege reduces impact. If the application connects to the database with only required permissions, an injection defect may still be serious but less catastrophic. If the application uses administrator-level database access for normal operations, one injection defect can affect the entire database.
Prevention Technique: Parameterized Queries
Parameterized queries are one of the strongest defenses against SQL Injection. Instead of building SQL by concatenating strings, the application sends the query structure separately from values. The database treats user input as data, not SQL syntax.
SELECT * FROM Users
WHERE id = ?
The placeholder is bound to a value by the database driver. Even if the value contains quotes, spaces, or SQL-like text, it is not interpreted as part of the SQL command. This preserves the intended query structure.
Parameterized queries should be used consistently. One safe endpoint does not protect another unsafe endpoint. Search, reporting, filtering, sorting, login, batch export, and admin tools all need safe query construction. Stored procedures can help in some designs, but they can still be unsafe if they build dynamic SQL internally with concatenation.
Prevention Technique: Input Validation
Input validation ensures that the API accepts only expected data. Validation should check data type, length, format, allowed characters, numeric range, enum values, object structure, required fields, and business rules. An employee ID should be numeric or match the expected identifier format. A status should be one of known values. A date should be valid. A sort field should come from an allow list.
Allow-list validation is usually stronger than deny-list validation. A deny list tries to block dangerous values, but attackers can encode, split, or vary payloads. An allow list defines what is acceptable and rejects everything else. If a country code must be two uppercase letters, the API does not need to guess every dangerous SQL payload; it accepts only the expected pattern.
Validation should happen on the server. Frontend validation improves user experience but cannot protect the API because attackers can bypass the UI. API tests should send invalid input directly to the backend to verify server-side enforcement.
Other Prevention Techniques
Output encoding reduces risk when data is later displayed or consumed by another interpreter. For example, data stored through an API may later be rendered in an HTML page, CSV file, XML document, email template, log viewer, or report. Encoding must match the output context. SQL parameterization protects SQL queries, while HTML encoding protects browser rendering, and CSV handling protects spreadsheet output.
Least privilege limits damage. Database accounts should have only required permissions. Application accounts should not use database administrator credentials for normal operations. File-processing services should run with limited operating system rights. Service accounts should be scoped carefully. If injection occurs, least privilege reduces what the attacker can do.
Secure error handling prevents information leakage. APIs should not expose SQL queries, stack traces, table names, database names, server file paths, driver messages, or internal exception details. Detailed errors can be logged safely for internal investigation, but client responses should be generic and controlled.
Dependency management is also important. Database drivers, ORM frameworks, XML parsers, template engines, and web frameworks should be kept updated. Security patches often fix parsing, escaping, or interpreter-related weaknesses.
Injection Testing in API Testing
QA engineers should verify SQL Injection, NoSQL Injection, Command Injection, LDAP Injection, XPath Injection, XML Injection, input validation, error handling, database security, and whether authorization remains enforced after malicious input. Testing should cover both obvious and less obvious input points.
A good test starts with understanding the endpoint. What input does it accept? Where is that input used? Does it search a database? Does it call another service? Does it build a command? Does it process XML? Does it use a template? Does it store data that is rendered later? These questions help testers choose meaningful payloads instead of blindly sending random strings.
Injection testing should be scoped and controlled. Do not run destructive payloads against production systems. Use safe test data and approved environments. The goal is to verify that input is handled safely, not to damage systems. Automated tests should use non-destructive payloads and clear assertions.
Example Test Cases
For SQL Injection, send a payload such as `' OR '1'='1` in a login, search, filter, or ID field. The expected result is that the request is rejected or safely handled. The API should not bypass authentication, return unintended records, expose database errors, or crash.
For invalid characters, send values such as `<`, `>`, quotes, semicolons, comment markers, and other special characters. The API should validate or safely handle them according to the contract. Special characters are not always invalid, but they should never change backend command behavior.
For very long input, send a controlled oversized string. The expected behavior is graceful validation without crashes, memory exhaustion, or excessive response time. For Command Injection, send shell-like strings such as `&& dir` or `; ls` in fields that may affect file or process handling. The API should treat them as data and not execute commands.
For NoSQL Injection, send an object where a string is expected, such as `{ "$ne": null }`. The API should reject the wrong type or handle it safely. For XML and XPath areas, send unexpected elements or XPath-like input and verify that access is not bypassed and parsing remains safe.
REST Assured Example
REST Assured can automate injection checks in Java. A login or search endpoint can be tested with a SQL-like payload and should reject it or handle it safely.
given()
.queryParam("username", "' OR '1'='1")
.when()
.get("/login")
.then()
.statusCode(401);
This test should not only check the status code in a real suite. It should also verify that the response body does not include protected data or internal error details. For search APIs, the test may assert that the result set does not expand unexpectedly.
Postman Example
In Postman, testers can create a set of controlled injection payloads and run them against selected endpoints. Useful payload categories include SQL-like strings, comment markers, semicolons, XML fragments, NoSQL operator objects, shell separators, angle brackets, and very long input values.
' OR '1'='1
--
;
&&
<>
{ "$ne": null }
After sending these inputs, verify the status code, error response, response body, database integrity, logs where available, and absence of sensitive information. Postman is useful for exploration, but repeatable high-value checks should eventually move into automated regression suites.
Karate Example
Karate can express injection tests clearly. A query parameter payload may look like this:
Given param username = "' OR '1'='1"
When method GET
Then status 401
For JSON-body validation, Karate can send structured malicious input and assert a safe rejection. This works well for NoSQL Injection and Mass Assignment adjacent tests where type and property control matter. The scenario name should identify the risk being tested so reports remain useful.
Real-World Examples
In banking, injection could expose account balances, transaction history, beneficiary data, loan records, or payment information. It could also manipulate transfer workflows if backend queries or commands are unsafe. Financial APIs require strict input validation and least-privilege database access.
In healthcare, injection could expose patient records, prescriptions, insurance details, medical history, and clinical notes. It may also affect appointment or billing workflows. Because healthcare data is highly sensitive, secure error handling and audit logging are important alongside prevention.
In e-commerce, injection could expose customer accounts, orders, payment references, coupons, inventory, or administrative reports. Search, product filtering, coupon validation, order lookup, and admin dashboards are common areas to test.
In employee management systems, injection could expose employee records, salary data, HR information, manager assignments, or access permissions. APIs that support reporting, filtering, and bulk export need careful validation because they often generate complex queries.
Best Practices
Use parameterized queries or prepared statements for database access. Avoid dynamic query concatenation with untrusted input. Validate all input on the server using allow-list rules where possible. Confirm expected data types, lengths, formats, ranges, and enum values. Use safe APIs instead of shell commands. Escape LDAP, XPath, and XML inputs according to the correct context when those technologies are used.
Apply least privilege to database accounts, service accounts, file systems, and operating system processes. Return generic error messages to clients while logging safe diagnostic details internally. Keep frameworks, libraries, database drivers, XML parsers, and template engines updated. Perform regular security testing and include injection checks in API regression coverage for high-risk endpoints.
Review code paths that process search, filters, sorting, reports, authentication, file uploads, admin tools, dynamic expressions, and third-party inputs. These areas often handle flexible input, and flexible input needs stronger validation.
Common Mistakes
A common mistake is building queries with string concatenation. Never concatenate untrusted input directly into SQL, LDAP, XPath, command strings, or expression syntax. Another mistake is trusting user input because it came from a known frontend. APIs can be called directly, and client-side restrictions can be bypassed.
Revealing database errors is another mistake. SQL syntax errors, table names, driver messages, and stack traces help attackers refine payloads. APIs should return safe errors. Using overprivileged database accounts is also dangerous because it increases the impact of any injection defect.
Testing only valid input is a testing mistake. Security testing should include malicious, unexpected, encoded, boundary-case, and malformed input. Valid-data tests prove the API works. Injection tests prove the API handles hostile input safely.
Common HTTP Status Codes
| Scenario | Common Status Code |
|---|---|
| Valid request | 200 OK |
| Invalid input | 400 Bad Request |
| Authentication failure | 401 Unauthorized |
| Authorization failure | 403 Forbidden |
| Unexpected server error | 500 Internal Server Error, without implementation details |
The preferred response depends on the API design. The security requirement is that malicious input must not execute as commands, must not expose protected data, and must not reveal sensitive internals. A `500` response may indicate the API handled the input poorly even if no data was returned.
Practical Review Checklist
When reviewing injection risk, identify every input source first. Include path parameters, query parameters, request bodies, headers, cookies, file names, form fields, and external API responses. Then identify where each input goes. Does it reach SQL, NoSQL, command execution, LDAP, XPath, XML parsing, templates, logs, or downstream services?
Review implementation controls. Are SQL queries parameterized? Are NoSQL inputs schema-validated? Are command executions avoided or safely structured? Are allow lists used for sort fields, filter names, file types, and enum values? Are errors generic? Are backend accounts least privileged?
Review test coverage. Are malicious payloads included for high-risk inputs? Are long inputs tested? Are special characters tested? Are invalid data types tested? Are persisted effects checked? Are authorization rules still enforced when payloads are malicious? Injection testing should confirm both safe handling and safe outcomes.
Interview Questions
A common interview question is: what is an Injection Attack? A strong answer is that an Injection Attack is a vulnerability where malicious user input is interpreted as commands, queries, or expressions by the backend instead of being treated as ordinary data.
Another question is: what is SQL Injection? SQL Injection is a type of injection attack where malicious SQL statements are inserted into user input to manipulate database queries. It may lead to authentication bypass, unauthorized data access, data modification, or database damage.
Interviewers may ask how SQL Injection can be prevented. Good answers include parameterized queries, prepared statements, input validation, avoiding dynamic query concatenation, least-privilege database accounts, and generic error messages. They may also ask what API testers should verify: SQL Injection, NoSQL Injection, command injection, LDAP injection, XPath injection, input validation, secure error handling, and database integrity.
Another useful point is that injection remains important in API testing even when it is not a standalone item in the OWASP API Security Top 10 2023 list. It is still a major software security concern and appears in API risk areas through unsafe input handling, property-level authorization issues, resource consumption, and unsafe consumption of APIs.
Interview-Ready Explanation
Injection Attacks are security vulnerabilities where an application incorrectly interprets untrusted user input as executable commands, queries, or expressions instead of treating it as plain data. Common types include SQL Injection, NoSQL Injection, Command Injection, LDAP Injection, XPath Injection, XML Injection, Template Injection, CRLF Injection, and Expression Language Injection. These attacks can happen when applications trust input, fail to validate it, concatenate it into backend instructions, or expose raw interpreter errors.
Injection attacks can lead to authentication bypass, unauthorized data access, data modification, privilege escalation, database deletion, remote code execution, and business disruption. The most effective prevention techniques are parameterized queries, prepared statements, strict input validation, allow lists, safe command APIs, context-aware escaping, least-privilege backend accounts, secure error handling, and updated libraries.
During API testing, testers should send controlled malicious inputs through query parameters, path parameters, headers, cookies, request bodies, form data, and file metadata. They should verify that the API rejects or safely handles the input, does not expose database or system errors, does not return unauthorized data, does not execute commands, and preserves database integrity. Strong injection testing proves that the API treats untrusted input as data, not as executable backend logic.
Key Takeaway
Injection attacks happen when untrusted input crosses into an interpreter without proper protection. The API may intend to receive a name, ID, search term, file name, or filter value, but unsafe backend handling can allow that input to change SQL, NoSQL, command, LDAP, XPath, XML, template, or expression behavior. This makes injection one of the most important security topics for API developers and testers.
For testers, the practical rule is to test both normal input and hostile input. Validate that malicious payloads do not bypass authentication, do not bypass authorization, do not expose sensitive data, do not reveal internal errors, and do not damage stored data. Secure APIs handle untrusted input deliberately, validate it strictly, and pass it to backend systems safely.