尽管政策允许我的站点引荐来源网址,但 S3 存储桶上的 copyObject 访问被拒绝

Posted

技术标签:

【中文标题】尽管政策允许我的站点引荐来源网址,但 S3 存储桶上的 copyObject 访问被拒绝【英文标题】:copyObject Access Denied on S3 Bucket despite policy allowing my site referrer 【发布时间】:2019-03-23 09:32:05 【问题描述】:

我正在使用适用于 php 的 AWS 开发工具包向我的 S3 存储桶上传和显示文件。

这些文件应该只能通过我的网站访问,不允许其他引荐来源 - 不允许盗链等。

我还需要能够复制存储桶中的对象。

我照常创建和连接:

    $s3Client = new Aws\S3\S3Client([
        'version'       => 'latest',
        'region'        => 'eu-west-2'
    ]);

    $s3 = $s3Client::factory(array(
        'version'       => 'latest',
        'region'        => 'eu-west-2',
        'credentials'   => array(
        'provider'      => $provider,
        'key'           => $key,
        'secret'        => $secret
        )
    ));

并执行复制对象命令:

    $s3->copyObject([
        'Bucket'     => "$targetBucket",
        'Key'        => "$targetKeyname",
        'CopySource' => "$sourceBucket/$sourceKeyname",
    ]);

我尝试了使用“允许 if string like referrer”的策略,但 AWS 然后告诉我我允许公共访问?!?!? 一切正常,即使是 copyObject 操作,但仍然可以直接从任何地方访问文件!

我尝试使用“拒绝如果字符串不像推荐人”,它主要按预期工作 - 我可以上传和显示文件,并且直接链接时文件不显示(这是我想要的) - 但是,copyObject 操作不再工作,我收到拒绝访问错误。

我已经尝试了我能想到的所有其他方法,并花了数小时在谷歌上搜索和寻找答案,但无济于事。

这是每个单独的政策...

如果字符串 LIKE referrer,则只允许文件访问 (GetObject):


"Version": "2008-10-17",
"Id": "",
"Statement": [
    
        "Sid": "Deny access if referer is not my site",
        "Effect": "Deny",
        "Principal": 
            "AWS": "*"
        ,
        "Action": "s3:GetObject",
        "Resource": [
            "arn:aws:s3:::MY-BUCKET/*"
        ],
        "Condition": 
            "StringLike": 
                "aws:Referer": [
                    "http://MY-SITE/*",
                    "https://MY-SITE/*"
                    ]
                
            
        
    ]

结果:上传和复制对象工作,但文件仍然可以在任何地方访问


如果字符串 NOT LIKE referrer,则拒绝所有操作 (*):


"Version": "2008-10-17",
"Id": "",
"Statement": [
    
        "Sid": "Deny access if referer is not my site",
        "Effect": "Deny",
        "Principal": 
            "AWS": "*"
        ,
        "Action": "s3:GetObject",
        "Resource": [
            "arn:aws:s3:::MY-BUCKET/*"
        ],
        "Condition": 
            "StringNotLike": 
                "aws:Referer": [
                    "http://MY-SITE/*",
                    "https://MY-SITE/*"
                    ]
                
            
        
    ]

结果:copyObject 操作不再起作用,我收到拒绝访问错误

【问题讨论】:

【参考方案1】:

AWS 可能会警告您它是公开的,因为实际上它仍然是公开的。

警告

应谨慎使用此密钥:aws:referer 允许 Amazon S3 存储桶所有者帮助防止未经授权的第三方网站将其内容提供给标准 Web 浏览器。 [...] 由于aws:referer 值是由调用者在 HTTP 标头中提供的,因此未经授权的各方可以使用修改后的或自定义浏览器来提供他们选择的任何 aws:referer 值。因此,不应使用 aws:referer 来防止未经授权的各方发出直接 AWS 请求。它仅用于让客户保护其存储在 Amazon S3 中的数字内容不被未经授权的第三方网站引用。

https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html

如果您对这种原始机制没意见,请使用它,但请注意,它所做的只是相信浏览器的声明。

这就是 copyObject() 的问题 - 浏览器没有发出请求,因此没有要验证的 Referer 标头。

您可以使用StringLikeIfExists 条件测试来测试Deny错误 引用者(忽略引用者的缺失,就像对象副本那样)或者——更好——只是授予s3:GetObjectStringLike 您的推荐人,了解公共警告是正确的——这允许未经身份验证的访问,这就是推荐人检查的内容。如果从其他网站进行热链接,您的内容仍然可以公开访问,但不能通过标准的、未经修改的网络浏览器访问。

为了提高安全性,您需要使用 S3 资产的预签名 URL(到期时间短)来呈现 HTML,或者使用 Amazon Cognito 进行完全和适当的授权。

【讨论】:

【参考方案2】:

Amazon S3 中的对象默认为私有。除非以某种方式授予(例如,在 IAM 用户、IAM 组或 S3 存储桶策略上),否则无法访问。

以上政策均为拒绝政策,可以覆盖允许政策。因此,它们不是可访问的原因。

您应该首先发现授予访问权限的内容,然后删除该访问权限。一旦对象再次成为私有对象,您应该创建一个包含 Allow 语句的存储桶策略,该语句定义在哪些情况下允许访问。

【讨论】:

谢谢@john 我有一个根 IAM 用户和一个二级 IAM 用户,这是 AWS 推荐的(以防二级用户搞砸了)。根用户和辅助用户都具有 AmazonS3FullAccess 权限。我使用辅助用户的凭据在 S3 上连接和执行操作。我无法理解或找到授予访问权限的内容,因此我可以将其删除。在上述存储桶公共访问设置选项卡上,我没有检查任何选项,这会阻止我的上传和一切工作。您能提供进一步的建议吗?

以上是关于尽管政策允许我的站点引荐来源网址,但 S3 存储桶上的 copyObject 访问被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cloudfront 保护下载

尽管存储桶是公共的,但 Amazon S3 base64 图像不适用于 og:image 标签

不允许使用 Google 地图 API 引荐来源网址

不允许使用 Google 地图 API 引荐来源网址

PHP HTTP 引荐来源网址

S3:AJAX POST 没有“访问控制允许来源”