NOWSECURE CONNECT 2022 CONFERENCE - REGISTER FOR REPLAYS!

NowSecure Connect — THE mobile AppSec + AppDev community online event — returns with new content and the latest training. Join the world’s brightest innovators, practitioners, community leaders, and industry influencers online for in-depth training, discussions, strategy sessions, CTF and more. Gain access to keynotes, exclusive breakouts, expert panels, on-demand sessions, plus an interactive peer-to-peer community. #NSConnect22 is your source for cutting-edge mobile AppDev, mobile AppSec and mobile DevSecOps insight. Register for replays!

NOWSECURE CONNECT 2022 CONFERENCE - REGISTER FOR REPLAYS! NOWSECURE CONNECT 2022 CONFERENCE - REGISTER FOR REPLAYS! Show More
magnifying glass icon

It’s Not About the Bike: Vulnerabilities in Peloton’s Mobile Apps and APIs

Posted by

Austin Emmitt

Mobile Security Researcher
Austin Emmitt is a Mobile Security Researcher at Nowsecure. He enjoys bugfinding but not bughunting so he spends most of his time automating security tasks.
Peloton Bike

Peloton has become perhaps the most well known and successful fitness equipment company today. It makes several connected fitness products including popular Internet-connected stationary exercise bikes and publishes an impressive library of live and on-demand course content. The class platform offers an immersive experience that makes exercise fun and competitive.

But this blog post isn’t about exercise because I’m not good at that. This post explores my discovery of security vulnerabilities in Peloton mobile apps and the company’s web APIs, something I’m much better at as a mobile security researcher for NowSecure.

This blog post covers Peloton security, the vulnerabilities that have been communicated to the vendor in accordance with its Responsible Disclosure program and the remediation that Peloton has completed and deployed to its customers and equipment around the world. Peloton has been excellent to work with on these issues, responding promptly and constructively to the disclosed vulnerabilities. Every vulnerability listed in this post has been confirmed to be fixed and Peloton has stated that users don’t need to take any action because their systems have already been updated.

Disclosure Summary

The following security and privacy issues can be found in this disclosure:

  1. Peloton user exposure to account takeover 
  2. Peloton user exposure to phishing attack
  3. Remote access to Peloton users’ private personal information 
  4. Ability to remotely change device name and serial number

Sadly we frequently find issues like this across thousands of mobile apps in our mobile security research and mobile app pen testing. With mobile breaches rising year after year our team even built a mobile risk tracker to help people understand. While these Peloton security and privacy vulnerabilities described in this post are serious issues that should concern any user, the good news is they have been resolved.

Peloton Security Collaboration

Peloton collaborated with NowSecure on these issues in a professional manner with swift responses and fixes and the team requested information when necessary. Security researchers who want to learn more about the Peloton Coordinated Vulnerability Disclosure (CVD) program can visit here. Media inquiries can contact [email protected].

“Collaborations with security researchers and analysts play a key role in how we keep the Peloton community secure,” says Jorge Lopez, director of global security incident response & threat intelligence for Peloton. “We’d like to thank Austin Emmitt and the NowSecure team for their partnership and for working hand-in-hand with us from the minute they reported the vulnerabilities. Together we were able to quickly address the issues they identified and validate the fixes. Our investigation revealed no evidence that sensitive information was exposed and Peloton Members do not need to take any action as a result of this disclosure.”

While I’m a full-time security researcher, my company NowSecure has for more than a decade worked with mobile developers and security teams around the world, providing automated security testing tools, pen tester toolstraining and pen testing services to help them grow their mobile security programs. Also, my fellow researchers here at NowSecure have created the popular open-source security tools, Frida and Radare.

What follows are the technical details of my security research activities with Peloton, the vulnerabilities found, the quality interaction and fast resolutions.

Disclosure Timeline

  • 9/22/21 – Initial Disclosure to Peloton containing
    • Web API Security Vulnerabilities
    • iOS App Issues
      • Disabled iOS native App Transport Security (ATS) Protection Can Lead to Insecure Network Connections. CVSS 6.1 – Medium.
      • Allowing Third-Party Keyboards Potentially Exposes User Input. CVSS 5.5 – Medium.
  • 9/27/21 – Response email from Peloton Product Security asking for more details on specific issues.
  • 9/29/21 – Email from Peloton Product Security confirming the XSS and Information Disclosure issues, additionally agreeing with my scoring of these issues to be CVSS 8.8.
  • 10/20/21 – Email from Peloton Product Security announcing a fix rolling out for the XSS and iOS app issues. The information disclosure was not yet fixed.
  • 10/26/21 – We confirmed that the XSS issue had been resolved and communicated this to Peloton.
  • 11/5/21 – We emailed the Peloton Product Security team about changes they have made to the device endpoint to fix the remaining information disclosure issue. We also confirmed with them that the iOS app issues have been fixed as well.
  • 12/8/21 – Public disclosure of our findings.

We’d like to thank Austin Emmitt and the NowSecure team for their partnership and for working hand in hand with us from the minute they reported the vulnerabilities. – Jorge Lopez, Director, Global Security Incident Response u0026 Threat Intelligence, Peloton

The Peloton Platforms

Users can access Peloton class content from a number of platforms, including the web, Android and iPhone mobile apps, and the apps running on the tablets mounted to Peloton bikes and treadmills. On the web users can access classes and account information at members.onepeloton.com. This site, the apps and the tablets built into the equipment all communicate with the API at api.onepeloton.com. For instance, information about a specific class session can be found at https://api.onepeloton.com/api/peloton/f6888dccf5554a2f92cfc376eda1721c. It’s not surprising that the apps on Android and on the bike itself share the same backend APIs because the bike tablet also runs Android and shares much of the same client-side code as the mobile app in the Google Play Store. At the time of publication, the lower cost Bike model (as opposed to the Bike+) runs Android 7.0.

The Peloton Bike Tablet

Though it is not immediately obvious, the tablet attached to the Bike runs Android. This is quickly verified by tapping ‘Settings’ in the upper right hand corner after the device has started and the profile login screen is shown. By going to the ‘About’ section we can find the build information, and by tapping the ‘Build’ number 7 times we can access the developer options and enable Android Debug Bridge (adb), a command-line tool for interacting with Android devices. Any app can be installed with adb install including a new launcher, like the standard Pixel Launcher.

The hardware on the bike is also a pretty standard Mediatek SoC, the mt8173. This can be seen in this snippet of output from getprop

[ro.mediatek.chip_ver]: [S01]
[ro.mediatek.platform]: [MT8173]
[ro.mediatek.project.path]: [device/peloton/qbert]
[ro.mediatek.version.branch]: [alps-mp-n0.mp12]
[ro.mediatek.version.release]: [alps-mp-n0.mp12-V1.32_qt8173.tb.ui7.n_P25]
[ro.mediatek.version.sdk]: [4]

Additionally adb access allows us to retrieve the output of logcat, which among other things gives us a glimpse into the bike’s communications with the backend:

11-24 22:18:15.743 16605 21812 I okhttp.OkHttpClient: --> GET https://api.onepeloton.com/api/me
11-24 22:18:15.916 16605 21808 I okhttp.OkHttpClient: <-- 200 https://gql-graphql-gateway.prod.k8s.onepeloton.com/graphql (383ms, unknown-length body)
11-24 22:18:16.345 16605 21812 I okhttp.OkHttpClient: <-- 200 https://api.onepeloton.com/api/me (601ms, unknown-length body)
11-24 22:18:16.373 16605 21808 I okhttp.OkHttpClient: --> GET https://api.onepeloton.com/api/schedule/events?start=1637730000&end=1638939600&apply_platform_filter=false
11-24 22:18:16.387 16605 21819 I okhttp.OkHttpClient: --> GET https://api.onepeloton.com/api/schedule/events?start=1637730000&end=1638939600&apply_platform_filter=false
11-24 22:18:16.425 16605 21820 I okhttp.OkHttpClient: --> POST https://api.onepeloton.com/stats/token (0-byte body)
11-24 22:18:16.453 16605 21783 I okhttp.OkHttpClient: --> GET https://api.onepeloton.com/api/user/e262e252fb3643fb8c65e0b8ea049bb/contract_agreements
11-24 22:18:16.488 16605 21791 I okhttp.OkHttpClient: --> GET https://api.onepeloton.com/api/user/e262e252fb3643fb8c65e0b8ea0469bb/feed?limit=200
11-24 22:18:16.525 16605 21824 I okhttp.OkHttpClient: --> POST https://api.onepeloton.com/api/started_client_session (0-byte body)
11-24 22:18:16.541 16605 21823 I okhttp.OkHttpClient: --> POST https://gql-graphql-gateway.prod.k8s.onepeloton.com/graphql (1338-byte body)
11-24 22:18:16.556 16605 21814 I okhttp.OkHttpClient: --> PUT https://api.onepeloton.com/api/subscription/<my censored subscription id>/serial (70-byte body)
11-24 22:18:16.643 16605 21823 I okhttp.OkHttpClient: <-- HTTP FAILED: java.io.IOException: Canceled
1311-24 22:18:16.752 16605 21808 I okhttp.OkHttpClient: <-- 200 https://api.onepeloton.com/api/schedule/events?start=1637730000&end=1638939600&apply_platform_filter=false (378ms, 11-byte body)

These log outputs allowed us to discover some very important endpoints including:

  • https://api.onepeloton.com/api/me – information about the current logged in user.
  • https://api.onepeloton.com/api/user/e262e252fb3643fb8c65e0b8ea0469bb – information about any user by id (or by username, you can use it instead of the id here).
  • https://api.onepeloton.com/api/subscription/<my censored subscription id> – information about the subscription, requires authentication.

The log output also can contain reference to the endpoint with the information disclosure vulnerability described above.

Information Disclosure from api.onepeloton.com

During the process of logging into a Peloton account on the Bike, the com.peloton.activity app first checks that the Peloton Bike from which a user logs in is the one already associated with that user’s subscription. It does this by requesting the endpoint https://api.onepeloton.com/api/device/<device id>. This endpoint gives information about Peloton devices, including the name, serial, subscription id etc (at least it used to, it no longer returns such info as part of the fix). It was also possible to pass the joins parameter to the endpoint to include information for the subscription tied to the bike with https://api.onepeloton.com/api/device/<device id>?joins=subscription%2Csubscription.user. This included the cost of the OnePeloton subscription, the date of last payment, and other potentially sensitive information. Additionally the name and serial number of the device could be changed with a PUT request to https://api.onepeloton.com/api/device/<device id>/name (and /tablet_serial_number respectively). Here’s the problem: no authentication whatsoever was needed for any of the above requests. As noted above, this endpoint is accessed in the login flow on the device. Specifically, it is accessed before the user has logged in, so it could not be part of the normal user session authenticated communication. This meant it was possible to get sensitive information about any user, their subscription, as well as change the name of their Peloton Bike, without needing anything other than their device id.  A script like this one could change any device name to anything you would like.

import requests
device_id = "<a valid device id>"
endpoint = "https://api.onepeloton.com/api/device/" + device_id + "/name"
response = requests.put(endpoint, data='{"name":"<put anything here>"}')
print(response.text)

To be clear the device ID is not a value that it is possible to guess, and it is also not leaked in any unauthorized endpoint that I could find. However it was presented in the About screen of the main Peloton app,  so any attacker with brief physical access to the Bike could obtain indefinite access to information about a user’s device and subscription. This vulnerability could be made worse if there were a way to discover the device ID or get the user information through XSS.

XSS on members.onepeloton.com

As part of the login process on members.onepeloton.com a successful login forwarded the user to https://members.onepeloton.com/callback/?redirectUrl=… , which in turn redirected them to the URL found (base64 encoded) in the redirectUrl parameter. This led to both an open redirect vulnerability, and more importantly a reflected XSS vulnerability. By using the javascript:… URI scheme an attacker could create a malicious link that when clicked would run the attackers JS in the context of members.onepeloton.com.

Peloton Security vulnerability
The reflected xss vulnerability with the payload javascript:alert(document.cookie)

The base64 encoding here is a real gift to the attacker as it prevents the suspicious payload from being blocked by cloudflare. This XSS could be leveraged to obtain full account takeover by retrieving the session_id from https://api.onepeloton.com/auth/check_session which also helpfully returns user information, including name, email and phone number if one was provided. The cross-origin settings of api.onepeloton.com permit this request, the response to which could be sent on to a server controlled by the attacker. Setting the cookie peloton_session_id to the discovered session_id value from this endpoint effectively logs the attacker in as the victim. The attacker could then make a PUT request to the /api/user/<user id> endpoint to change the email address associated with the account. Finally by using the “forgot password” feature the attacker could reset the password, taking full control of the account and locking out the original user.

Peloton iOS Mobile App Issues

Using the NowSecure Platform automated mobile application security testing software we were able to discover a number of issues with the Peloton iOS app. One of the simpler and more serious vulnerabilities was the disabling of the iOS native security feature App Transport Security (ATS). This feature ensures that all connections are made over TLS, preventing http://... connections that could leak sensitive information and be subject to interception and manipulation.

Additionally the Peloton iOS mobile app allowed third-party keyboards which could allow malicious installed keyboards to intercept sensitive information entered into the app by the user. In order to prevent the use of third-party keyboards, developers should include

func application(application: UIApplication,
shouldAllowExtensionPointIdentifier extensionPointIdentifier: String) -> Bool {
   return extensionPointIdentifier != UIApplicationKeyboardExtensionPointIdentifier
}

These issues represent simple but important ways that mobile app developers can apply secure coding best practices to improve the overall security and privacy of their mobile applications.

The Fixes

As stated, Peloton quickly remediated each of the issues described above. The XSS vulnerability was completely removed by simply getting rid of the callback endpoint.

The information disclosure in the device endpoint was more complicated to mitigate. As explained above, this endpoint is an important part of the login process on the Peloton Bike which meant that it was not possible to put the endpoint behind proper authentication. However much of the sensitive information has been removed and the endpoint now also requires the device_serial parameter to be passed so two identifiers would need to be known to the attacker. Additionally the /tablet_serial_number endpoint has been deprecated and the /name endpoint requires authentication with the user that is the “owner” of the subscription associated with the device.

Both iOS app vulnerabilities listed here were fixed in a recent update to the app found in the Apple App Store.