All Products
Search
Document Center

Object Storage Service:Hotlink protection

Last Updated:Sep 20, 2023

You can configure a Referer whitelist or a Referer blacklist and specify whether to allow a request with an empty Referer for an Object Storage Service (OSS) bucket to prevent resources in the bucket from unauthorized access. This topic describes how to enable and use hotlink protection.

Usage Notes

  • OSS supports only bucket-level hotlink protection. You cannot configure hotlink protection for objects or directories in a bucket.

  • Only URL-based access (GetObject) and anonymous access are verified based on the hotlink protection configurations.

  • Requests that contain the Authorization header are not verified。

  • By default, if you preview an MP4 object by using a bucket domain name, such as bucketname.oss-cn-zhangjiakou.aliyuncs.com, the browser sends two requests at the same time. One request contains a Referer, and the other request contains an empty Referer. In this case, you must add the bucket domain name to the Referer whitelist and turn on Allow Empty Referer.

  • If you preview a non-MP4 object by using a bucket domain name, such as bucketname.oss-cn-zhangjiakou.aliyuncs.com, you need to only turn on Allow Empty Referer.

  • You can specify the TruncatePath parameter only by calling the PutBucketReferer operation. This parameter specifies whether to truncate all subsequent parts of the URL, including the path.

How it works

OSS determines the source from which a request is sent based on the value of Referer that is included in the request. When a browser sends a request to the web server, Referer is included in the request headers to specify the source from which the request is sent. OSS determines whether to allow the request based on the value of Referer that is included in the request and the Referer whitelist or Referer blacklist that is configured for a specific bucket. If the value of Referer in the request is included in the Referer whitelist, the request is allowed. If the value of Referer in the request is not included in the Referer whitelist or is included in the Referer blacklist, the request is denied.

For example, if the Referer whitelist of a bucket is set to https://10.10.10.10, you may encounter the following scenarios:

  • User A adds an image named test.jpg to the https://10.10.10.10 website. When a user accesses the image on the website, the browser sends a request in which the value of Referer is https://10.10.10.10. OSS allows the request because the value of Referer in the request is included in the Referer whitelist.

  • User B embeds the URL of an image named test.jpg into the https://192.168.0.0 website. When a user accesses the image on the website, the browser sends a request in which the value of Referer is https://192.168.0.0. OSS denies the request because the value of Referer in the request is not included in the Referer whitelist.

Process

After hotlink protection is enabled, OSS determines the source from which a request is sent based on Referer in the request and determines whether to allow the request. The following figure shows the process in detail.

image
  1. Check whether Referer is empty.

    • If Referer is empty, check whether empty Referers are allowed.

      • If empty Referers are allowed, the request is allowed.

      • If empty Referers are not allowed and the Referer whitelist is empty, the request is allowed.

      • If empty Referers are not allowed and the Referer whitelist is not empty, the request is denied.

    • If Referer is not empty, perform Step 2.

  2. Check whether the Referer blacklist is empty.

    • If the Referer blacklist and Referer whitelist are empty, the request is allowed.

    • If the Referer blacklist is empty and the Referer whitelist is not empty, skip Step 3 and perform Step 4.

    • If the Referer blacklist is not empty, perform Step 3.

  3. Traverse the Referer blacklist.

    • If the domain name or IP address is included in the Referer blacklist, the request is denied.

    • If the domain name or IP address is not included in the Referer blacklist, perform Step 4.

  4. Traverse the Referer whitelist.

    • If the domain name or IP address is included in the Referer whitelist, the request is allowed.

    • If the domain name or IP address is not included in the Referer whitelist, the request is denied.

Use the OSS console

  1. Log on to the OSS console.

  2. In the left-side navigation pane, click Buckets. On the Buckets page, find and click the desired bucket.

  3. In the left-side navigation pane, choose Content Security > Hotlink Protection.

  4. On the Hotlink Protection page, turn on Hotlink Protection.

    • In the Referer Whitelist and Referer Blacklist fields, enter domain names or IP addresses.

      Configuration specifications for a Referer whitelist and Referer blacklist

      Specification

      Example

      If Referer is a domain name, HTTP or HTTPS must be included.

      If you set Referer Whitelist or Referer Blacklist to http://www.aliyun.com, addresses that contain the http://www.aliyun.com prefix, such as http://www.aliyun.com/123 and http://www.aliyun.com.cn, can be matched. Addresses that contain the https://www.aliyun.com prefix, such as https://www.aliyun.com/123 and https://www.aliyun.com.cn, cannot be matched.

      You can use an asterisk (*) as a wildcard character to specify zero or multiple characters.

      • If you set Referer Whitelist or Referer Blacklist to *www.example.com, http://www.example.com and https://www.example.com can be matched.

      • If you set Referer Whitelist or Referer Blacklist to *.example.com, http://help.example.com, https://help.example.com, http://www.example.com, and https://www.example.com can be matched.

      You can use a question mark (?) as a wildcard character to specify a character.

      If you set Referer Whitelist or Referer Blacklist to http://www.aliyun?.com, addresses such as http://www.aliyunc.com can be matched.

      Referers support domain names or IP addresses that contain port numbers.

      You can set Referer Whitelist or Referer Blacklist to http://www.example.com:8080 and 10.10.10.10:8080.

      Separate multiple Referers with using carriage returns as line breaks.

      Examples:

      http://www.aliyun.com
      http://www.alibabacloud.com
    • Specify whether to set Allow Empty Referer to Yes to allow a request that contains an empty Referer.

      • Yes: An HTTP or HTTPS request that does not contain a Referer or contains an empty Referer can access objects in the bucket.

      • No: Only an HTTP or HTTPS request that contains allowed Referers can access objects in the bucket.

    • Specify whether to set Truncate QueryString to Yes to allow query strings to be truncated.

      • Yes: Query strings in Referer are truncated. For example, if Referer is set to http://www.example.com/?action=nop, the query string is truncated and http://www.example.com/ is used to match addresses.

      • No: Query strings in Referer are not truncated. For example, if Referer is set to http://www.example.com/?action=nop, http://www.example.com/?action=nop is used to match addresses.

        Rules for a Referer whitelist or a Referer blacklist to match query strings that are not truncated

        Rule

        Description

        Query strings are not decoded.

        If the request URL is http://www.example.com/?job_id=task$01, and http://www.example.com/?job_id=task%2401 is included in the Referer whitelist or Referer blacklist, the request URL does not match the Referer whitelist or Referer blacklist.

        Fields included in query strings are not case-sensitive.

        If the request URL is http://www.examplecom/?ACTION=NOP, and http://www.example.com/?action=nop is included in the Referer whitelist or Referer blacklist, the request URL matches the Referer whitelist or Referer blacklist.

        Fields included in query strings are not parsed.

        If the request URL is http://example.com/?b=c&a=b, and http://example.com/?a=b&b=c is included in the Referer whitelist or Referer blacklist, the request URL does not match the Referer whitelist or Referer blacklist.

  5. Click Save.

Use OSS SDKs

If you specify multiple Referers by using OSS SDKs, separate them with commas (,).

The following sample code provides examples on how to configure hotlink protection for a bucket by using OSS SDKs for common programming languages. For more information about how to configure hotlink protection for a bucket by using OSS SDKs for other programming languages, see Overview.

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.BucketReferer;
import java.util.ArrayList;
import java.util.List;

public class Demo {

    public static void main(String[] args) throws Exception {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";

        // Create an OSSClient instance. 
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            List<String> refererList = new ArrayList<String>();
            // Add Referers to the Referer whitelist. You can use asterisks (*) and question marks (?) as wildcard characters in Referers. 
            refererList.add("http://www.aliyun.com");
            refererList.add("http://www.*.com");
            refererList.add("http://www.?.aliyuncs.com");
            // Configure the Referer whitelist of the bucket. If true is specified, requests with empty Referer fields are allowed. If false is specified, requests with empty Referer fields are not allowed. 
            BucketReferer br = new BucketReferer(true, refererList);
            ossClient.setBucketReferer(bucketName, br);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Model\RefererConfig;

// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
$accessKeyId = "<yourAccessKeyId>";
$accessKeySecret = "<yourAccessKeySecret>";
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";

$refererConfig = new RefererConfig();
// Allow empty Referers. 
$refererConfig->setAllowEmptyReferer(true);
// Add Referers to the Referer whitelist. You can use asterisks (*) and question marks (?) as wildcard characters in Referers. 
$refererConfig->addReferer("example.com");
$refererConfig->addReferer("example.net");
try{
    $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);

    $ossClient->putBucketReferer($bucket, $refererConfig);
} catch(OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}
print(__FUNCTION__ . ": OK" . "\n");
            
const OSS = require('ali-oss')

const client = new OSS({
  // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou. 
  region: 'yourregion',
  // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
  accessKeyId: 'yourAccessKeyId',
  accessKeySecret: 'yourAccessKeySecret',
  // Set yourbucketname to the name of your bucket. 
  bucket: 'yourbucketname'
});

async function putBucketReferer () {
  try {
  const result = await client.putBucketReferer('bucket-name', true, [
    'example.com',
    '*.example.com'
  ]);
  console.log(result);
  } catch (e) {
    console.log(e);
  }
 }

putBucketReferer();
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import BucketReferer
# Obtain access credentials from environment variables. Before you run this sample code, make sure that you have configured environment variables OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET. 
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
# Set yourBucketName to the name of the bucket. 
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'yourBucketName')
# Specify that empty Referer fields are allowed. 
allow_empty_referer = True 
# Specify a Referer whitelist. 
referers = ['http://aliyun.com', 'http://*.aliyuncs.com']
# Specify a Referer blacklist. 
black_referers=['http://example.com', 'http://*.example.com']
# Specify that query strings can be truncated. 
allow_truncate_query_string=True
# Configure hotlink protection. 
bucket.put_bucket_referer(BucketReferer(allow_empty_referer=allow_empty_referer, referers=referers, black_referers=black_referers,allow_truncate_query_string=allow_truncate_query_string))
using Aliyun.OSS;
using Aliyun.OSS.Common;
// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
var endpoint = "yourEndpoint";
// The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
var accessKeyId = "yourAccessKeyId";
var accessKeySecret = "yourAccessKeySecret";
// Specify the name of the bucket. 
var bucketName = "examplebucket";
// Create an OSSClient instance. 
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    var refererList = new List<string>();
    // Add a Referer whitelist. You can use asterisks (*) and question marks (?) as wildcard characters in Referers. 
    refererList.Add(" http://www.aliyun.com");
    refererList.Add(" http://www.*.com");
    refererList.Add(" http://www.?.aliyuncs.com");
    var srq = new SetBucketRefererRequest(bucketName, refererList);
    // Configure the Referer whitelist. 
    client.SetBucketReferer(srq);
    Console.WriteLine("Set bucket:{0} Referer succeeded ", bucketName);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}
PutBucketRefererRequest request = new PutBucketRefererRequest();
request.setBucketName("yourBucketName");
// Add Referers to the Referer whitelist. You can use asterisks (*) and question marks (?) as wildcards in Referers. 
ArrayList<String> referers = new ArrayList<String>();
referers.add("http://example.com");
referers.add("http://www.*.com");
referers.add("http://www.?.com");
request.setReferers(referers);

OSSAsyncTask task = oss.asyncPutBucketReferer(request, new OSSCompletedCallback<PutBucketRefererRequest, PutBucketRefererResult>() {
    @Override
    public void onSuccess(PutBucketRefererRequest request, PutBucketRefererResult result) {
        OSSLog.logInfo("code: " + result.getStatusCode());
    }
    @Override
    public void onFailure(PutBucketRefererRequest request, ClientException clientException, ServiceException serviceException) {
        OSSLog.logError("error: "+serviceException.getRawMessage());
    }
});
task.waitUntilFinished();
package main

import (
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "os"
)

func main() {
    // Specify the name of the bucket. 
    bucketName := "yourBucketName"

    // Obtain the access credentials from the environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // Create an OSSClient instance. 
    // Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint. 
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    var setBucketReferer oss.RefererXML
    // Add Referers to the Referer whitelist and specify that empty Referers are not allowed. You can use asterisks (*) and question marks (?) as wildcard characters in Referers. 
    setBucketReferer.RefererList = []string{
    "http://www.aliyun.com",
    "https://www.aliyun.com",
    "http://www.???.aliyuncs.com",
    "http://www.*.com",
    }
    // Add a Referer blacklist. OSS SDK for Go V2.2.8 or later supports Referer blacklist settings. 
    setBucketReferer.RefererBlacklist = &oss.RefererBlacklist{
    []string{
    "http://www.refuse.com",
    "https://*.hack.com",
    "http://ban.*.com",
    "https://www.?.deny.com",
    },
    }
    setBucketReferer.AllowEmptyReferer = false
    boolFalse := false
    setBucketReferer.AllowTruncateQueryString = &boolFalse
    err = client.SetBucketRefererV2(bucketName,setBucketReferer)
    if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
    }

    fmt.Println("Set Bucket Referer Success")
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";

    /* Initialize resources, such as network resources. */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret,  conf) ;

    /* Configure hotlink protection. */
    SetBucketRefererRequest request(BucketName);
    request.addReferer("http://example.com");
    request.addReferer("https://example.com");
    request.addReferer("https://www.?.example.com");
    request.addReferer("https://www.*.cn");
    request.setAllowEmptyReferer(false);

    auto outcome = client.SetBucketReferer(request);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "SetBucketReferer fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /* Release resources, such as network resources. */
    ShutdownSdk();
    return 0;
}
#include "oss_api.h"
#include "aos_http_io.h"
/* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
const char *endpoint = "yourEndpoint";
/* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
const char *access_key_id = "yourAccessKeyId";
const char *access_key_secret = "yourAccessKeySecret";
/* Specify the name of the bucket. Example: examplebucket. */
const char *bucket_name = "examplebucket";
void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* Use a char* string to initialize data of the aos_string_t type. */
    aos_str_set(&options->config->endpoint, endpoint);
    aos_str_set(&options->config->access_key_id, access_key_id);
    aos_str_set(&options->config->access_key_secret, access_key_secret);
    /* Specify whether to use CNAME. A value of 0 indicates that CNAME is not used. */
    options->config->is_cname = 0;
    /* Configure network parameters, such as the timeout period. */
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* Call the aos_http_io_initialize method in main() to initialize global resources, such as network resources and memory resources. */
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* Create a memory pool to manage memory. aos_pool_t is equivalent to apr_pool_t. The code that is used to create a memory pool is included in the APR library. */
    aos_pool_t *pool;
    /* Create a memory pool. The value of the second parameter is NULL. This value indicates that the pool does not inherit other memory pools. */
    aos_pool_create(&pool, NULL);
    /* Create and initialize options. This parameter includes global configuration information, such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
    oss_request_options_t *oss_client_options;
    /* Allocate the memory resources in the memory pool to the options. */
    oss_client_options = oss_request_options_create(pool);
    /* Initialize oss_client_options. */
    init_options(oss_client_options);
    /* Initialize the parameters. */
    aos_string_t bucket;
    aos_table_t *resp_headers = NULL; 
    aos_status_t *resp_status = NULL;
    oss_referer_config_t referer_config;
    aos_str_set(&bucket, bucket_name);
    aos_list_init(&referer_config.referer_list);
    oss_create_and_add_refer(pool, &referer_config, "http://www.aliyun.com");
    oss_create_and_add_refer(pool, &referer_config, "https://www.aliyun.com");
    referer_config.allow_empty_referer = 0;
    /* Add Referers to the Referer whitelist. You can use asterisks (*) and question marks (?) as wildcards in Referers. */
    resp_status = oss_put_bucket_referer(oss_client_options, &bucket, &referer_config, &resp_headers);
    if (aos_status_is_ok(resp_status)) {
        printf("put bucket referer succeeded\n");
    } else {
        printf("put bucket referer failed\n");      
    }
    /* Release the memory pool. This operation releases the memory resources allocated for the request. */
    aos_pool_destroy(pool);
    /* Release the allocated global resources. */
    aos_http_io_deinitialize();
    return 0;
}
require 'aliyun/oss'

client = Aliyun::OSS::Client.new(
  # In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
  endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
  # The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. 
  access_key_id: 'AccessKeyId', access_key_secret: 'AccessKeySecret')

# Specify the bucket name. Example: examplebucket. 
bucket = client.get_bucket('examplebucket')
# Configure the Referer allowlist of the bucket. 
bucket.referer = Aliyun::OSS::BucketReferer.new(
  allow_empty: true, whitelist: ['example.com', '*.example.com'])

Use ossutil

If you specify multiple Referers by using ossutil, separate them with commas (,).

For more information about how to configure hotlink protection for a bucket by using ossutil, see referer.

Use RESTful APIs

If you specify multiple Referers by calling RESTful API operations, separate them with commas (,).

If your business requires a high level of customization, you can directly call RESTful APIs. To directly call an API, you must include the signature calculation in your code. For more information, see PutBucketReferer.

References