This article helps StackPath SecureCDN customers prevent hotlinking, a form of bandwidth leeching, by applying a secure token on content served from the StackPath SecureCDN.
Hotlinking is a form of bandwidth leeching occurs when a website directly links to files on another website.
For example, an image displayed on a website should have HTML that looks something similar to:
<img src="images/myimage.jpg" height="200" width="500">
The above image is being pulled from the images folder on same server the website is located on.
In contrast, hotlinked images are being displayed on a website, but being loaded from a completely different website. An example of this HTML would look like this:
<img src="https://differentwebsite.com/images/myimage.jpg" height="200" width="500">
StackPath provides a way to prevent hotlinking by applying a secure token on each CDN links in order to take it off after a certain amount of time. After applying this token bandwidth leechers will receive 403 Forbidden error.
Below we will outline the process of setting up the StackPath Secure Token with WordPress using the CDN Linker plugin.
-
Go to Sites and click Manage to the right of the site you wish to enable the Secure Token on.
- In the left-hand nav click Security
-
Enable the Secure Token and define your secret in provided field under the siteSecurity settings:
Now, we need to edit two files within the CDN Linker folder.
- ossdl-cdn-off-linker/wp-cdn-linker.php contains the main configuration for CDN Linker
- ossdl-cdn-off-linker/cdn-linker-base.php contains all rewrite logic
Next, we will add a text box where token will be placed:
- Open ossdl-cdn-off-linker/wp-cdn-linker.php and add HTML tags that will display the label and text field with a notification text:
<label for="ossdl_off_cdn_url">SECURE TOKEN</label> <input type="text" name="ossdl_off_token" size="64" value="<?php echo(get_option('ossdl_off_token')); ?>" /> <span>USE THIS OPTION ONLY IF YOU HAVE SECURE TOKEN ENABLED</span>
-
This code above will display something similar to this image on the CDN Linker configuration page.
- Register option – set activate action:
function ossdl_off_activate() {add_option('ossdl_off_cdn_url', get_option('siteurl')); add_option('ossdl_off_include_dirs', 'wp-content,wp-includes'); add_option('ossdl_off_exclude', '.php'); add_option('ossdl_off_rootrelative', ''); add_option('ossdl_off_www_is_optional', ''); add_option('ossdl_off_disable_cdnuris_if_https', '1'); add_option('ossdl_off_token', ''); }
- Set the deactivate action:
function ossdl_off_deactivate() {delete_option('ossdl_off_cdn_url'); delete_option('ossdl_off_include_dirs'); delete_option('ossdl_off_exclude'); delete_option('ossdl_off_rootrelative'); delete_option('ossdl_off_www_is_optional'); delete_option('ossdl_off_disable_cdnuris_if_https'); delete_option('ossdl_off_token'); }
- Set the update action:
function ossdl_off_options() {if (!empty($_POST) && check_admin_referer('save-options', 'ossdl-nonce')) {update_option('ossdl_off_cdn_url', $_POST['ossdl_off_cdn_url']); update_option('ossdl_off_token', $_POST['ossdl_off_token']); … }
- Open ossdl-cdn-off-linker/cdn-linker-base.php and create function called, for example, “sec”:
function sec($rel){$secret = get_option('ossdl_off_token'); //Get token value from text field in settings section $path = $rel; $expire = time() + 3600; //One day validity $md5 = base64_encode(md5($secret . $path . $expire, true)); $md5 = strtr($md5, '+/', '-_'); $md5 = str_replace('=', '', $md5); $url = "{$path}?st={$md5}&e={$expire}"; }
- Under function “rewrite_single” find:
return str_replace($blog_url, $this->cdn_url->get_for($match[0]), $match[0]);
- and replace it with:
if(get_option('ossdl_off_token') != ""){$relative1 = str_replace($this->cdn_url->get_for($match[0]), '', $match[0]); $relative2 = sec($relative1); $abs = str_replace($blog_url, '', $match[0]); $abs = sec($abs); return $this->cdn_url->get_for($match[0]) . $abs; } else{return str_replace($blog_url, $this->cdn_url->get_for($match[0]), $match[0]); }
- Open ossdl-cdn-off-linker/cdn-linker-base.php and create function called, for example, “sec”:
- Explanation:
if ossdl_off_token option is not set (text field contains token value), call “sec” function and pass uri to it for secure string composition. If ossdl_off_token is empty (token not set), simply rewrite the url by predefined CDN url. The resulting source code portion is :
<link rel='stylesheet' id='dashicons-css' href='http://site.company.stackpathdns.com/wp-includes/css/dashicons.min.css?st=RiIb3samLXPHiuMd30U_Dw&e=1398811628' type='text/css' media='all' /> <link rel='stylesheet' id='admin-bar-css' href='http://site.company.stackpathdns.com/wp-includes/css/admin-bar.min.css?st=RoOgowtm2Fjyxa8yhfzfsQ&e=1398811628' type='text/css' media='all' /> <link rel='stylesheet' id='genericons-css' href='http://site.company.stackpathdns.com/wp-content/themes/twentyfourteen/genericons/genericons.css?st=IJBVawC0fuzC9cSov2FMjA&e=1398811628' type='text/css' media='all' /> <link rel='stylesheet' id='twentyfourteen-style-css' href='http://site.company.stackpathdns.com/wp-content/themes/twentyfourteen/style.css?st=9P2LcL8cBUz7JbZiBiwslg&e=1398811628' type='text/css' media='all' />
-
Let's take a look at what the response looks like with and without tokens.
- With a regular token query string:
curl -I "http://site.company.stackpathdns.com/wp-content/themes/twentyfourteen/genericons/genericons.css?st=IJBVawC0fuzC9cSov2FMjA&e=1398811628"HTTP/1.1 200 OK Date: Tue, 29 Apr 2014 21:51:29 GMT Content-Type: text/css Content-Length: 22680 Connection: keep-alive Last-Modified: Tue, 12 Nov 2013 18:38:10 GMT Pragma: public Cache-Control: public, must-revalidate, proxy-revalidate Cache-Control: public, max-age=604800 Expires: Tue, 06 May 2014 21:51:26 GMT Server: NetDNA-cache/2.2 X-Cache: HIT Accept-Ranges: bytes
- Without a token:
curl -I http://site.company.stackpathdns.com/wp-content/themes/twentyfourteen/genericons/genericons.css HTTP/1.1 403 Forbidden Date: Tue, 29 Apr 2014 21:53:49 GMT Content-Type: text/html Content-Length: 169 Connection: keep-alive Server: NetDNA-cache/2.2
- With a regular token query string:
To ensure you implemented StackPath SecureCDN correctly, you can view the source code of any page to confirm that the CDN domain is being used for static assets instead of your origin domain. You can also use tools like Pingdom and WebPageTest that can give you more detailed reports on your CDN implementation status.