API Security · Lesson 11
Security: OWASP API Top 10 Deep Dive
While standard web application security focuses on injection and cross-site scripting, API security has different weak spots. The OWASP API Security Top 10 outlines risks unique to resource-oriented interfaces. We will deep-dive into three of the most common and destructive modern API vulnerabilities: Server-Side Request Forgery (SSRF), Mass Assignment, and Unrestricted Access to Sensitive Business Flows.
By the end you'll be able to
- Identify and mitigate Server-Side Request Forgery (SSRF) in webhook and URL-fetching endpoints.
- Defend APIs against Mass Assignment (broken object property level authorization) using DTO schemas.
- Architect defenses for Sensitive Business Flows using velocity limiting, behavior scoring, and CAPTCHAs.
- Compute rate-limit exhaustion curves and defense-in-depth budgets to block automated API exploitation.
1. Server-Side Request Forgery (SSRF)
SSRF (OWASP API7:2023) occurs when an API endpoint accepts a user-supplied URL and makes a request to it from the backend server. Since the server operates inside the company's internal private network, an attacker can supply local IP addresses (e.g. http://127.0.0.1 or http://169.254.169.254) to access internal metadata services, databases, or administration panels that are closed to the public internet.
In AWS, Google Cloud, and Azure, a link local address 169.254.169.254 hosts the Instance Metadata Service (IMDS). A request to http://169.254.169.254/latest/meta-data/iam/security-credentials/ returns the temporary IAM credentials of the virtual machine. If your API fetches a user-supplied profile image URL without strict filtering, an attacker can extract these credentials and compromise your cloud account.
SSRF Mitigation Checklist
- IP Address Validation. Resolve the hostname to an IP address before establishing the socket. Reject the request if the resolved IP points to private ranges:
127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.169.254. - DNS Rebinding Protection. Attackers can bypass initial checks by returning a public IP during resolution, then immediately swapping it to a private IP when the client makes the connection. Fix: pin the resolved IP address and connect directly to it, disabling automatic host header re-lookup.
- Isolate Fetchers. Run the URL-fetching service in an isolated network sandbox or VPC lane with zero access to internal databases.
2. Mass Assignment
Mass Assignment (OWASP API3:2023 - Broken Object Property Level Authorization) occurs when an API framework automatically binds user-supplied JSON properties directly to internal database objects or ORM models. If the database object includes columns like is_admin or role, an attacker can insert these keys into their API request payloads to escalate their privileges.
// ❌ VULNERABLE: Direct model binding
func UpdateProfile(w http.ResponseWriter, r *http.Request) {
var user User
json.NewDecoder(r.Body).Decode(&user) // Decodes whatever keys the client sent!
db.Save(&user)
}
// Payload sent by attacker to elevate status:
{
"display_name": "Attacker",
"is_admin": true
}
Mass Assignment Defenses
- Data Transfer Objects (DTOs). Never bind request bodies directly to database models. Instead, parse inputs into dedicated request schemas (DTOs) that contain only the properties developers explicitly want to allow users to modify (e.g.
UpdateProfileRequestcontaining onlydisplay_nameandavatar_url). - Schema Schemas & Validation. Use strict JSON schemas to validate properties and throw a 400 Bad Request error if additional, unrecognized keys are submitted.
3. Unrestricted Access to Sensitive Business Flows
Sensitive Business Flow Abuse (OWASP API6:2023) occurs when an API exposes actions that have high business impact or cost (e.g., ticket booking, promo code redemption, SMS OTP verification, account creation) and fails to limit how quickly or frequently they can be executed by automated bots.
Unlike standard rate limiting which blocks sudden volumetric DDOS attacks, abusers of sensitive flows often crawl slowly (low and slow) using rotated proxies to bypass IP-based limiters, draining company funds (e.g. paying for SMS gateway fees) or scraping inventory.
Under the hood: SSRF connection hijacking
This diagram shows how an attacker utilizes a vulnerable webhook-validator API to fetch database credentials from an internal AWS metadata server.
By the numbers: SMS gateway abuse budget math
Let's calculate the financial impact of unrestricted business flow exploitation and compute velocity limit thresholds.
Governing Equations
- Abuse Cost Accumulation: If an attacker exploits an unprotected OTP/SMS endpoint at rate $R$ (requests/min), and each SMS carrier delivery costs $C_{sms}$ dollars: $$Cost_{min} = R \times C_{sms}$$
- IP-Rotated attack threshold: If rate limiters only track IP addresses, and attackers rotate through proxy pool $P$ at $N$ IPs per minute: $$Limit_{IP} \times P = \text{Bypassed Rate}$$
- SMS Cost Burn Curve: $$Total_{cost} = Rate_{bypass} \times C_{sms} \times T_{duration}$$
Scenario Parameters
- Cost per SMS (India/Global mixed carriers): $0.04
- Attacker Proxy Pool ($P$): 20,000 distinct residential IP addresses
- IP Rate Limit: 5 requests per minute per IP (standard rate limit)
- Attack Duration ($T$): 8 hours (480 minutes)
Worked Calculations: Financial Loss under IP Limiting
- Compute the bypassed request rate: Since the attacker can make 5 calls per IP before triggering a block, they spread requests across 20,000 IPs: $$Rate_{bypass} = 20,000 \text{ IPs} \times 5 \text{ reqs/min} = 100,000 \text{ requests/minute}$$ $$Event_{rate} = 1,666.6 \text{ requests/second}$$
- Compute the cost rate per minute: $$Cost_{minute} = 100,000 \text{ requests/min} \times \$0.04 = \$4,000 / \text{minute}$$
- Compute total 8-hour exposure cost: $$Total_{cost} = \$4,000/\text{min} \times 480 \text{ minutes} = \mathbf{\$1,920,000}$$ This is a massive financial blow for a single night!
To defend the sensitive flow, we must design a rate-limiting schema that tracks multiple keys simultaneously:
- Client IP key: Max 3 requests / minute. (Blocks simple script attempts).
- Target phone number key: Max 3 requests / 5 minutes. (Prevents target harassment and phone spam).
- Tenant/Store ID key: Max 100 requests / minute globally. (Caps total company risk exposure).
- Cryptographic Proof-of-Work (PoW) token: Force client browsers to solve a CPU-intensive math problem (hashcash) for every SMS requested, increasing attacker cost by 1,000×.
How to debug & inspect it
To inspect and identify OWASP API vulnerabilities, capture and analyze request payloads and DNS resolutions using common network utilities.
Use the guide below to trace and repair vulnerabilities in your API schemas and networks:
| Vulnerability | Symptom | Fix |
|---|---|---|
| Server-Side Request Forgery (SSRF) | Server establishes outgoing TCP requests to internal IP addresses or cloud metadata points | Implement DNS resolution checks prior to socket connection; drop requests to local/RFC1918 IPs. |
| Mass Assignment / Broken Property Authorization | Users can modify internal status, database keys, or billing variables during POST/PATCH | Construct strict input schemas (DTOs). Disallow model properties from binding directly to incoming json objects. |
| SMS/OTP Flood Abuse | Spikes in SMS billing fees; SMS carrier pools depleted by bot traffic | Enforce velocity limits keyed on phone numbers, and implement Captcha/PoW hurdles for public entry points. |
🧠 Quick check
1. Why does simple host blocklisting (e.g., matching "localhost") fail to prevent SSRF?
Attacker hostnames can bypass string filters but still resolve to private IP addresses (like `127.0.0.1` or internal subnet targets). Effective mitigation requires resolving hostnames to IP addresses first and verifying they do not fall within private/reserved network blocks.
2. How does the use of Data Transfer Objects (DTOs) prevent Mass Assignment?
DTOs serve as a security buffer. Instead of mapping requests directly to GORM/ActiveRecord models, requests map to intermediate schemas that exclude security-sensitive columns like `is_admin` or `account_tier`.
3. Which mitigation addresses DNS Rebinding attacks during URL fetching?
To prevent DNS Rebinding, resolve the DNS name, validate the resulting IP, and instruct your HTTP client to connect directly to that resolved IP rather than resolving the hostname again during the connection phase.
4. Why do volumetric rate limits fail to protect Sensitive Business Flows from professional botnets?
By utilizing rotated IP proxy pools, attackers can spread the attack (e.g. 100,000 calls per minute) so that each individual IP only makes a single request, slipping underneath standard volumetric threshold limiters.
✍️ Exercise: design the SSRF validator function
Write out the pseudocode for a safe URL-fetching validation function that checks against SSRF and DNS rebinding attacks.
Model answer:
A secure URL fetch function must implement resolution validation and connect directly to the resolved IP address to prevent rebinding:
function safe_fetch_url(user_url_str) {
// 1. Parse URL structure
parsed_url = parse_url(user_url_str)
if parsed_url.scheme not in ["http", "https"]:
raise ValueError("Invalid scheme")
// 2. Resolve hostname to IP address
resolved_ips = dns_resolve(parsed_url.hostname)
if not resolved_ips:
raise ValueError("Could not resolve host")
target_ip = resolved_ips[0]
// 3. Verify IP is not in private/reserved ranges (RFC 1918)
if is_private_ip(target_ip) or is_link_local_ip(target_ip) or is_loopback_ip(target_ip):
raise ValueError("Access to private/local network ranges is forbidden")
// 4. Perform the HTTP request directly to target_ip
// Set 'Host' header to parsed_url.hostname so the server receives correct routing headers
http_headers = { "Host": parsed_url.hostname }
response = execute_http_get(connection_target=target_ip, port=parsed_url.port, headers=http_headers)
return response
}
Key takeaways
- **Validate IPs, not names**. SSRF bypasses basic host filters. Resolve the domain to an IP and verify it is not local (e.g., `127.0.0.1`, `169.254.169.254`) before opening sockets.
- **Decouple ORM binding**. Mass assignment is a severe vulnerability. Use strict Data Transfer Objects (DTOs) to explicitly define allowable fields for user modifications.
- **Protect sensitive business logic**. Velocity limit sensitive flows (SMS OTP, registration) using multi-dimensional keys (phone numbers, global tenant thresholds, browser PoW).
- **Mitigate DNS Rebinding**. Prevent resolution swaps by pinning the verified IP and executing the socket connection directly to it.
Sources & further reading
- OWASP API Security Top 10 (2023 Edition) — the official reference for API vulnerabilities
- Mitre CVE Repository — Mass Assignment & SSRF Cases — real-world examples of CVE exploits targeting corporate APIs
- Cloudflare Learning — DNS Rebinding Protection — technical mechanisms to prevent rebinding exploits