.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
api-v2.soundcloud.com
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.
Recommendation
- Implement account lockout mechanism based on failed authentication attempts.
- Authentication endpoints should implement more-restrictive rate limiting policies.
References
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
api-v2.soundcloud.com
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.
Recommendation
- 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.
References
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
api-v2.soundcloud.com
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.
Recommendation
To mitigate this issue, the affected endpoints should:
- define a max allowed number of track IDs in the
ids
parameter; - validate the
ids
list length against the established limit on every single request; - limit the number of tracks to be fetched and returned in a single request;
- if needed, implement pagination.
References
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.
Recommendation
- Define appropriate rate limits.
- Verify whether
limit
is validated before retrieving the tracks to be returned.
References
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.
Recommendation
Although no security issues or exploits are known at the time for these software/versions, you’re advised to:
- Gracefully handle the exception returning an appropriate HTTP response;
- Update Nginx to the latest version, since it includes several bug fixes.
References
Improper Input Validation
The
/tracks/{track_urn}
endpoint of
api-v2.soundcloud.com
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
genre
Issuing requests directly to the API server puts the attacker in control of additional 61960 bytes (total of 66160 bytes).
Recommendation
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.
References
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.