Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/espn.py (Python)

Code before:
                    'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange'
                })['access_token']

            assertion = self._call_bamgrid_api(
                'accounts/grant', video_id, payload={'id_token': cookie.value.split('|')[1]},
                headers={
                    'Authorization': token,
                    'Content-Type': 'application/json; charset=UTF-8'
                })['assertion']

            token = self._call_bamgrid_api(
                'token', video_id, payload={
                    'subject_token': assertion,
                    'subject_token_type': 'urn:bamtech:params:oauth:token-type:account',
                    'platform': 'android',
                    'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange'
                })['access_token']

            playback = self._download_json(
                video_data['videoHref'].format(scenario='browser~ssai'), video_id,
                headers={
                    'Accept': 'application/vnd.media-service+json; version=5',
                    'Authorization': token
                })

            m3u8_url, headers = playback['stream']['complete'][0]['url'], {'authorization': token}

        # TV Provider required
        else:
            resource = self._get_mvpd_resource('ESPN', title, video_id, None)
            auth = self._extract_mvpd_auth(url, video_id, 'ESPN', resource).encode()

            asset = self._download_json(
                f'https://watch.auth.api.espn.com/video/auth/media/{video_id}/asset?apikey=uiqlbgzdwuru14v627vdusswb',
                video_id, data=f'adobeToken={urllib.parse.quote_plus(base64.b64encode(auth)).encode()}&drmSupport=HLS')
            m3u8_url, m3u8_headers = asset['stream'], {}

        formats, subtitles = self._extract_m3u8_formats_and_subtitles(m3u8_url, video_id, 'mp4', m3u8_id='hls')
        self._sort_formats(formats)

        return {
            'id': video_id,
            'title': video_data.get('name'),
            'formats': formats,
            'subtitles': subtitles,
            'thumbnail': video_data.get('posterHref')
            'http_headers': headers,
        }


Review comment (security):
```suggestion
            assertion = self._call_bamgrid_api(
                'devices', video_id,
                headers={'Content-Type': 'application/json; charset=UTF-8'},
                payload={
                    'deviceFamily': 'android',
                    'applicationRuntime': 'android',
                    'deviceProfile': 'tv',
                    'attributes': {},
                })['assertion']
            token = self._call_bamgrid_api(
                'token', video_id, payload={
                    'subject_token': assertion,
                    'subject_token_type': 'urn:bamtech:params:oauth:token-type:device',
                    'platform': 'android',
                    'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange'
                })['access_token']

            assertion = self._call_bamgrid_api(
                'accounts/grant', video_id, payload={'id_token': cookie.value.split('|')[1]},
                headers={
                    'Authorization': token,
                    'Content-Type': 'application/json; charset=UTF-8'
                })['assertion']
            token = self._call_bamgrid_api(
                'token', video_id, payload={
                    'subject_token': assertion,
                    'subject_token_type': 'urn:bamtech:params:oauth:token-type:account',
                    'platform': 'android',
                    'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange'
                })['access_token']

            playback = self._download_json(
                video_data['videoHref'].format(scenario='browser~ssai'), video_id,
                headers={
                    'Accept': 'application/vnd.media-service+json; version=5',
                    'Authorization': token
                })
            m3u8_url, headers = playback['stream']['complete'][0]['url'], {'authorization': token}
```

Code after:
                })['access_token']

            assertion = self._call_bamgrid_api(
                'accounts/grant', video_id, payload={'id_token': cookie.value.split('|')[1]},
                headers={
                    'Authorization': token,
                    'Content-Type': 'application/json; charset=UTF-8'
                })['assertion']
            token = self._call_bamgrid_api(
                'token', video_id, payload={
                    'subject_token': assertion,
                    'subject_token_type': 'urn:bamtech:params:oauth:token-type:account',
                    'platform': 'android',
                    'grant_type': 'urn:ietf:params:oauth:grant-type:token-exchange'
                })['access_token']

            playback = self._download_json(
                video_data['videoHref'].format(scenario='browser~ssai'), video_id,
                headers={
                    'Accept': 'application/vnd.media-service+json; version=5',
                    'Authorization': token
                })
            m3u8_url, headers = playback['stream']['complete'][0]['url'], {'authorization': token}

        # TV Provider required
        else:
            resource = self._get_mvpd_resource('ESPN', video_data['name'], video_id, None)
            auth = self._extract_mvpd_auth(url, video_id, 'ESPN', resource).encode()

            asset = self._download_json(
                f'https://watch.auth.api.espn.com/video/auth/media/{video_id}/asset?apikey=uiqlbgzdwuru14v627vdusswb',
                video_id, data=f'adobeToken={urllib.parse.quote_plus(base64.b64encode(auth))}&drmSupport=HLS'.encode())
            m3u8_url, headers = asset['stream'], {}

        formats, subtitles = self._extract_m3u8_formats_and_subtitles(m3u8_url, video_id, 'mp4', m3u8_id='hls')
        self._sort_formats(formats)

        return {
            'id': video_id,
            'title': video_data.get('name'),
            'formats': formats,
            'subtitles': subtitles,
            'thumbnail': video_data.get('posterHref'),
            'http_headers': headers,
        }