diff --git a/docs/.vuepress/public/img/2000000033.jpg b/docs/.vuepress/public/img/2000000033.jpg
new file mode 100644
index 0000000..b0d8c85
Binary files /dev/null and b/docs/.vuepress/public/img/2000000033.jpg differ
diff --git a/docs/.vuepress/public/img/2000000034.png b/docs/.vuepress/public/img/2000000034.png
new file mode 100644
index 0000000..2346342
Binary files /dev/null and b/docs/.vuepress/public/img/2000000034.png differ
diff --git a/docs/.vuepress/public/img/2000000035.png b/docs/.vuepress/public/img/2000000035.png
new file mode 100644
index 0000000..f4d0e97
Binary files /dev/null and b/docs/.vuepress/public/img/2000000035.png differ
diff --git a/docs/.vuepress/public/img/2000000036.png b/docs/.vuepress/public/img/2000000036.png
new file mode 100644
index 0000000..3cc1e6c
Binary files /dev/null and b/docs/.vuepress/public/img/2000000036.png differ
diff --git a/docs/.vuepress/public/img/2000000037.png b/docs/.vuepress/public/img/2000000037.png
new file mode 100644
index 0000000..8572e51
Binary files /dev/null and b/docs/.vuepress/public/img/2000000037.png differ
diff --git a/docs/.vuepress/public/img/2000000038.png b/docs/.vuepress/public/img/2000000038.png
new file mode 100644
index 0000000..c3b9b44
Binary files /dev/null and b/docs/.vuepress/public/img/2000000038.png differ
diff --git a/docs/.vuepress/public/img/2000000039.png b/docs/.vuepress/public/img/2000000039.png
new file mode 100644
index 0000000..5056460
Binary files /dev/null and b/docs/.vuepress/public/img/2000000039.png differ
diff --git a/docs/Changelog/readme.md b/docs/Changelog/readme.md
index f517ed6..d0829ec 100644
--- a/docs/Changelog/readme.md
+++ b/docs/Changelog/readme.md
@@ -5,6 +5,23 @@ title: 更新日志
---
+## 2024.6.9
+
+
+
+
+
+
+
+
+
+ 新增文章《使用云函数限制存储桶上传类型》文章地址
+
+
+
+
+
+
## 2024.5.6
diff --git a/docs/CloudService/S3/limiting-bucket-upload-types-using-cloud-functions.md b/docs/CloudService/S3/limiting-bucket-upload-types-using-cloud-functions.md
new file mode 100644
index 0000000..7a11a80
--- /dev/null
+++ b/docs/CloudService/S3/limiting-bucket-upload-types-using-cloud-functions.md
@@ -0,0 +1,183 @@
+---
+title: 使用云函数限制存储桶上传类型
+
+---
+
+使用云函数限制存储桶上传类型
+
+---
+
+## 前言
+
+相信不少师傅都挖到过存储桶任意文件上传的漏洞,不过由于存储桶的特性,这种任意文件上传的危害性相对传统站点要低一些,但仍然具备一定的风险,比如可以被拿来当做钓鱼或者挂黑页等等。
+
+常规修复这类风险的办法是通过在后端代码里限制文件的上传类型,网上已经有了相应的文章,本文将探讨另外一个方法,即使用云函数去限制存储桶的文件上传类型。
+
+本文将以限制存储桶只能上传图片的场景为例,至于怎么限制其他类型则只需要对函数代码稍加修改就能实现,为了更好的理解本文内容,这里简单绘制了一个流程图如下。
+
+
+
+## 操作步骤
+
+这里以阿里云为例,首先在函数计算 FC 服务里创建一个事件函数,这里函数的区域需要和目标存储桶的区域保持一致。
+
+
+
+运行环境选择 Python,然后将下面的代码保存为 index.py 文件后压缩成 ZIP 包,再将 ZIP 包上传到云函数中。
+
+```python
+import os
+import json
+import oss2
+import imghdr
+
+
+def handler(event, context):
+ # 获取临时访问凭证并进行认证
+ creds = context.credentials
+ auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token)
+
+ # 获取上传文件的相关信息
+ evt_lst = json.loads(event)
+ evt = evt_lst['events'][0]
+ bucket_name = evt['oss']['bucket']['name']
+ object_key = evt['oss']['object']['key']
+ endpoint = 'oss-' + evt['region'] + '-internal.aliyuncs.com'
+ bucket = oss2.Bucket(auth, endpoint, bucket_name)
+
+ # 获取上传文件的后缀类型
+ upload_file_suffix_type = os.path.splitext(object_key)[1].replace('.', '')
+
+ # 获取上传文件的内容类型
+ head_result = bucket.head_object(object_key)
+ upload_file_content_type = head_result.headers.get('Content-Type')
+
+ # 获取上传文件的文件头类型
+ upload_file_content = bucket.get_object(object_key).read()
+ upload_file_header_type = imghdr.what(None, h=upload_file_content[:32])
+
+ print(f'[+] 文件上传路径:oss://{bucket_name}/{object_key}')
+ print(f'[+] 文件头类型:{upload_file_header_type}')
+ print(f'[+] 文件后缀类型:{upload_file_suffix_type}')
+ print(f'[+] 文件 Content-Type:{upload_file_content_type}')
+
+ # 允许上传的文件类型列表
+ allowed_types = ['jpg', 'jpeg', 'png', 'gif']
+ allowed_content_types = ['image/jpeg', 'image/png', 'image/gif']
+
+ # 检查文件类型是否合规
+ Compliant = 0
+ print('[+] 正在检查上传的文件是否合规 ……')
+ if upload_file_header_type not in allowed_types:
+ print('[-] 文件头类型检查不通过。')
+ else:
+ print('[+] 文件头类型检查通过。')
+ if upload_file_suffix_type not in allowed_types:
+ print('[-] 文件后缀类型检查不通过。')
+ else:
+ print('[+] 文件后缀类型检查通过。')
+ if upload_file_content_type not in allowed_content_types:
+ print('[-] 文件 Content Type 检查不通过。')
+ else:
+ print('[+] 文件 Content Type 检查通过。')
+ Compliant = 1
+
+ # 删除不允许上传的文件
+ if Compliant:
+ print(f'[+] 文件 oss://{bucket_name}/{object_key} 检查通过。')
+ else:
+ print(f'[-] 文件 oss://{bucket_name}/{object_key} 检查不通过,正在删除该文件。')
+ bucket.delete_object(object_key)
+ print(f'[!] 文件 oss://{bucket_name}/{object_key} 已被删除。')
+```
+
+由于我们在这里的 Python 代码中需要调用到 GetObject 和 DeleteObject 的 API,因此还需要为这个函数配置一个至少具备这两个操作权限的角色。
+
+这里我们在 IAM 里创建一个角色,这个角色的最低权限要求如下:
+
+```json
+{
+ "Version": "1",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": [
+ "oss:GetObject",
+ "oss:DeleteObject"
+ ],
+ "Resource": "acs:oss:oss-::/*"
+ }
+ ]
+}
+```
+
+信任策略如下:
+
+```json
+{
+ "Statement": [
+ {
+ "Action": "sts:AssumeRole",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": [
+ "fc.aliyuncs.com"
+ ]
+ }
+ }
+ ],
+ "Version": "1"
+}
+```
+
+角色创建完成后,在「高级配置」这里选择我们在函数中要使用的角色名称,其他地方可以保持默认或者根据自己的需求进行修改,最后点击函数「创建」按钮。
+
+
+
+创建完云函数后,我们还需要为这个函数创建一个触发器,从而让存储桶有文件上传时能够触发这个函数的执行。
+
+在函数配置页面中,选择「触发器」,点击「创建触发器」,触发类型选择 OSS,Bucket 名称选择自己需要限制文件上传类型的 Bucket,触发事件这里选择 PutObject,角色直接使用默认角色,最后点击「确定」,这样所有的配置就完成了。
+
+
+
+此时我们向存储桶上传一个正常的文件,可以看到三项检查都是通过的,这样文件是能正常上传的。
+
+
+
+如果上传一个后缀是 html 的文件,那么检查就是不通过的,此时云函数就会把这个文件从存储桶中删掉。
+
+
+
+如果上传的文件名是 png 后缀的,Content-Type 是 image/jpeg,但 Body 部分不是图片类型同样也会无法上传。
+
+
+
+到此为止,已经能够基本实现使用云函数去限制文件上传类型了,不过这里还有一些可以优化的地方以及一些局限性留给读者探讨。
+
+**可以优化的地方:**
+
+1. 如果想识别其他类型的文件,例如 zip、txt 等格式,这里使用的 imghdr 库就不够用了,imghdr 只能识别出图片文件的类型,这时可以使用第三方库,例如 python-magic 库。
+2. 这里代码中采取的策略是检测到不合规的文件会直接执行删除操作,在实际场景中直接删除可能具有一定的风险性,尤其是存在存储桶同名称覆盖问题的时候,因此这里还是需要根据自身业务情况做适当的调整。
+
+**存在局限性的地方:**
+
+由于云函数里的 OSS 触发器只能采取异步的方式执行,因此云函数在触发时,文件就已经被上传到存储桶里了,所以没办法解决在上传同名称文件时被覆盖的问题,这个问题目前似乎只能通过后端代码去解决。
+
+## 总结
+
+本文为限制存储桶文件上传类型提供了一个新的解决方案,但也具备一定的局限性。
+
+此外在当前存储桶策略里我注意到在资源路径下可以使用 *.png 来限制文件的上传后缀,不过目前还没办法限制 Content Type,在此也希望云厂商能够在存储桶策略里加上限制 Content Type 的策略,这样限制存储桶的文件上传类型就更方便了,提升存储桶的安全性也会变得更加简单。
+
+不过如果想要有更严格的限制策略,那么还是云函数或者后端代码具有更高的自由度。
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/CloudService/sidebar_contents.js b/docs/CloudService/sidebar_contents.js
index 4a351e8..99cba3a 100644
--- a/docs/CloudService/sidebar_contents.js
+++ b/docs/CloudService/sidebar_contents.js
@@ -13,6 +13,7 @@ module.exports = [
"/CloudService/S3/bucket-policy-able-to-write",
"/CloudService/S3/bucket-object-traversal",
"/CloudService/S3/specific-bucket-policy-configuration",
+ "/CloudService/S3/limiting-bucket-upload-types-using-cloud-functions"
]
},
{