Checkmarx Research: SoundCloud API Security Advisory

.tbl20200211 td{border:1px solid black;} Recently, the Checkmarx Security Research team investigated the online music platform SoundCloud. According to their website, “As the world’s largest music and audio platform, SoundCloud lets people discover and enjoy the greatest selection of music from the most diverse creator community on earth.” This investigation was part of a broader research conducted by Checkmarx, in order to examine the state of API Security in leading online platforms. Multiple vulnerabilities were discovered in SoundCloud’s API endpoints, including:
  • Broken Authentication & User Enumeration - may lead to account takeover
  • Lack of Resources Limiting & Rate Limiting – may lead to denial of service
  • Security Misconfiguration & Improper Input Validation - may lead to exploitation of service
The Checkmarx research team responsibly disclosed the information found in this report to the SoundCloud security team, which were very cooperative, prioritizing patching these issues immediately.

Broken Authentication (CVSS 7.5)

CVSS Score: 7.5 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N The /sign-in/password endpoint of does not implement proper account lockout based on failed authentication attempts. It solely relies on rate limiting which can be evaded using several combinations of use_agent, device_id, and signature. Based on the endpoint responses, it is possible to automate brute-force attacks, such as Credential Stuffing, to obtain a valid access_token. Note that User Enumeration weakness included in this report can be used to get a valid user account identifier (Figure 1). Figure 1: Credential Stuffing sessionCombining these two issues, attackers might be able to take-over user accounts.


  • Implement account lockout mechanism based on failed authentication attempts.
  • Authentication endpoints should implement more-restrictive rate limiting policies.


User Enumeration (CVSS 5.3)

CVSS Score: 5.3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N Both /sign-in/identifier and /users/password_reset endpoints of can be used to enumerate user accounts. In both cases, the endpoints provide different responses depending on whether the requested user account identifier exists or not (Figures 2 and 3). Figure 2: /sign-in/identifier request/response Figure 3: /users/password_reset request/responseNote that this issue can be combined with the Broken Authentication weakness included in this report to take-over user accounts.


  • Avoid exposing the /sign-in/identifier endpoint, combining the sign-in in a single HTTP request with a generic error message for failed attempts.
  • Although /sign-in/password endpoint looks like a good candidate, since it includes both the identifier and password properties, it does not fulfill the generic error message requirement.


Lack of Resources Limiting (CVSS 5.3)

CVSS Score: 5.3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L The /tracks endpoint of does not implement proper resources limiting, returning an arbitrary amount of data based on given query string ids parameter. Since no validation is performed regarding the number of tracks IDs in the ids list, it is possible to manipulate the list to retrieve an arbitrary number of tracks in a single request. The request issued by the SoundCloud WebApp includes 16 track IDs in the ids query string parameter, but by manipulating the list, we were able to retrieve up to 689 tracks in a single request (Figure 4). Figure 4: Retrieving 689 tracks in a single requestThe table below compares response’ sizes and times:  
# tracks response length (bytes) response time (s)
16 41701 0,233
689 1947564 2,074
  Although there’s no specification about the maximum length for a requested path, it is usually enforced by the HTTP server. For an arbitrary long path, the API returns a 413 Request Entity Too Large error (Figure 5) Figure 5: 413 Request Entity Too Large errorAlso note that this endpoint does not required authentication/authorization (Figure 6). Figure 6: No Authorization headerThis can be used to perpetrate a Distributed Denial of Service (DDoS) attack: using a specially crafted list of track IDs to maximize the response size, and issuing requests from several sources at the same time to deplete resources in the application layer will make the target’s system services unavailable.


To mitigate this issue, the affected endpoints should:
  1. define a max allowed number of track IDs in the ids parameter;
  2. validate the ids list length against the established limit on every single request;
  3. limit the number of tracks to be fetched and returned in a single request;
  4. if needed, implement pagination.


Lack of Resources & Rate Limiting

The /me/play-history/tracks endpoint appears to not enforce rate limiting, allowing a large number of POST requests. The table below highlights the number of requests made from a single machine/IP address. We considered “Successful Requests” those whose HTTP response code was 204.  
# Requests Successful Rate Duration (s)
1520 100% 21s
  Despite the fact we were able to perform 1520 successful requests, a GET request to the same endpoint returns 489 tracks only (Figure 7). Figure 7: GET /me/play-history/tracks?limit=500Either using the next_href URL in the response, or by manipulating the limit query string parameter, we always get the same 489 tracks (Figure 8). Figure 8: GET /me/play-history/tracks?limit=1000Note that changing the query string parameter limit to 1000, we get a slightly different response: now next_href is null. Although we were not able to confirm it, this may highlight a lack of a resources limiting issue. The lack of rate limiting may compromise the system availability, making it vulnerable to DoS attacks. From a business perspective, not limiting the amount of requests to this endpoint may compromise the data integrity, since it may create biased tracks-statistics.


  • Define appropriate rate limits.
  • Verify whether limit is validated before retrieving the tracks to be returned.


Security Misconfiguration

Issuing a PUT request to /users/{user_id} with an already used permalink returns an unhandled Java exception (java.lang.IllegalStateException), which exposes information about the components/versions in use (Figure 9). Figure 9: Java ExceptionThe table below lists exposed information together with latest versions:  
Software Used Version Latest Version
Phusion Passenger 6.0.4 6.0.4
Nginx 1.17.3 1.17.5
  Attackers may take advantage of this information to exploit the system.


Although no security issues or exploits are known at the time for these software/versions, you’re advised to:
  1. Gracefully handle the exception returning an appropriate HTTP response;
  2. Update Nginx to the latest version, since it includes several bug fixes.


Improper Input Validation

The /tracks/{track_urn} endpoint of does not properly validate and enforce the length of the following properties: description, title, and genre (Figure 10). The table below compares the SoundCloud WebApp and the API length limits:  
Property WebApp API
description 4000 65650
title 100 255
genre 100 255
  Figure 10: 65650 characters long descriptionFor description longer than 65650 characters, the server returns 500 Internal Server Error (Figure 11). Figure 11: Error setting descriptionFor both title (Figure 12) and genre (Figure 13), strings longer than 255 characters are truncated. Figure 12: 256 characters long title Figure 13: 256 characters long genreIssuing requests directly to the API server puts the attacker in control of additional 61960 bytes (total of 66160 bytes).


The API endpoint should not rely on the SoundCloud WebApp to perform the input validation. Instead it should perform input validation using a centralized routine, using the same validation rules as the WebApp.


Summary of Disclosure and Events

When the vulnerabilities were first discovered, and confirmed, the Checkmarx research team responsibly notified SoundCloud of their findings.

SoundCloud’s Response

“At SoundCloud, the security of our users' accounts is extremely important to us. We are always looking for ways to enhance the security of our platform for our users. We appreciate Checkmarx reaching out to discuss their findings.”

Timeline of Disclosure

  • 11-Nov-2019: Full report sent to SoundCloud’s Security Engineering
  • 11-Nov-2019: Report receipt confirmed by SoundCloud’s Security Engineering
  • 13-Dec-2019: SoundCloud Fix - Prevent information leakage in error responses
  • 30-Jan-2020: SoundCloud Fix - Improve rate-limiting of password brute-force attempts
Note: The release of this publication was coordinated with SoundCloud after their confirmation of a fix being released.

Final Words

The professionalism shown by SoundCloud does not go unnoticed. They were a pleasure to work with due to their responsiveness, thoroughness, and timeliness. This type of research activity is part of the Checkmarx Security Research Team’s ongoing efforts to drive the necessary changes in software security practices among organizations who offer online services in an effort to improve security for everyone overall.
Skip to content