【问题标题】:Prevent hotlinking of Amazon S3 files?防止 Amazon S3 文件的热链接?
【发布时间】:2012-07-16 09:04:39
【问题描述】:

我希望允许任何人在我的网站上以src<video> 标签播放位于我的s3 中的视频,但不允许 允许人们将其用作@987654325 @ 在他们的网站上通过在浏览器栏中输入网址直接播放视频。

希望人们这样做:

我不希望以下 HTML 出现在 http://your-site.com 上,而只出现在 http://my-site.com 上:

<html>
    <video src="https://s3.amazonaws.com/my-bucket/my-video.mp4"></video>
</html>

我在这方面看到过一些 SO links,但我想用代码来谈谈,因为我无法让这些解决方案为我工作。

这是我目前有效的存储桶政策:

{
"Version": "2008-10-17",
"Statement": [
    {
        "Sid": "AllowPublicRead",
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::my-bucket/*",
        "Condition": {
            "StringLike": {
                "aws:Referer": [
                    "https://my-site.com/*"
                ]
            }
        }
    }
  }

两个问题:

  1. 为了测试我的存储桶策略,我将上面的 HTML 放在本地主机上的测试文件中,果然我可以通过输入 http://localhost/test.html 来访问视频。为什么我的存储桶策略不能阻止这种情况? (我只希望它在 http://my-site.com/test.html 上工作)
  2. 为了防止人们将 s3 URL 输入浏览器栏,我想我需要一个与存储桶策略不同的解决方案,因为我从 AWS 文档中不清楚如何防止通过浏览器直接访问。我正在考虑散列网址以使其难以猜测。不过,也许有一些方法可以使用 AWS 存储桶策略或其他解决方案?

更清楚地说,我的文件存储在 s3 上,但它们是由亚马逊的 CloudFront 交付的。所以我的 CloudFront url src 目前是 media.my-site.com/my-video.mp4。 CNAME 是 media.my-site.com。

【问题讨论】:

  • “我正在考虑对 url 进行哈希处理以使其难以猜测。” — 默默无闻的安全性是一个糟糕的计划。
  • @DC_,谢谢,我不会那样做。您对我应该怎么做有什么建议吗?
  • @tim 不幸的是,我几乎没有使用 AWS 的经验,所以我无法在存储桶策略方面为您提供帮助。我想我有一个想法,我会把它作为答案发布。
  • @timpeterson,对不起,我以为你在谈论 CloudFront -> S3。我的(已删除)评论不适用。
  • @Matthew 我的文件存储在 s3 上,但它们由 CloudFront 交付。所以我的src CloudFront 网址目前类似于media.my-site.com/my-video.mp4。这有助于更好地解释吗?我会在我的问题中更清楚地说明这一点。

标签: php amazon-s3 amazon-web-services referrer hotlinking


【解决方案1】:

鉴于 CloudFront 目前不允许您直接限制访问(据我所知),我会这样做:

<video src="/media.php?v=my-video.mp4"></video>

那么你的media.php 文件看起来像:

if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != 'my-site.com')
{
  header('HTTP/1.1 503 Hot Linking Not Permitted');
  // display some message / image / video
  exit;
}

# this base url changes from time to time
$url = 'http://cdn.my-site.com';

header("Location: $url/{$_GET['v']}");

为使其不那么明显,您可能需要设置重写以将/media/my-video.mp4 路由到文件中。这样一来,看起来就没有中间 PHP 脚本了。

您执行引荐来源网址检查的具体方式取决于您想要的安全级别。有些人禁用引荐来源网址,因此您可能希望允许空引荐来源网址。或者您甚至可以检查会话变量或 cookie 是否存在等。

当然,最终用户将能够嗅出真实的 URL。这就是您可能需要不时更改 CNAME 的原因。

希望此解决方案足以阻止人们滥用您的网站,但绝不是完美的。

【讨论】:

  • 嗨@Michael,感谢您的回答。因此,通过“嗅出真实的 URL”,您的意思是从源代码/Firebug/Developer Tools 中获取它?似乎不是试图找出 php 文件的逻辑,而是简单的途径是:1)从 my-site.com 源代码获取 URL(CloudFront 的)(假设他们第一次合法访问)。 2) 将 URL 放入 your-site.com 源代码 3) 希望 my-site.com 不会更改其链接(即 CNAME)。我们在同一页上吗?
  • 是的,没错。使用 Firebug 之类的东西,他们可以查看 HTTP 流量并看到电影只是重定向到 CloudFront。该 URL 将不受保护,因此您需要不时更新您的 CNAME。
【解决方案2】:

您能否使用 PHP 作为代理,而不是直接链接到您的 S3 文件,以便最终用户永远看不到实际的 S3 URL,并且您可以更轻松地验证引用者?不过,您可能需要某种数据库,因此您可以将 ID 链接到 S3 文件。例如(不考虑安全措施):

<?php
$file = $_GET['id'];
$referer = $_SERVER['HTTP_REFERER'];

if($referer === 'http://my-site.com/test.html'){
    $s3 = //Query your database of S3 files with the ID provided to get the S3 URL
    header(mime_content_type($s3));
    include($s3);
}
?>

这可以保存为 get_file.php 或任何你想要的,你可以把http://my-site.com/file/get_file.php?id=120381 之类的链接放在你的 HTML 中。

更进一步,您可以使用 .htaccess 文件将http://my-site.com/file/120381.mp4 等请求路由到http://my-site.com/file/get_file.php?id=120381

我不确定它的效果如何,我提供的 PHP 代码只是帮助传达我的想法的一个示例;它不是完美的代码,所以请不要仅仅为此而对我投反对票。

【讨论】:

  • HTTP_REFERER可由客户端设置。
  • @LucM 是的,好点。我还是觉得这个方法比默默无闻的方法更安全;如果有人有更好的想法,请提出新的答案!
  • @LucM 感谢您提供看起来适用于盗链的解决方案。但是,如果有人试图通过在浏览器栏中输入内容来获取您的文件,您是否同意“默默无闻的安全性”是唯一的选择?
  • 是的,HTTP_REFERER 可以由客户端设置,但大多数人使用有效的引荐来源网址,这使得检查成为阻止热链接嵌入内容的有效方法。这里更大的问题是,虽然不会直接看到 URL,但仍然可以通过使用任何浏览器开发工具通过嗅探 HTTP 流量轻松发现它。因此,我会将其与您定期更新的 CNAME 结合起来。
  • 关于答案本身,您不想“包含” CloudFront 内容。你想重定向到它。包含文件并将其传递会破坏 CloudFront 的全部目的。关键是,人们会天真地复制/粘贴您的 PHP 链接,该链接具有 HTTP 引荐来源网址检查。如果他们访问了真正的 CF 链接,那么在您更新 CNAME 之前,这只会工作很短的时间。不是万无一失,但可能很有效,除非你有人们真的想要窃取的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多