How to secure CDN content with secure tokens

Secure tokens are among the most effective tools to protect your images, videos and downloads from unauthorized access and hot linking. Once enabled, the fature will cause PUSHR to validate every request from every visitor and serve the requested content only to those who can provide a valid access token. 

Tokens can be generated to protect files and entire directories. 

How does it work

Your website, service or app generates a unique token to authenticate the request for a file or directory. The IP of the visitor, the path to the content, the expiration time of the token and a secret passphrase are used. The successfully generated token hash and it's expiration time are then inserted into the URL to the content that is being protected. The path to the file or directory is then appended as a query string to the resulting URL. When PUSHR receives the request it attempts to recreate the token based on the prvovided information. If the passed hash matches the recreated hash the visitor is allowed to retrieve the requested file. If the token is not valid, is expired, or is missing, an error HTTP 403 is returned and access is blocked. 

File token vs. Title token

Based on the type of content that is being protected, PUSHR distinguishes two types of tokens. For single files like mp4 videos for example, the entire path to the protected video can be used. This way the token would be valid only for the given file, but will be invalid for other files in the same directory. We refer to this as a file token, and it is how you'd usually want to protect most of your files. 


However, some content types like HLS video on demand consist of multiple video fragments (.ts files) and one or more manifest files (.m3u8). These usually reside in the same directory, or in subdirectories of the main directory. If a file token is generated for the master manifest file, it will only work for it but not for the .ts and other .m3u8 files linked inside. This would cause the HLS video to be blocked even for authorized viewers. To avoid this and still protect the HLS video, only the path to the parent directory should be used in the token. This is refered to as a title token.

Generating tokens

The PHP code below generates a file token for a file named video.mp4, which is accesible from the following CDN URL:

https://cdn_hostname/vod/1875/video.mp4

The token is set to be valid for one hour after which it will no longer work. 

$secret = '58749ca2d6029a1303b37e055075904fafe49';
$host = 'https://cdn_hostname';
$path = '/vod/1875/'; 
$file = 'video.mp4'; 
$ip = $_SERVER['REMOTE_ADDR']; 
$exp = time()+3600; 
$md5 = base64_encode(md5($secret.$path.$ip.$exp, true)); 
$md5 = strtr($md5, '+/', '-_'); 
$md5 = str_replace('=', '', $md5);
  
$link = $host."/".$md5."/".$exp.$path.$file."?pushr=/vod/1875/video.mp4";

The resulting link to video.mp4 is now held inside the $link variable. It looks like this:

https://cdn_hostname/3HVsqx08yT9Z/1605534932/vod/1875/video.mp4?pushr=/vod/1875/video.mp4

In the URL above, the newly generated token is included first:

3HVsqx08yT9Z

The expiration timestmap is included second. It is in unix epoch format:

1605534932

Appended as query string is the path that we want PUSHR to protect:

?pushr=/vod/1875/video.mp4

The file video.mp4 will be protected by the token, and all other files in the /vod/1875/ directory will not be accessible unless a file token is generated  individually for each one of them. 

To generate a title token that would work with HLS video content, we need to omit the file from the path. This way a single token will be securing the whole directory. The code would change as the the query string will only include the path up to the parent directory:

$secret = '58749ca2d6029a1303b37e055075904fafe49';
$host = 'https://cdn_hostname';
$path = '/vod/1875/'; 
$file = 'playlist.m3u8';
$ip = $_SERVER['REMOTE_ADDR']; 
$exp = time()+3600; 
$md5 = base64_encode(md5($secret.$path.$ip.$exp, true)); 
$md5 = strtr($md5, '+/', '-_'); 
$md5 = str_replace('=', '', $md5);
  
$link = $host."/".$md5."/".$exp.$path.$file."?pushr=/vod/1875/";

 The resulting link to the protected HLS video would then be:

https://cdn_hostname/3HVsqx08yT9Z/1605534932/vod/1875/playlist.m3u8?pushr=/vod/1875/

 Note: Title tokens require relative links inside manifest files.