1. 前言
阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。
OSS具有与平台无关的RESTful API接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
2.OSS与文件系统的对比
下表为OSS与文件系统在数据模型、数据获取、优势以及劣势的差异对比。
对比项 | OSS | 文件系统 |
数据模型 | OSS是一个分布式的对象存储服务,提供的是一个Key-Value对形式的对象存储服务。 | 文件系统是一种典型的树状索引结构。 |
数据获取 | 根据Object的名称(Key)唯一的获取该Object的内容。 虽然您可以使用类似 | 一个名为 |
优势 | 支持海量的用户并发访问。 | 支持文件的修改,例如修改指定偏移位置的内容、截断文件尾部等。也支持文件夹的操作,例如重命名目录、删除目录、移动目录等非常容易。 |
劣势 | OSS保存的Object不支持修改(追加写Object需要调用特定的接口,生成的Object也和正常上传的Object类型上有差别)。用户即使只需要修改一个字节也需要重新上传整个Object。 OSS可以通过一些操作来模拟类似文件夹的功能,但是代价非常高。例如重命名目录,如果希望将test1目录重命名成test2,则OSS的实际操作是将所有以 | 受限于单个设备的性能。访问越深的目录消耗的资源也越大,操作拥有很多文件的目录也会非常慢。 |
从上述表格得知,不建议将OSS映射为文件系统。如果结合您的业务场景需要将OSS挂载为文件系统,建议只执行写入文件、删除文件、读取文件操作。使用OSS应该充分发挥其优点,即海量数据处理能力,优先用来存储海量的非结构化数据,例如图片、视频、文档等。
下表为OSS与文件系统的概念对应说明。
对象存储 OSS | 文件系统 |
Object | 文件 |
Bucket | 主目录 |
Region | 无 |
Endpoint | 无 |
AccessKey | 无 |
无 | 多级目录 |
GetService | 获取主目录列表 |
GetBucket | 获取文件列表 |
PutObject | 写文件 |
AppendObject | 追加写文件 |
GetObject | 读文件 |
DeleteObject | 删除文件 |
无 | 修改文件内容 |
CopyObject (目标文件和源文件相同) | 修改文件属性 |
CopyObject(目标文件和源文件不同) | 复制文件 |
CopyObject+DeleteObject | 重命名文件 |
3. OSS客户端签名直传的安全风险
3.1 为什么使用客户端直传而非服务端代理上传
在典型的服务端和客户端架构下,常见的文件上传方式是服务端代理上传:客户端将文件上传到业务服务器,然后业务服务器将文件上传到OSS。在这个过程中,一份数据需要在网络上传输两次,会造成网络资源的浪费,增加服务端的资源开销。为了解决这一问题,可以在客户端直连OSS来完成文件上传,无需经过业务服务器中转。
3.2 客户端签名直传方式的风险
客户端签名直传是指在客户端生成签名,使用签名上传文件到OSS。客户端可以直接将文件上传至OSS,减少了中间环节,因此可以加快上传速度。
上传文件到OSS需要使用RAM用户的访问密钥(AccessKey)来完成签名认证,但是在客户端中使用长期有效的访问密钥,可能会导致访问密钥泄露,进而引起安全问题。
4. 客户端签名直传方式风险解决方法
4.1 解决方法1: 服务端生成STS临时访问凭证
对于大部分上传文件的场景,建议您在服务端使用STS SDK获取STS临时访问凭证,然后在客户端使用STS临时凭证和OSS SDK直接上传文件。客户端能重复使用服务端生成的STS临时访问凭证生成签名,因此适用于基于分片上传大文件、基于分片断点续传的场景。需要注意的是,频繁地调用STS服务会引起限流,因此建议您对STS临时凭证做缓存处理,并在有效期前刷新。为了确保STS临时访问凭证不被客户端滥用,建议您为STS临时访问凭证添加额外的权限策略,以进一步限制其权限。
服务端通过STS临时访问凭证授权客户端上传文件到OSS的过程如下
-
客户端向业务服务器请求临时访问凭证。
-
业务服务器使用STS SDK调用AssumeRole接口,获取临时访问凭证。
-
STS生成并返回临时访问凭证给业务服务器。
-
业务服务器返回临时访问凭证给客户端。
-
客户端使用OSS SDK通过该临时访问凭证上传文件到OSS。
-
OSS返回成功响应给客户端。
报文格式样例1:
假设你有一个Web应用需要上传文件到OSS。你可以在服务端生成STS临时访问凭证,并将这些临时凭证传递给Web应用。Web应用使用这些临时凭证进行文件上传操作。
服务端生成STS临时访问凭证:
POST / HTTP/1.1
Host: sts.aliyuncs.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 200
Action=AssumeRole
&RoleArn=acs:ram::1234567890123456:role/your-role
&RoleSessionName=session-name
&DurationSeconds=3600
&Version=2015-04-01
&AccessKeyId=your-access-key-id
&SignatureMethod=HMAC-SHA1
&Timestamp=2024-06-11T12%3A00%3A00Z
&SignatureVersion=1.0
&SignatureNonce=unique-nonce
&Signature=your-signature
服务端响应(通过HTTPS传输):
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: 500
<AssumeRoleResponse>
<RequestId>request-id</RequestId>
<AssumedRoleUser>
<AssumedRoleId>role-id</AssumedRoleId>
<Arn>acs:ram::1234567890123456:role/your-role/session-name</Arn>
</AssumedRoleUser>
<Credentials>
<SecurityToken>your-security-token</SecurityToken>
<AccessKeySecret>your-access-key-secret</AccessKeySecret>
<AccessKeyId>your-temporary-access-key-id</AccessKeyId>
<Expiration>2024-06-11T13:00:00Z</Expiration>
</Credentials>
</AssumeRoleResponse>
Web应用使用临时凭证上传文件(通过HTTPS传输):
PUT /your-bucket-name/large-file.txt HTTP/1.1
Host: your-bucket-name.your-oss-endpoint
Authorization: OSS your-temporary-access-key-id:your-signature
x-oss-security-token: your-security-token
Date: Wed, 11 Jun 2024 12:10:00 GMT
Content-Length: 5242880
Content-Type: application/octet-stream
[binary data of the file]
报文格式样例2(来自阿里云官方文档):
服务端获取临时凭证报文截图:
客户端使用临时凭证上传文件报文中的凭证信息:
accessKeyId: credentials.AccessKeyId,
accessKeySecret: credentials.AccessKeySecret,
stsToken: credentials.SecurityToken
从样例中不难分析出:使用STS临时访问凭证可以显著减少密钥泄露的风险,因为临时凭证的有效期有限、权限可控,并且可以通过安全传输和监控进一步增强安全性。通过合理配置和使用STS临时访问凭证,可以确保你的应用在安全性和灵活性之间取得良好的平衡。
阿里云的某架构师认为:无AK设计的STS访问方式通过提供临时、细粒度的权限控制,增强系统的安全性,同时提高操作的灵活性和管理效率,特别适用于需要动态、安全授权的云服务访问场景。STS(Security Token Service)访问替代原来的AK方式主要带来以下几点优势:
1. 安全性增强:
- 最小权限原则:STS允许为第三方应用或子用户颁发具有严格限制的临时访问凭证,这些凭证具有自定义的有效时间和权限范围。相比直接使用长期有效的Access Key,即使凭证泄露,也能将潜在的安全风险限定在很短的时间内,并且影响范围有限。
- 细粒度权限控制:STS可以针对具体操作、资源或服务设定权限,而不是像传统AK那样可能赋予广泛的操作权限,这有助于实施更精细的安全策略。
2. 灵活性与便捷性:
- 临时授权:对于需要临时访问阿里云资源的场景,如短期合作、第三方应用集成等,STS能够快速生成相应的临时凭证,无需长期维护或交换敏感的Access Key信息。
- 自动化集成:STS易于与自动化流程集成,例如CI/CD管道中自动获取临时凭证进行资源访问,简化了权限管理和运维工作。
3. 降低管理负担:
- 避免AK共享:减少了长期AK的共享需求,有助于遵循最佳实践,避免因AK泄露导致的账户安全风险。
- 权限生命周期管理:STS令牌的自动过期特性减轻了权限回收的压力,无需手动撤销或修改长期AK权限。
4. 兼容性和标准化:
- 标准协议:STS遵循行业标准,便于与外部系统的集成,使得权限管理更加标准化和开放。
4.2 解决方法2 服务端生成PostObject所需的签名和Post Policy
对于需要限制上传文件属性的场景,您可以在服务端生成PostObject所需的Post签名、PostPolicy等信息,然后客户端可以凭借这些信息,在一定的限制下不依赖OSS SDK直接上传文件。您可以借助服务端生成的PostPolicy限制客户端上传的文件,例如限制文件大小、文件类型。此方案适用于通过HTML表单上传的方式上传文件。需要注意的是,此方案不支持基于分片上传大文件、基于分片断点续传的场景。
关于服务端签名直传是对断点续传的影响,我询问了阿里云的“AI客服”:
“采用服务端签名直传并不直接影响断点续传功能的使用,但需确保客户端实现支持断点续传逻辑。OSS本身支持断点续传上传,关键在于客户端需正确处理checkpointDir
以记录上传进度。服务端签名直传主要涉及为客户端生成一次性上传凭证,并不影响客户端实现断点续传机制。同时,设置上传回调功能与断点续传是两个独立特性,可以同时应用,互不影响。确保客户端在实现时兼容这两个功能即可。”
服务端通过Post签名和Post Policy授权客户端上传文件到OSS的过程如下
-
客户端向业务服务器请求Post签名和Post Policy等信息。
-
业务服务器生成并返回Post签名和Post Policy等信息给客户端。
-
客户端使用Post签名和Post Policy等信息调用PostObject通过HTML表单的方式上传文件到OSS。
-
OSS返回成功响应给客户端。
样例1
关于客户端使用Post Policy上传文件的HTTP请求数据包格式,我从AI获取了一个客户端生成数据包格式的样例:
import requests
# 配置
bucket_name = 'your-bucket-name'
endpoint = 'your-oss-endpoint'
object_name = 'example.txt'
file_path = 'path/to/your/file.txt'
# 从服务端获取的Policy和Signature
policy = 'your-generated-policy'
signature = 'your-generated-signature'
# 构建表单数据
form_data = {
'key': object_name,
'policy': policy,
'OSSAccessKeyId': 'your-access-key-id',
'success_action_status': '201', # 返回201状态码表示成功
'signature': signature
}
# 上传文件
with open(file_path, 'rb') as file:
files = {'file': file}
response = requests.post(f'http://{bucket_name}.{endpoint}', data=form_data, files=files)
print('Response status code:', response.status_code)
print('Response text:', response.text)
样例2(阿里云官方文档):
服务端代码部分:
response = {
'policy': base64.b64encode(json.dumps(policy).encode('utf-8')).decode(),
'ossAccessKeyId': access_key_id,
'signature': signature,
'host': host,
'dir': upload_dir
# 可以在这里再自行追加其他参数
}
客户端上传文件代码:
const formData = new FormData();
formData.append("name", filename);
formData.append("policy", data.policy);
formData.append("OSSAccessKeyId", data.ossAccessKeyId);
formData.append("success_action_status", "200");
formData.append("signature", data.signature);
formData.append("key", data.dir + filename);
formData.append("file", file);
从样例的python代码可见,access_key_secret没有被使用。
也许你会关心,这里的签名是用什么参数生成的。我们可以通过阿里云官方文档的样例代码的注释可以窥见:
"""
生成签名字符串Signature。
:param access_key_secret: 有权限访问目标Bucket的AccessKeySecret。
:param expiration: 签名过期时间,按照ISO8601标准表示,并需要使用UTC时间,格式为yyyy-MM-ddTHH:mm:ssZ。示例值:"2014-12-01T12:00:00.000Z"。
:param conditions: 策略条件,用于限制上传表单时允许设置的值。
:param policy_extra_props: 额外的policy参数,后续如果policy新增参数支持,可以在通过dict传入额外的参数。
:return: signature,签名字符串。
"""
如上,私钥肯定是要的,除此之外,还有“签名过期时间,策略条件,额外policy参数”。
“服务端签名直传并设置上传回调”在工程实践中是比较好的方法。
请阅读
如何基于PostPolicy的使用规则服务端签名直传并设置上传回调_对象存储(OSS)-阿里云帮助中心
4.3 解决方法3 服务端生成PutObject所需的签名URL
对于简单上传文件的场景,您可以在服务端使用OSS SDK生成PutObject所需的签名URL,客户端可以凭借签名URL,不依赖OSS SDK直接上传文件。需要注意的是,此方案不适用于基于分片上传大文件、基于分片断点续传的场景。在服务端对每个分片生成签名URL,并将签名URL返回给客户端,会增加与服务端的交互次数和网络请求的复杂性。另外,客户端可能会修改分片的内容或顺序,导致最终合并的文件不正确。
服务端通过签名URL授权客户端上传文件到OSS的过程如下
-
客户端向业务服务器请求签名URL。
-
业务服务器使用OSS SDK生成PUT类型的签名URL,然后将其返回给客户端。
-
客户端使用PUT类型的签名URL调用PutObject上传文件到OSS。
-
OSS向客户端返回成功响应。
这里的“此方案不适用场景”,我起初比较疑惑,后来做了一些研究,以下是结论:
服务端生成PutObject签名URL的方案主要适用于简单的文件上传场景。对于大文件的分片上传和断点续传,确实会增加复杂性,因为每个分片都需要单独生成签名URL,并且需要处理分片的顺序和内容一致性问题。
在分片上传的场景中,每个分片都需要服务端生成签名URL并返回给客户端,这会增加与服务端的交互次数和网络请求的复杂性。这不仅增加了系统的负载,还可能导致性能问题。
虽然客户端确实有可能修改分片的内容或顺序,但这并不是签名URL方案特有的问题,而是所有分片上传方案都需要考虑的问题。OSS提供的分片上传机制本身就包含了对分片顺序和内容一致性的校验,客户端需要正确实现这些逻辑。
总体来说,资料中提到的“此方案不适用于基于分片上传大文件、基于分片断点续传的场景”是正确的。具体原因包括:
- 增加交互次数和复杂性:每个分片都需要单独生成签名URL,增加了与服务端的交互次数和网络请求的复杂性。
- 内容和顺序一致性:虽然OSS本身提供了分片上传的机制来确保内容和顺序的一致性,但客户端需要正确实现这些逻辑,否则可能会导致最终合并的文件不正确。
样例
阿里云提供的签名示例:
签名示例
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2p***********&Expires=1141889120&Signature=****Pxyb****mGa%****272YEAiv****
如果需要使用STS用户构造URL签名,则必须携带security-token
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=nz2p***********&Expires=1141889120&Signature=****Pxyb****mGa%****272YEAiv****&security-token=CAIS****q6Ft5B2yfSjIr****Oz31blR9oWmWBf****DR/xm3Imc****IHxMdHJsCeAcs/Q0lGFR5/sflqJIR****EvCUcZr8szfWcsZos2****u5Jko1be0ewHKeQKZsebWZ+LmNpy/Ht6md1HDkAJq3LL+bk/Mdle5MJqP+/kFC9MMRVuAcCZhDtVbLRcYgq18D3bKMuu3ORPHm3fZCFES2jBxkmRi86+ysIP+phPVlw/90fRH5dazcJW0Zsx0OJo6Wcq+3+FqM6DQlTNM6hwNtoUO1fYUommb54nDXwQIvUjfbtC5qIM/cFVLAYEhAL****TGkvl1h/fejYyfyW****kFCHiPF****JCUSbr4a4sjF6zyPnPWycyCLYXleLzhxPWd/2kagAGaXG69BqwYNvrKKI3W8****bNc1wQDMXQfiHpFCRG6lYhh3****pwH90A3sTlxzRGvi8+****JwrluOHWs+Fj6S6s0cOhKvKRWYE8UuWeXIvv4l6DAGwH****LjLC11f5prUJ****b+3hwuBod32Jx+us/1p996Glao725orcb****
您可以在签名URL中添加想要授权的IP地址、IP地址段或VPC ID,避免未授权的终端访问OSS资源。
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf?&OSSAccessKeyId=44CF****************&Expires=1475462111&Signature=77Dv****************&x-oss-ac-subnet-mask=32
参考链接:
我从网上找到的生成的分片上传签名URL示例
分片上传签名URL格式如下所示:
https://example-bucket.oss-cn-hangzhou.aliyuncs.com/example.txt?partNumber=1&uploadId=0004B9956DB1A8B8B8A1E8E8E8E8E8E8&OSSAccessKeyId=LTAI4G1pEXAMPLE&Expires=1622548800&Signature=abc123EXAMPLE
参数解释:
Bucket 名称:example-bucket
Endpoint:oss-cn-hangzhou.aliyuncs.com
Object 名称:example.txt
Access Key ID:LTAI4G1pEXAMPLE
过期时间:1622548800(Unix时间戳)
签名:abc123EXAMPLE
分片编号:1
上传ID:0004B9956DB1A8B8B8A1E8E8E8E8E8E8
以上URL并无access_key_secret,因为
服务端使用access_key_id
和access_key_secret
生成签名URL,并将其返回给客户端。生成签名URL的过程在服务端进行,客户端无法获取access_key_secret
。
参考资料:
在客户端直接上传文件到OSS_对象存储(OSS)-阿里云帮助中心
4.4 改为服务端文件上传方式
在典型的服务端和客户端架构下,常见的文件上传方式是就是服务端代理上传:客户端将文件上传到业务服务器,然后业务服务器将文件上传到OSS。
但是我们需要意识到的是:在这个过程中,一份数据需要在网络上传输两次,会造成网络资源的开销翻倍。
4.5 解决方法2和解决方法3的使用区别
PostObject:
适用于表单上传场景,提供细粒度的控制。
适合Web应用开发,简单易用。
不适用于大文件的分片上传和断点续传。
PutObject:
适用于简单的文件上传场景,客户端直接使用签名URL进行上传。
适合需要直接上传文件的场景,签名URL短期有效。
不适用于大文件的分片上传和断点续传,增加了复杂性和交互次数。
根据具体的使用场景和需求,可以选择合适的上传方式。
对于需要表单上传和细粒度控制的场景,可以使用PostObject签名和Post Policy
对于简单的文件上传,可以使用PutObject签名URL
4.6 解决方法1相较于解决方法2的优点
2024年9月4日,我与阿里云的“企业架构师”开会讨论了这几种解决方案。对方极力推荐解决方案1,阿里云的架构师认为对于企业的复杂系统,解决方案1更简单维护更方便,而且不同场景的试用性更强,他们向客户重点推荐“服务端生成STS临时访问凭证”的解决方法。
以下是使用 STS 临时访问凭证相对于服务端生成 PostObject 所需签名和 Post Policy 方法的一些优势:
4.6.1安全性方面
细粒度访问控制:STS 临时访问凭证可以精确地定义用户或应用程序在特定时间段内对 OSS 资源的访问权限,例如只读、只写特定目录等。而基于签名和 Post Policy 的方式相对来说在权限控制的灵活性上稍逊一筹。
降低长期密钥暴露风险:使用 STS 临时访问凭证不需要将阿里云主账号或长期有效的子账号密钥暴露给客户端,减少了密钥泄露可能导致的安全隐患。而在生成签名和 Post Policy 时,如果处理不当可能会存在长期密钥被意外暴露的风险。
4.6.2使用便捷性方面
简化开发流程:STS 临时访问凭证的生成和管理在阿里云的安全框架下相对标准化,开发者可以更方便地在不同应用场景中集成和使用。相比之下,处理签名和 Post Policy 需要对相关算法和流程有深入理解,开发和维护成本较高。
动态权限管理:在一些复杂的业务场景中,可能需要根据不同的用户角色、业务逻辑动态调整对存储桶的访问权限。STS 临时访问凭证可以通过编程方式在服务端动态生成和调整权限,而修改 Post Policy 相对来说不够灵活。
4.6.3可扩展性方面
适应复杂业务架构:对于大型企业或复杂的云服务架构,可能有多个不同的服务或组件需要访问 OSS 存储桶。STS 临时访问凭证可以更好地适应这种复杂的架构,方便地为不同的服务分配不同的访问权限,并且可以随时调整,更有利于系统的扩展和演进。而基于签名和 Post Policy 的方式在可扩展性方面可能会受到一定限制,尤其是在权限管理变得复杂时。
4.6.3.1多服务协作与权限隔离
在复杂业务架构中,往往存在多个不同功能的服务,例如一个电商系统中可能有商品图片上传服务、用户头像管理服务、订单相关文件存储服务等。STS 临时访问凭证可以为每个服务单独生成相应权限的临时凭证。例如商品图片上传服务只被授予对存储桶中商品图片目录的写入权限,用户头像管理服务只对头像目录有读写权限,这样就实现了不同服务之间的权限隔离。而通过传统的签名和 Post Policy 方式来管理这些不同服务的权限会变得非常复杂,容易出现权限混淆或难以维护的情况。
4.6.3.2动态业务需求调整
随着业务的发展和变化,对存储桶的访问需求也会动态改变。比如在促销活动期间,商品图片的上传量会大幅增加,可能需要临时增加某个商品图片上传服务对存储桶的访问带宽或者存储容量限制。通过 STS 临时访问凭证,服务端可以动态地调整该服务对应的临时凭证权限,快速响应业务需求。而如果依赖于固定的签名和 Post Policy,这种动态调整可能需要重新设计和部署整个权限相关的逻辑,导致响应速度慢且容易出错。
4.6.3.3与第三方服务集成
复杂业务架构中可能会涉及与第三方服务的集成。例如,企业使用的第三方数据分析服务需要访问 OSS 存储桶中的数据进行分析。使用 STS 临时访问凭证,可以为这个第三方服务生成一个具有特定时间限制和只读权限的临时凭证,确保第三方服务在授权范围内安全地访问数据。而通过 Post Policy 与第三方服务集成时,可能会面临兼容性问题以及如何安全地传递签名信息等挑战,增加了集成的难度和风险。
4.6.3.4跨账号和跨区域协作
在大型企业中,可能存在多个不同的阿里云账号,或者在不同的地域都有业务部署。STS 临时访问凭证可以方便地实现跨账号和跨区域的资源访问控制。例如,总部的某个管理服务需要访问分布在不同区域子公司的 OSS 存储桶资源,或者不同账号下的相关服务需要协同工作。通过 STS 可以生成相应的临时凭证来满足这些复杂的协作需求。而在使用 Post Policy 时,跨账号和跨区域的操作会涉及到更多复杂的签名计算和策略配置,并且在安全性和权限管理上更难以把控。
5.以A企业举例
5.1 A企业原方案
为了减少A企业的业务服务器负担并提高效率,该Web应用被设计为在用户的网页浏览器中直接与<云产品名称>交互,而非所有请求都通过企业的业务服务器中转。
企业A计划采取以下方案搭建Web应用文件直传服务:
由于网页浏览器运行环境完全处于用户端且不受企业A直接控制,企业A面临以下挑战:
密钥泄露的重大风险:网页浏览器归用户所有,并且被视为不可信的环境。若在浏览器中存储RAM用户的访问密钥等敏感信息,则可能会面临密钥意外泄露的显著风险。一旦密钥落入不法分子之手,他们就可能利用这些密钥非法访问企业在云端的敏感数据,导致核心商业机密、客户隐私信息、知识产权及其他关键资产的泄漏,给企业造成不可估量的经济损失和信誉损害。
过度权限的安全漏洞:在为企业的业务服务器应用程序创建RAM用户时,往往需要赋予该用户较高的权限,以便于它可以访问和管理其他云服务。然而,如果用户的访问密钥被存储在浏览器中而后又意外泄露,这将可能导致拥有过多权限的密钥落入恶意攻击者之手。此举不仅增加了企业资源被滥用的概率,还可能带来更严重的问题。黑客可能会使用盗取的密钥在企业的云资源上部署病毒或恶意软件,比如植入后门、植入密码窃取木马程序、以企业资源进行加密货币挖矿等,严重破坏企业的正常业务运营,并对企业的财务和声誉构成严重威胁。
5.2 A企业调整后的方案
为了应对上述风险,企业A可以在原有方案的基础上增加临时授权。通过这种方式,企业A能够在确保数据直传效率的同时,实现以下效果:
增强的身份验证和授权:通过STS生成的具有时间限制的令牌,即便在短时间内泄露,也极大降低了安全风险。因为这些凭证很快就会失效,降低了被不当利用的可能性。
精细化权限控制:STS允许根据最小权限原则配置权限,仅授权Web应用必需的访问权限。这种精细化的权限控制方法限制了潜在泄露的影响范围,防止了过度权限的风险。
企业A最终采取以下方案搭建Web应用文件直传服务:
5.3 编码代码实现
编码实现的参考资料:
上传文件操作方式->使用RestfulAPI 或 使用SDK
上传文件、图片、视频等资源到OSS_对象存储(OSS)-阿里云帮助中心
使用文件url分享文件:
编写代码时对这里有疑问
阿里云工程师答复 可以使用我们提供的credential sdk,和oss client 坐下桥接集成就行了。
通过 provider 机制来桥接我们的 credentail sdk。如果您的应用部署在 ecs 上,那么就可以使用 ecs 的实例角色来实现无AK。credentail sdk 会帮助我们:
1. 基于ECS实例角色获取临时凭证时,不需要开发者关心怎么获取了。
2. Credential sdk会自动维护临时凭证的生命周期,研发人员无需关心临时凭证的到期更新,Credentials sdk会自动保证凭证的周期性更新。
上图截自链接:通过ECS实例角色实现临时凭证的获取和使用-阿里云帮助中心
按照指导将sdk导入IDEA时可能会缺少依赖。建议安装如下依赖。
<!--建议使用最新发布的Credentials版本。-->
<!--获取所有已发布的版本列表,请参见https://github.com/aliyun/credentials-java/blob/master/ChangeLog.txt-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</version>
</dependency>
6. OSS安全的其他一些考虑
6.1 降低因账号密码泄露带来的未授权访问风险
安全问题:
如果因个人或者企业账号密码泄露引发了未经授权的访问,可能会出现非法用户对OSS资源进行违法操作,或者合法用户以未授权的方式对OSS资源进行各类操作,这将给数据安全带来极大的威胁。为此,OSS提供了在实施数据安全保护时需要考虑的多种安全最佳实践。
最佳实践1:修改ACL为私有访问权限
除非您明确要求包括匿名访问者在内的任何人都能读写您的OSS资源,包括存储空间(Bucket)以及文件(Object),否则请勿将Bucket或者Object的读写权限ACL设置为公共读(public-read)或者公共读写(public-read-write)。
鉴于公共读或者公共读写权限对OSS资源带来的数据安全风险考虑,强烈建议您将Bucket或者Object的读写权限设置为私有(private)。设置为私有权限后,只有该Bucket拥有者可以对该Bucket以及Bucket内的Object进行读写操作,其他人均无访问权限。
最佳实践2:避免代码明文使用AccessKey或本地加密存储AccessKey
代码中明文使用AccessKey会由于各种原因的代码泄露导致AccessKey泄露。而本地加密存储AccessKey也并不安全,原因是数据的加解密内容会存放在内存中,而内存中的数据可以被转储。尤其是移动App和PC桌面应用极易出现此类问题,攻击者只需要使用某些注入、API HOOK、动态调试等技术,就可以获取到加解密后的数据。
服务端可以通过阿里云SDK托管凭据插件的方式规避代码明文使用AccessKey,解决因源码或编译产物泄露而导致的AccessKey泄露问题。
最佳实践3:以RAM用户的方式访问OSS
阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维。
创建RAM用户后,您可以控制这些RAM用户对资源的操作权限。当您的企业存在多用户协同操作资源的场景时,可以让您避免与其他用户共享阿里云账号密钥,按需为用户分配最小权限,从而降低企业的信息安全风险。
RAM用户创建完成后,您可以通过RAM Policy为RAM用户授权的方式来集中管理您的用户(例如员工、系统或应用程序),以及控制用户可以访问您名下哪些资源的权限。例如,您可以通过以下RAM Policy阻止指定RAM用户访问目标存储空间examplebucket及examplebucket内的文件或目录。
{
"Version": "1",
"Statement": [
{
"Effect": "Deny",
"Action": "oss:*",
"Resource": [
"acs:oss:*:*:examplebucket",
"acs:oss:*:*:examplebucket/*"
]
}
]
}
最佳实践4:启用多因素认证
多因素认证MFA(Multi Factor Authentication)是一种简单有效的最佳安全实践。启用MFA后,登录阿里云控制台时需要输入账号密码和MFA设备实时生成的动态验证码,在账号密码泄露时也可以阻止未授权访问,提高账号安全性。
最佳实践5:STS临时授权访问OSS
您可以通过STS服务给其他用户颁发一个临时访问凭证。该用户可使用临时访问凭证在规定时间内访问您的OSS资源。临时访问凭证无需透露您的长期密钥,使您的OSS资源访问更加安全。
最佳实践6:Bucket Policy
Bucket Policy是阿里云OSS推出的针对Bucket的授权策略,您可以通过Bucket Policy授权其他用户访问您指定的OSS资源。通过Bucket Policy,您可以授权另一个账号访问或管理整个Bucket或Bucket内的部分资源,或者对同账号下的不同RAM用户授予访问或管理Bucket资源的不同权限。
配置Bucket Policy时,请遵循以下权限最小化原则,从而降低数据安全风险。
-
避免授权整个Bucket
资源授权过大容易导致其他用户数据被非法访问,所以在实际生产业务中请限制指定资源途径,避免授权整个Bucket。
-
不授权匿名访问
允许匿名访问意味着用户只需要知道Endpoint和Bucket名称就可以正常访问OSS,而EndPoint是可以枚举的,Bucket名称也可以从已授权的访问文件URL中提取。由此可见,授权允许匿名访问会带来极大的安全风险。
-
设置合理的Action
通过控制台的图形化配置Bucket Policy时,简单设置中的四类授权操作(Action)仅为用户提供了一种便捷的Policy设置方法,每类Action并不一定完全符合您的业务需求,建议您结合业务需求并通过高级设置的方式给予授权用户最小的权限。例如,生成只读权限往往会包含
oss:ListObjects
、oss:GetObject
等。但是一般场景下的文件下载只需要oss:GetObject
权限即可。 -
启用HTTPS访问
启用HTTPS访问可以解决网络中间人攻击以及域名劫持等问题。另外Chrome浏览器也对HTTP协议进行干预,例如HTTPS站点默认无法加载HTTP资源。基于以上原因,请务必开启HTTPS,以最低成本解决多种风险问题。
-
限定来源的IP地址
如果访问OSS资源的IP地址是固定可枚举的,强烈建议配置IP地址。
参考:如何降低因账号密码泄露带来的未授权访问风险_对象存储(OSS)-阿里云帮助中心
6.2 降低因恶意访问流量导致大额资金损失的风险
安全问题:
当您的存储空间(Bucket)被恶意攻击、流量被恶意盗刷时,会出现高带宽或者大流量突发的情况,进而产生高于日常消费金额的账单。
最佳实践1:修改ACL为私有访问权限
除非您明确要求包括匿名访问者在内的任何人都能读写您的OSS资源,包括存储空间(Bucket)以及文件(Object),否则请勿将Bucket或者Object的读写权限ACL设置为公共读(public-read)或者公共读写(public-read-write)。
鉴于公共读或者公共读写权限对OSS资源带来的数据安全风险考虑,强烈建议您将Bucket或者Object的读写权限设置为私有(private)。设置为私有权限后,只有该Bucket拥有者可以对该Bucket以及Bucket内的Object进行读写操作,其他人均无访问权限。
最佳实践2:通过云监控配置报警规则
当您需要监控OSS资源的使用和运行情况时,可以通过云监控创建阈值报警规则,实现监控指标超过静态阈值或动态阈值后自动发送报警通知的功能,帮助您及时了解监控数据异常并快速进行处理。
例如,您可以为目标存储空间examplebucket配置报警规则,并在报警规则中指定当连续一个周期(1周期=1分钟)出现公网流入流量、公网流出流量、CDN流入流量、CDN流出流量等在其大于或等于100 Mbytes,将告警信息写入日志服务指定的Logstore中。
以公网流入流量大于或者等于100 Mbytes时触发报警为例,其报警规则配置如下:
最佳实践3:配置防盗链
OSS支持对Bucket设置防盗链,即通过对访问来源设置白名单的机制,避免OSS资源被其他人盗用。
防盗链通过请求Header中的Referer地址判断访问来源。当浏览器向Web服务器发送请求的时候,请求Header中将包含Referer,用于告知Web服务器该请求的页面链接来源。OSS根据浏览器附带的Referer与用户配置的Referer规则来判断允许或拒绝此请求,如果Referer一致,则OSS将允许该请求的访问;如果Referer不一致,则OSS将拒绝该请求的访问。
如果防盗链Referer设置为 “https://www.example.com
,且不允许空Referer”。
那么如果用户A在https://www.example.com
嵌入了exampleobject.png图片,当浏览器请求访问此图片时会带上https://www.example.com
的Referer,此场景下OSS将允许该请求的访问。
此时,如果用户B盗用了exampleobject.png的图片并将其嵌入https://example.org
,当浏览器请求访问此图片时会带上https://example.org
的Referer,此场景下OSS将拒绝该请求的访问。
最佳实践4:设置跨域资源共享
跨域资源共享CORS(Cross-Origin Resource Sharing)简称跨域访问,是HTML5提供的标准跨域解决方案,允许Web应用服务器进行跨域访问控制,确保跨域数据传输的安全性。跨域访问是浏览器出于安全考虑而设置的限制,是一种用于隔离潜在恶意文件的关键安全机制。当A、B两个网站属于不同域时,来自于A网站页面中的JavaScript代码访问B网站时,浏览器会拒绝该访问。
OSS支持根据需求灵活配置CORS规则,实现允许或者拒绝相应的跨域请求。例如,您希望仅允许来源为www.aliyun.com
、跨域请求方法为GET
的请求,则CORS规则配置如下:
防盗链和跨域资源共享(CORS)都是阿里云OSS提供的安全机制,用于控制对OSS资源的访问,确保资源不被未经授权的访问或滥用。两者都可以通过OSS控制台或API进行灵活配置,设置访问规则以满足不同的安全需求。
他们的区别是防盗链通过检查HTTP Referer头来限制哪些域名可以访问资源,主要用于防止未经授权的第三方网站直接引用和使用您的资源,如图片和视频。CORS通过设置和检查HTTP头(如Access-Control-Allow-Origin
)来控制跨域访问,主要用于允许合法的跨域资源共享,解决Web应用程序跨域访问的问题,如前后端分离的架构。
最佳实践5:避免使用顺序前缀的方式命名文件
当您上传大量文件时,如果使用顺序前缀(如时间戳或字母顺序)、日期、数字ID等可以被遍历的方式来命名文件,攻击者可通过总结规律以及编写脚本的方式获取全部的文件,最终造成数据泄露。强烈建议您通过向文件名添加十六进制哈希前缀或以反转文件名的方式命名文件,从而有效降低文件名被遍历的风险。
参考资料:
如何降低因恶意访问流量带来的资金损失风险_对象存储(OSS)-阿里云帮助中心
6.3 降低因操作失误等原因导致数据丢失的风险
安全问题:
不小心的误操作导致本不该删除的数据被误删除,从而导致业务无法正常运转。
最佳实践1:为Bucket开启版本控制
版本控制是针对存储空间(Bucket)级别的数据保护功能。开启版本控制后,针对数据的覆盖和删除操作将会以历史版本的形式保存下来。在对象(Object)被错误覆盖或者误删除后,您能够将Bucket中存储的Object恢复至任意时刻的历史版本。
最佳实践2:为Bucket开启跨区域复制
跨区域复制(Cross-Region Replication)是跨不同OSS数据中心(地域)的Bucket自动、异步(近实时)复制文件(Object),它会将Object的创建、更新等操作从源Bucket复制到不同区域的目标Bucket。
跨区域复制功能满足Bucket跨区域容灾或用户数据复制的需求。您可以通过该功能达到数据的跨区域容灾效果,也可以通过将数据保护策略配置为增/改同步来实现误删数据的保护。
当您将源存储空间的所有数据同步到目标存储空间后,如果您误删除了源存储空间中的某个Object,此时您仍然可以从目标存储空间中找回误删除的Object。
最佳实践3:为Bucket设置定时备份
您可以使用OSS的定时备份功能将Bucket内的Object定期备份到云备份(Cloud Backup)中,当Object意外丢失或受损时,可通过云备份(Cloud Backup)及时恢复。
当您为examplebucket配置定时备份后,云备份(Cloud Backup)将按照指定的起始时间备份examplebucket内的所有Object,并按照设置的保留时间策略将备份版本保存在目标备份库中。
在云备份(Cloud Backup)完成一次全量备份后,如果您误删除了examplebucket内的任意Object,可通过云备份(Cloud Backup)控制台创建恢复任务的方式,将examplebucket内的Object恢复至被删除前的版本。
参考资料:
降低因操作失误等原因导致数据丢失的风险_对象存储(OSS)-阿里云帮助中心
6.4 敏感数据安全防护
阿里云对象存储OSS与阿里云数据安全中心DSC(Data Security Center)结合,对敏感数据进行识别、分类、分级和保护。
背景
敏感数据主要包括个人隐私信息、密码/密钥、敏感图片等高价值数据,这些数据通常会以不同的格式存储在您的各类存储系统中。如何更好地发现、定位、保护这些数据,对您的企业非常重要。OSS本身提供了细粒度的权限管理和数据加密等数据安全选项,创建同城冗余存储Bucket、跨区域复制、版本控制等数据保护机制,日志转存和实时日志查询等记录监控与审计能力。若您希望更好的针对敏感数据进行识别、分类、分级和保护,可使用OSS+DSC的方案。
DSC与OSS结合使用,在您完成数据源识别授权后,从您的海量数据中快速发现和定位敏感数据,对敏感数据分类分级并统一展示,同时追踪敏感数据的使用情况,并根据预先定义的安全策略,对数据进行保护和审计,以便您随时了解数据资产的安全状态。
应用场景
-
敏感数据识别
企业拥有大量数据,但无法准确获知这些数据中是否包含敏感信息,以及敏感数据所在的位置。您可以使用OSS结合DSC的方案,利用DSC内置算法规则或根据行业特点自定义规则,对存储在OSS中的数据进行整体扫描、分类、分级,并根据结果做进一步的安全防护。例如利用OSS的访问控制和加密等功能,对数据进行保护。
-
数据脱敏
数据进行对外交换供他人分析或使用时,未进行脱敏处理会导致敏感信息的意外泄漏。OSS与DSC结合的方案,可以支持灵活多样的内置或自定义脱敏算法,可实现生产类敏感数据脱敏后,供开发、测试等非生产环境使用的场景,并确保脱敏后的数据保真可用。
-
异常检测和审计
DSC可通过智能化的检测模型,对访问OSS中敏感数据的行为进行检测和审计。为数据安全管理团队提供相关告警,并基于检测结果完善风险预判和规避方案。参考资料
-
参考资料
7. 最后
本文探讨了OSS客户端签名直传的安全风险及解决方法。我们对比了OSS与文件系统,分析了客户端直传的风险,并提出了多种解决方案,如服务端生成STS临时访问凭证和签名URL。通过A企业案例展示了实际应用效果,并提供了多种OSS安全最佳实践。希望本文能帮助读者更好地理解和应对OSS的安全挑战,保护数据安全。
参考资料: