Rails Activestorage 和 S3,存储敏感数据
Rails Activestorage and S3, storing sensitive data
ActiveStorage可以通过JS中的用户浏览器直接在S3上上传和访问文件。这是否意味着您的 S3 凭据已嵌入到用户浏览器中?我想我误解了,那会使您的凭据几乎 public...
在这种情况下,唯一能阻止任何人访问其他用户数据的是 unique token generation。但是 24 字节的随机密钥很容易被暴力破解。我是否应该通过为每个用户实施与其自身数据相关的唯一密钥来加强安全性?
什么是好的安全架构?
您的 S3 凭据应作为环境变量保存在您的存储库中,而不是硬编码。 Hartls 的书 The Rails Tutorial 中有一个示例。
当您将 ActiveStorage 与 S3 一起使用时。您需要将凭据存储在环境变量中
您需要创建一个文件storage.yml
amazon:
service: s3
access_key_id: ENV["AWS_ACCESS_KEY_ID"]
secret_access_key: ENV["AWS_SECRET_KEY"]
region: ENV["AWS_REGION"]
bucket: ENV["S3_BUCKET"]
一个很好的安全架构,可能这就是在 ActiveStorage 中实现的是:
1- 请求包含上传表单的页面。
2- blob 记录将在服务器端创建并保存到数据库(甚至在任何上传发生之前)。 https://github.com/rails/rails/blob/0718c75bc2a7378d30e729a3c1d25ceb99400b7b/activestorage/app/models/active_storage/blob.rb#L70
3- 服务器在后端调用第三方云服务(例如 AWS S3)并使用 AWS 凭据(秘密凭据,不应暴露给 [=71] 发出预签名 url =]) 用于上传。 https://github.com/rails/rails/blob/master/activestorage/lib/active_storage/service/s3_service.rb#L87
https://www.rubydoc.info/github/aws/aws-sdk-ruby/Aws%2FS3%2FObject:presigned_url
4- 服务器呈现带有表单和嵌入的 presigned_url 的页面。
5- 此时前端将在服务器上生成 presigned_url 并呈现到表单中。
6- Javascript 将从 html DOM 中捕获此 presigned_url 并使用它进行上传。
7- 上传后,javascript 将有 signed_id
将在表单中发布到后端以更新 blob 记录并将其标记为已上传(创建的那个在步骤 1).
优点:
1- 您不需要通过服务器来上传任何文件,这意味着您在上传过程中不会阻塞任何进程并使用客户端计算能力来处理这种简单的任务。
2-后台挂了也可以上传
3- 更快的用户体验(更少的往返)。
缺点:
1- 任何有权访问它的人都可以使用临时令牌进行上传。
2- presigned_url 有有效期 (expires_at) ,如果浏览器在实际上传前长时间闲置,浏览器可能会出现授权错误。它可能需要从服务器发出一个新的临时令牌!?
注:
- 生成的 presigned_url 可以根据经过身份验证的用户限制对特定 folder/scope 的访问,或者如果上传的 blob 是 public,他们可以有权访问整个 bucket/no-scope按业务要求。
这就是 signed uploads
的工作方式:)
ActiveStorage可以通过JS中的用户浏览器直接在S3上上传和访问文件。这是否意味着您的 S3 凭据已嵌入到用户浏览器中?我想我误解了,那会使您的凭据几乎 public...
在这种情况下,唯一能阻止任何人访问其他用户数据的是 unique token generation。但是 24 字节的随机密钥很容易被暴力破解。我是否应该通过为每个用户实施与其自身数据相关的唯一密钥来加强安全性?
什么是好的安全架构?
您的 S3 凭据应作为环境变量保存在您的存储库中,而不是硬编码。 Hartls 的书 The Rails Tutorial 中有一个示例。
当您将 ActiveStorage 与 S3 一起使用时。您需要将凭据存储在环境变量中
您需要创建一个文件storage.yml
amazon:
service: s3
access_key_id: ENV["AWS_ACCESS_KEY_ID"]
secret_access_key: ENV["AWS_SECRET_KEY"]
region: ENV["AWS_REGION"]
bucket: ENV["S3_BUCKET"]
一个很好的安全架构,可能这就是在 ActiveStorage 中实现的是:
1- 请求包含上传表单的页面。
2- blob 记录将在服务器端创建并保存到数据库(甚至在任何上传发生之前)。 https://github.com/rails/rails/blob/0718c75bc2a7378d30e729a3c1d25ceb99400b7b/activestorage/app/models/active_storage/blob.rb#L70
3- 服务器在后端调用第三方云服务(例如 AWS S3)并使用 AWS 凭据(秘密凭据,不应暴露给 [=71] 发出预签名 url =]) 用于上传。 https://github.com/rails/rails/blob/master/activestorage/lib/active_storage/service/s3_service.rb#L87
https://www.rubydoc.info/github/aws/aws-sdk-ruby/Aws%2FS3%2FObject:presigned_url
4- 服务器呈现带有表单和嵌入的 presigned_url 的页面。
5- 此时前端将在服务器上生成 presigned_url 并呈现到表单中。
6- Javascript 将从 html DOM 中捕获此 presigned_url 并使用它进行上传。
7- 上传后,javascript 将有 signed_id
将在表单中发布到后端以更新 blob 记录并将其标记为已上传(创建的那个在步骤 1).
优点:
1- 您不需要通过服务器来上传任何文件,这意味着您在上传过程中不会阻塞任何进程并使用客户端计算能力来处理这种简单的任务。
2-后台挂了也可以上传
3- 更快的用户体验(更少的往返)。
缺点:
1- 任何有权访问它的人都可以使用临时令牌进行上传。
2- presigned_url 有有效期 (expires_at) ,如果浏览器在实际上传前长时间闲置,浏览器可能会出现授权错误。它可能需要从服务器发出一个新的临时令牌!?
注:
- 生成的 presigned_url 可以根据经过身份验证的用户限制对特定 folder/scope 的访问,或者如果上传的 blob 是 public,他们可以有权访问整个 bucket/no-scope按业务要求。
这就是 signed uploads
的工作方式:)