API Threat Research: Detailed Financial Records Exposed on Financial Services Platform
Incident synopsis
Salt Labs researchers investigated a large financial institution’s online platform that provides API services to thousands of partner banks and financial advisors. As a result of multiple API vulnerabilities, our researchers were able to launch attacks where:
- Any user could read the financial records of any customer
- Any user could delete any customer’s accounts in the system
- Any user could take over any account
- Any user could create a denial-of-service condition that would render entire applications unavailable
We were successful in propagating these attacks, many of which correspond to the OWASP API Security Top 10. We were able to exploit the following high-severity API security vulnerabilities in the financial services platform:
- broken object level authorization (BOLA)
- broken function level authorization (BFLA)
- susceptibility to parameter tampering
- improper input validation
Throughout this threat research report, we have anonymized any technical details of the vulnerability that could identify the organization, so as not to expose the financial entity to any additional risk. We have reviewed these findings with the organization and are sharing the information here to improve awareness around API security by detailing relevant attack patterns, technical details, and mitigation techniques for each vulnerability.
Research motivation
Salt Labs regularly conducts threat research to uncover potential vulnerabilities and help improve API security posture of customers, prospects, and the larger public as appropriate. We practice responsible disclosure when we uncover new vulnerabilities, working with the involved parties to resolve issues. We are sharing this anonymized information as educational material to help practitioners learn from these mistakes and avoid a potential incident or breach within their organization.
In this case, Salt Labs researchers investigated the online platform because this type of banking platform acts as a critical component of a digital supply chain in a large financial ecosystem. A broad range of financial services (FinServ) organizations offer traditional banking services to business and customers, and an ever-growing set of financial technology (FinTech) providers offer connectivity and online services to modernize traditional finance activities. Indeed, as banks undergo digital transformation and modernize their business for the online world, traditional FinServ organizations can increasingly look and operate more like FinTech.
We undertook this deep security research to better understand the risks in the API-driven ecosystems at the heart of these providers.
The security gaps we found and their potential business impacts
We dive deeper into the technical details of each vulnerability and attack in the next section, but just as important as those details – often more important to leadership teams – is an understanding of the tangible business impact these security gaps present. Such an analysis involves gauging security risk and business risk as well as exploitability and impact of each vulnerability. In this case, we were able to show how the impact worsens significantly when an attacker chains together multiple exploits of these issues. Ultimately, the vulnerabilities in authorization for these APIs allow for complete privilege escalation and account takeover (ATO) in the financial services platform.
Attack: Retrieve financial records and stored check images, with Social Security numbers and bank account numbers
Threat actors – both insider threats and external users – can abuse the authorization mechanisms in the APIs of this financial platform to gain access to far more data than the API design intended. Once attackers have obtained a working user account with even the most basic permission levels, they can escalate privileges to read any data within the financial platform.
In our research, we were able to access extensive financial records, stored check images, and other assets, with full visibility into sensitive data including social security numbers and bank account numbers. All of these data types fall under regulatory compliance and would leave the organization exposed to a broad set of regulatory and financial penalties. Attackers could also use this information to perpetuate other types of fraud such as assuming someone’s identity, redirecting income tax refunds, setting up fake accounts, and other nefarious activities.
Attack: Delete or lock out user accounts
Building on the exploitability of the authorization mechanisms of the financial services platform, we were able to show how a user with any level of access could take action against any other user account – validating, invalidating, and/or deleting users arbitrarily.
This gap compromises the integrity of all user accounts in the platform, enables attackers to perform administrative-level functions, and allows an attacker to make the financial services platform completely unavailable to all partners and customers. We also shared with the financial institution how easily attackers could use this API weakness to bribe users or administrators of the financial services platform.
Attack: Full account takeover of any user
Attackers could take over user accounts by compromising the two-factor authentication (2FA) mechanism. By manipulating parameters of API requests, we were able to redirect the 2FA challenges to our own devices.
With this access, we could have reset user passwords in the platform, create new accounts, or obtain access to more sensitive data where step-up authentication is required. Authentication and authorization mechanisms are weakened when it’s possible to redirect 2FA challenges, and this vulnerability, in turn, leads to greater risk of account compromise and account takeover (ATO).
Attack: Launch a Denial-of-Service event
Typically an attacker would opt to extract or exfiltrate as much sensitive data as possible when targeting an application and its APIs. ATO is also another primary goal to obtain persistence and abuse other users in the system. Attackers sometimes seek to launch denial of service (DoS) attacks to render an application or service entirely unavailable.
The most well-known DoS and distributed DoS (DDoS) attacks are volumetric attacks, where an attacker simply overwhelms network paths and systems with too much traffic for an architecture to handle. More nefarious are the application-layer DoS attack pattern, where an attacker crafts requests with “heavy queries” that are unique to an application and its APIs.
These application-layer DoS patterns will invoke some application function that is expensive in terms of time and compute cycles. To avoid harming this financial institution’s customers, we launched a minimal, short-term DoS attack on one platform function to highlight how the lack of resource limiting left the financial entity vulnerable. An actual hacker could use a small handful of requests – or even just one – to bring an entire platform like this one to its knees, rendering all data and functionality unavailable to customers and partners.
The technical details of these API security gaps
The following sections highlight the techniques we used to hack the APIs of this financial institution and exploit the latent vulnerabilities. In each case, we are detailing the form of the attack and sharing screen captures of the types of manipulations we performed. Identifying sensitive data such as hostnames, timestamps, and account identifiers have been recreated or obscured where appropriate.
Any user could read the financial records of any customer
Security gaps in authorization enable what are known as OWASP API1 broken object level authorization (BOLA) attacks. In these attacks, an attacker can escalate privileges horizontally (assume access level of another user who has equivalent permissions) and vertically (assume access level of another user who has higher or administrative permissions). In this case, Salt Labs researchers were able to adjust object IDs arbitrarily for API endpoints and, as a result, gain direct data access to any number of financial records.
Salt researchers found that an API endpoint allowed for client-controlled parameters in the URL, which served as file locators in the back end. The API endpoint looked like the following:
“/customer/rest/api/document/file?type=<type>&file=<file>&id=<ID>”
Specifically, a GET request to this API endpoint could be made by adjusting the query parameter ID to some alphanumeric sequence that would be used to retrieve stored data in the back end. A couple other factors increased the security impact:
- the ID parameter did not use sufficient randomness or entropy
- the API endpoint lacked any resource or rate limiting
As a result, Salt Labs researchers were able to guess and enumerate through record identifiers to extract data in the back end including contracts, scanned images of paper checks, and other sensitive documents residing on the financial services platform.
We include here an example check image that we extracted from the back end with an unprivileged account. The image has been blurred to protect the identity of the customer and the financial institution. The original check image was full fidelity.
API Request: The API request that Salt Labs researchers used to extract the check image from the back end can be seen above. An attacker simply needed to change the file and id parameters to access stored records in the backend without authorization.
API Response: The resulting API response from the manipulated API request can be seen above. This response included image data as indicated by the “Content-Type:image/tiff” HTTP header, which is why you see extended ASCII characters in the response. A user’s web browser would render the image on-screen, or it can be saved to other storage as a TIFF image file and viewed later.
We propagated just a few of these attacks – an actual hacker could easily use an intercepting proxy tool such as Burp Suite or OWASP Zed Attack Proxy to quickly enumerate through identifiers and access all stored documents in the platform. After exfiltrating data – mostly likely large data sets – an attacker would likely sell the data on the dark web or use it to perpetuate other types of fraud.
Any user could delete any customer’s accounts in the system
Salt Labs researchers discovered another variation of an authorization weakness in another API endpoint that controlled user credentials in the access control mechanism of the financial services platform. Specifically, the API endpoint was vulnerable to OWASP API5 — broken functional level authorization (BFLA) attacks. By abusing this endpoint, we were able to validate, invalidate, and delete user accounts arbitrarily, irrespective of the authenticated user’s access level.
Any API endpoint that requires user identifiers in multiple spots of an API request — such as in URL parameters, header values, cookies, and message payloads — is likely more susceptible to BFLA or BOLA attacks. Authenticated context or session identifiers may be written in a primary instance of an identifier in a given API request, while the code of the API uses one of the other user identifier instances to fetch records. Attackers will often manipulate these user and record identifier fields in an attempt to bypass or abuse authorization mechanisms.
The API endpoint looked like the following:
“/users/commit”
In the financial services platform, users interact with the API endpoint using POST requests rather than GET requests, so no URL parameters were required here. The first user identifier instance was specified in the cookie “uname.” The second user identifier instance was an attribute-value pair within the message body of the API request, “UID.” The Salt Labs team was able to alter the second user identifier along with another attribute-value pair “status” to take action on any user within the system. By changing the second identifier “UID” and the value of “status,” this endpoint enabled us to change the status of any user in the system to be validated, invalidated, or deleted. “Deleted” users were no longer able to access the financial services platform.
API Request: The API request that Salt Labs researchers used to change the status of a user in the back end can be seen above. You can see that “cookie.uname,” which is the authenticated user context, does not match “UID,” the target account to take action on. An attacker simply needed to change UID to the value of some other user in the system and specify a new value for “status.” The financial institution had cross-site request forgery (CSRF) defense mechanisms in place, as indicated by the cookie “xsrf-token,” but they were not enough to mitigate this attack.
API Response: The resulting response from the server indicates that the manipulated request worked, as evidenced by the “status” and “message” attribute-value pairs in the JSON format message body. Some of the submitted data from the API request is visible in the “data” attribute-value pair.
This vulnerability has serious repercussions for the financial services platform. A malicious threat actor could invalidate or delete any user in the platform and prevent access by sending one well-crafted API request.
Any user could take over any account
Salt Labs researchers discovered that the financial services platform made use of 2FA to strengthen authentication. 2FA mechanisms often utilize cellular text messages to send a PIN to a user’s registered mobile device as an additional challenge during the login processes or to allow privileged actions.
Salt Labs researchers found that one of the API endpoints that was prone to BFLA attacks could also be abused to circumvent 2FA, “/users/commit.” By manipulating the values of fields in requests to this API endpoint, our researchers could control where PINs were sent and could redirect the value used for 2FA to a mobile device we controlled. The system did not properly validate whether the user making the API request had sufficient privileges to make such alterations to a given user account.
API Request: The API request that Salt Labs researchers used to modify the registered 2FA device for a given user in the back end can be seen above. The block of values within “device” can be manipulated to any phone number. The parameter “protocol” defines the delivery mechanism for the 2FA challenge — SMS in this case. The parameter “deviceUpdate” is used in the request to indicate that a new number is being added to the user. These manipulations result in redirects of SMS challenges to that newly registered phone number.
API Response: The resulting response from the server indicates that the manipulated request worked as evidenced by the “status” and “message” attribute-value pairs in the JSON format message body. Some of the submitted data from the API request is visible as the “data” attribute-value pair.
We were able to easily abuse this API endpoint to bypass 2FA authentication, alter user accounts, and achieve ATO.
Any user could create a denial-of-service condition that would render entire applications unavailable
APIs are often designed to enable data retrieval. If no limits are put in place on requests, however, attackers can propagate application-level denial of service (DoS) attacks – often with only a handful of requests. In addition, some API functions are computationally “expensive” – attackers can launch these activities to render services unavailable for other users. The Salt team details the attacks focused on resource and rate limiting in the blog post API4:2019 Lack of Resources & Rate Limiting.
Salt Labs researchers searched for API endpoints that allow extracting a substantial number of records in a single API request. Salt researchers also looked for an API endpoint that had no enforcement of resource or rate limits on API requests. Our research yielded the following susceptible endpoints:
“/customers/search”
“/accounts/search”
Submitting a POST request to either API endpoint, we were able to manipulate the value of a variable within the message body of the API request. Specifically, a parameter named “pageSize” controlled the number of results that would be queried for in the back end and ultimately returned in the API response. The typical integer value for this parameter was 100. Since this value was user controllable, Salt Labs researchers could set the value higher. Had we used a value of 100000, for example, we could easily have consumed all computing resources on the platform, making it unavailable to all customers and partners – this type of attack is an application-level DoS attack.
API Request: The API request that Salt Labs researchers used to create the application-level DoS condition in the back end can be seen above. The block of values within “result” can be manipulated, specifically “pageSize” controls the number of records within a page result that will be served to the API client. Setting this value to a higher-than-normal value taxes the back end, since it must fetch more data for the API client to satisfy the request. In this case, Salt Labs researchers set the value of “pageSize” to 10000.
API Response: The resulting response from the back end contains a very large data set, as evidenced by the “Content-Length” HTTP header value of 492092 and number of records in the JSON format message body that have been truncated here for readability. The time it took for the back end to respond with the data set was also excessive. We launched this proof-of-concept, short-term attack to demonstrate susceptibility to application-level DoS. Had we set the “pageSize” value higher, it would’ve created a significant availability problem and outage in the financial services platform.
We demonstrated to the financial institution various ways a malicious threat actor could abuse this weakness. We highlighted how a hacker could create a temporary DoS condition by sending just one crafted PI request. We also showed how a threat actor could create a more persistent DoS situation by automating API requests with intercepting proxy tools or scripts to send this kind of crafted API request on a longer interval, such as once per minute, to avoid detection and evade any rate limits in place. Ultimately, the ability to manipulate the data retrieval volume meant a single API request or a small handful of them could bring down the entire financial services platform. Note that an attacker would not need to send a flood of network connection requests using a volumetric DoS attack to take down the platform. Web application firewalls, which provide rate limiting to prevent some types of DoS attacks, would easily be circumvented with this more subtle DoS attack via API call manipulation.
Methods to mitigate these API issues
Exploiting the flaws in this financial institution’s APIs would require unique manipulation of the business logic involved in each API. Similarly, appropriate remediation and mitigation techniques also must be unique.
Mitigating an authorization weakness that permits any user to read any record
A well-designed API should verify whether the user requesting a given piece of data is also authorized to access it. Unlike authentication, authorization should be performed continuously throughout a session and on each data access. This continuous approach to authorization is a basic security tenet of least privilege, which coincidentally also intersects with zero trust architecture.
Apply the following steps to mitigate the authorization weaknesses Salt Labs found in these API endpoints:
- The API and integrated, back-end systems should continuously validate whether the authenticated user is authorized to access the given record.
- If an authenticated user tries to access someone else’s records, the server should respond with a “401 Unauthorized” HTTP status.
- The platform should monitor and invalidate sessions where users are making excessive requests, enumerating records, or making repeated attempts to access unauthorized data.
- Use record identifiers with higher levels of entropy instead of easily guessable or enumerable hexadecimal and alphanumeric sequences.
- Enforce rate limits on API endpoints to prevent basic forms of enumeration of record identifiers – though be aware that attackers will throttle their requests to evade detection.
Mitigating an authorization weakness that permits an unprivileged user to delete another user account
Similar to the previous example of an API designed for data access, a well-designed API should verify whether the authenticated user attempting to perform a given function is authorized to use that function.
Apply the following steps to mitigate authorization weaknesses Salt Labs found in these API endpoints:
- The API and integrated, back-end systems should continuously validate whether the authenticated user is authorized to access the given function.
- If an authenticated user tries to access functionality for which they are not authorized, the server should respond with a “401 Unauthorized” HTTP status.
- The platform should monitor and invalidate sessions where users are making excessive requests, enumerating records, or making repeated attempts to access unauthorized functionality.
- Limit use of API request parameters to determine sources and targets for functions. The system should identify the function requestor based on the session identifier in the back end, not on a parameter or cookie value within the API request.
- Restrict use of the delete function for lower-privileged users. It should not be possible for a non-elevated user to delete other user accounts or their own ID.
Mitigating a parameter tampering weakness that allows for account takeover
API access controls are critical for protecting APIs in runtime. Organizations often employ 2FA to further strengthen authentication and authorization mechanisms for APIs and protect users from account compromise.
Follow these steps to mitigate the authentication parameter tampering weaknesses Salt Labs found in these API endpoints:
- Limit use of API request parameters to determine sources and targets for functions. The system should identify the function requestor based on the session identifier in the back end, not on a parameter or cookie value within the API request.
- Ensure that the registered mobile number of the authenticated API caller matches that of the target device the 2FA challenge is using. It should not be possible to send challenges to devices to which the user has no ownership of or were not previously registered.
Mitigating an input filtering weakness that allows for application-level denial of service
Denial of service (DoS) and Distributed denial of service (DDoS) protections are essential for any application or API, particularly those that are Internet-facing or designed for use by a very large user base. Mitigating an application-layer DoS attack pattern requires understanding the unique business logic of the APIs that make up an application or system so that API requests can be analyzed and responded to accordingly.
Follow these steps to mitigate input filtering weakness that Salt Labs was able to use for an application-layer DoS attack:
- Limit response sizes — Do not allow users to control the size of data sets in API responses by specifying values in API request parameters. Set these restrictions statically in the back end, based on your complete architecture to avoid bottlenecks or availability issues.
- Never rely on client-side filtering — If you want to provide users the ability to control or filter data, ensure that values in API request parameters fall within reasonable thresholds by filtering requests accordingly. Minimums and maximums will vary based on your design and architecture. As an example, if you’ve designed your APIs to return 100 records per page, do not allow the user to fetch more than that in a single request.
- Use dynamic rate limiting — Restrict data set sizes and API responses based on your available back-end computing power or network throughput.
Lessons Learned
Salt Labs researchers examined the online services platform of a large financial institution and uncovered a number of APIs with severe vulnerabilities. These vulnerabilities exposed customers as well as partner financial institutions to significant security risk, since the APIs provide access to sensitive financial data that also falls under regulatory control. Further, these API security gaps gave rise to concerns over account integrity and service availability.
The importance of authentication and authorization as part of API access control cannot be overstated. Attacks against access control mechanisms, particularly BOLA and BFLA, continue to plague organizations and their APIs. While 2FA can be a powerful enhancement for authentication, it is also prone to misconfiguration, which can translate into minimal added protection. For APIs implemented with resource and rate limits that are overly lax or overly restrictive, availability problems inevitably surface. All of these types of flaws feature prominently in the OWASP API Security Top 10 for good reason. API security problems are difficult to protect against with existing security tooling, and modern application development trends for rapid release and running at scale further challenge security initiatives.
The potential business and privacy impacts from these API security issues are broad. Realistically, many API security issues result from the complexity of third-party integration or misconfiguration, these days referred to simply as the digital supply chain. API issues can seem simple at first glance, and taken in isolation, misconfigurations or gaps in API implementations can seem easy to pin on development teams. However, many API flaws cannot be discovered in pre-production or static testing, and plenty of Fortune 500 organizations with sizable, mature, and well-funded application development and application security teams make similar API security mistakes.
The Salt Labs research into these API vulnerabilities highlight that many API security gaps are preventable. However, a lot of organizations misallocate security tooling budget or put too much confidence in traditional security approaches. Communication breakdowns between IT and security teams are also a common contributing factor, particularly as organizations attempt to scale and automate. No organization has the time or manpower to keep ahead of and verify all API and application changes without the aid of machine assistance. Traditional approaches such as vendor attestations, periodic penetration testing, application scanning, and traditional runtime protections will also leave organizations vulnerable to API security gaps.
Salt Labs provides this detailed vulnerability research and mitigation recommendations as part of our continued leadership in API security education. Any organization that is building or integrating APIs must ensure they have a full lifecycle approach to API security and dedicated API security tooling to be better equipped to find and address the broad spectrum of API security issues.
To learn more about how Salt can help defend your organization from API risks, you can connect with a rep or schedule a personalized demo.