Những điều bạn ước mình không cần biết về S3
(blog.plerion.com)- Trong các rủi ro rò rỉ dữ liệu AWS, truy cập trái phép vào bucket S3 xuất hiện lặp đi lặp lại; do thiết kế API cũ và các hành vi ngoại lệ, việc đánh giá đơn giản “công khai/riêng tư” trở nên khó khăn
- Nhiều thao tác S3 không được gọi qua endpoint AWS chung mà qua chính URL của bucket; với policy bucket cấu hình sai, ngay cả request
curlkhông xác thực cũng có thể thực hiện các thao tác nguy hiểm - Không thể xem là an toàn chỉ vì đã chặn
s3:ListBucket; các đường nhưListBucketVersions,ListMultipartUploads,fetch-ownercó thể làm lộ object key và định danh tài khoản - Người upload có thể ảnh hưởng đến các thuộc tính object như storage class, tag, Object Lock, một số header liên quan đến redirect, nên cần kiểm soát bổ sung như điều kiện IAM và chính sách vòng đời
- Nếu chỉ nhìn vào ACL và thiết lập chặn truy cập công khai để kết luận là riêng tư, bạn có thể bỏ sót các đường truy cập; người dùng Internet có thể truy cập object S3 thông qua CloudFront distribution hoặc Cognito identity pool
Thiết kế API S3 cũ và lời gọi ẩn danh
- S3 là một trong những dịch vụ AWS đời đầu nên rất vững chắc và được kiểm thử kỹ, nhưng do dấu vết từ trước khi có các mẫu thiết kế chuẩn hóa, nó có dạng API khác với các dịch vụ AWS khác
- Một số API S3 dùng endpoint chung như
s3.us-east-2.amazonaws.com, nhưng nhiều thao tác phải request trực tiếp đến URL bucket mục tiêu- Ví dụ liệt kê bucket có dạng
GET /vớiHost: [bucketname].s3.amazonaws.com - Truy vấn tag của bucket cũng gửi
GET /?taggingđến host của bucket đó
- Ví dụ liệt kê bucket có dạng
- Nhiều dịch vụ AWS như EC2 hay DynamoDB thường dùng endpoint chung và truyền tài nguyên mục tiêu qua HTTP header hoặc tham số
- Bucket S3 hỗ trợ cả truy cập công khai lẫn truy cập có xác thực, nên không phải lúc nào cũng rõ thao tác API nào có thể thực hiện mà không cần xác thực
- Nếu policy bucket mẫu cho phép
Principal: "*"vàAction: "s3:*"trên tài nguyên bucket, request không xác thực cũng có thể xóa bucket- Request ví dụ là
curl -X DELETE https://[bucketname].s3-ap-southeast-2.amazonaws.com
- Request ví dụ là
- Một số thao tác không hỗ trợ request ẩn danh và sẽ trả về lỗi như
s3:GetBucketOwnershipControls does not support Anonymous requests! - Request API ẩn danh được ghi vào CloudTrail dưới tài khoản anonymous
- Nếu là request không xác thực, không thể xác định ai đã xóa bucket, hay ai đã truy vấn cấu hình mã hóa hoặc trạng thái logging
- Có thể kiểm thử các đường như
/?logging,/?tagging,/?encryptionngay cả trong trình duyệt - Cũng có các thao tác như
GetObjectTorrentvẫn còn tài liệu nhưng không thể thực thi nữa
Chỉ chặn ListBucket khó ngăn lộ object key
- Để tải object S3, cần key của từng object; key được dùng như đường dẫn file
- Request
GETđến bucket gốc có thể trả về nội dung bucket tùy điều kiện, nên từ chốis3:ListBuckettrông như một biện pháp phòng vệ phổ biến - Ngay cả khi dùng ACL
public-readcùng với policy từ chốis3:ListBucket, vẫn còn các đường để lấy object keyGET /?versions, tứcs3:ListBucketVersions, trả về metadata của các phiên bản object trong bucketGET /?uploads, tứcs3:ListMultipartUploads, trả về danh sách các multipart upload đang diễn ra
- Tài liệu
HeadBucketcó nội dung nói về việc kiểm tra bucket có tồn tại và quyền truy cập hay không, nhưng trên thực tế nó kiểm tra liệu có quyền thực hiện thao tácListBuckethay không - Nếu chỉ kiểm tra việc
ListBucketcó bị từ chối hay không, bạn có thể bỏ sót khả năng lộ object key S3
Chi phí và rò rỉ từ multipart upload chưa hoàn tất
- Multipart upload bắt đầu bằng
create-multipart-uploadvà upload các phần bằngupload-part - Multipart upload chưa hoàn tất không dễ kiểm tra trong web console; có thể kiểm tra bằng
/?uploadshoặcaws s3api list-multipart-uploads --bucket [bucket-name] - Nếu request hoàn tất không được gửi thành công, Amazon S3 không ghép các phần lại và cũng không tạo object
- Các phần đã upload vẫn nằm trong tài khoản cho đến khi multipart upload hoàn tất hoặc bị hủy
- Các phần được lưu trữ phát sinh chi phí lưu trữ S3
- Chưa tìm thấy cách tải về các phần của object trước khi hoàn tất, nhưng có thể xóa chúng
- AWS khuyến nghị áp dụng quy tắc vòng đời để xóa các upload chưa hoàn tất sau một số ngày nhất định
- Khi liệt kê multipart upload chưa hoàn tất bằng
/?uploads, ARN của principal đã bắt đầu upload sẽ được trả về- Nếu bạn xem các định danh như account ID, ARN là không nhạy cảm thì điều này có thể không phải vấn đề
- Nếu không muốn công khai định danh hữu ích cho kẻ tấn công, có thể xem đây là một dạng rò rỉ
ACL và xác minh tài khoản dựa trên email
- Tài liệu ACL của S3 vẫn còn dấu vết từ thời AWS account được định danh bằng email của root user
- Thao tác
PutBucketACLcó thể chỉ định grantee bằng địa chỉ email- Dùng
Type: AmazonCustomerByEmailvàEmailAddress
- Dùng
- Nếu không có AWS account liên kết với email đã chỉ định, lỗi
UnresolvableGrantByEmailAddresssẽ xảy ra- Thông báo lỗi có dạng “địa chỉ email bạn cung cấp không khớp với bất kỳ tài khoản nào trong hồ sơ”
- Do hành vi này, có thể kiểm tra một địa chỉ email cụ thể có AWS account đã đăng ký hay không
Storage class và metadata object mà người upload có thể chọn
- Storage class của S3 được áp dụng cho object, không phải bucket
- Không có thiết lập ở cấp bucket để cố định storage class mong muốn; chủ thể upload có thể chỉ định storage class của object
- Ví dụ:
aws s3 cp "my.txt" "s3://mybucket/myobject.txt" --storage-class [CLASS]
- Ví dụ:
- Trong danh sách được định nghĩa sẵn, người upload có thể ảnh hưởng đến chi phí lưu trữ và truy cập trên mỗi GB mà chủ bucket phải chịu
- Nếu dùng condition key
s3:x-amz-storage-classtrong IAM policy, có thể giới hạn các storage class được phép- Policy ví dụ chỉ cho phép
STANDARDđối vớis3:PutObject
- Policy ví dụ chỉ cho phép
- Nếu thiết lập chính sách vòng đời, có thể chuyển tất cả object sang một storage class nhất định sau một khoảng thời gian
- Với upload dùng pre-signed URL, AWS Signature Version 4 yêu cầu ký mọi header bắt đầu bằng
X-Amz-- Storage class được chỉ định bằng header
x-amz-storage-class - Nếu ứng dụng không được triển khai cực kỳ sai, không có cách thao túng tức thì rõ ràng
- Storage class được chỉ định bằng header
Tag, Object Lock và redirect cũng nằm trong phạm vi ảnh hưởng của người upload
- Nhiều thuộc tính liên quan đến object S3 do người upload kiểm soát
- Object tag có thể được chỉ định khi upload
- Ví dụ:
--tagging "AllYourTags=AreBelong&To=Us"
- Ví dụ:
- Các hệ thống tự động hóa dựa trên giá trị tag có thể bị ảnh hưởng bởi giá trị tag do người upload tạo
- Object Lock có thể thiết lập lưu giữ object và legal hold nếu object locking được bật trên bucket
- Lệnh ví dụ dùng
--object-lock-retain-until-date "2099-01-01T00:00:00+0000",--object-lock-legal-hold-status "ON",--object-lock-mode "COMPLIANCE"
- Lệnh ví dụ dùng
- Với bucket bật static website hosting, có thể tạo open redirect bằng cấu hình của file được upload
- Cũng cần chú ý đến danh sách đầy đủ các header mà
PutObjecthỗ trợ- Pre-signed URL có các giới hạn
- Trong cấu hình dựa vào Cognito identity và IAM policy, request có thể được ký trong ngữ cảnh Cognito đã xác thực
Rò rỉ chủ bucket và định danh tài khoản
- Để kiểm tra một account ID cụ thể có phải là chủ sở hữu của bucket có thể truy cập hay không, có thể thêm header
x-amz-expected-bucket-ownervào requestListBucket- Nếu đưa account ID sai,
AccessDeniedsẽ được trả về - Nếu đưa account ID đúng và caller có quyền
ListBucket, phản hồi bình thường sẽ được trả về
- Nếu đưa account ID sai,
- Nếu dùng tham số
fetch-owner=truecủa APIListBucket, mỗi key trong phản hồi sẽ bao gồm phần tử Owner IDtrongOwnerlà chuỗi hex 64 ký tự mà tài liệu AWS gọi là canonical user ID- Đây là dạng đã được làm rối của AWS account ID
- Nếu đặt canonical user ID vào
Principalcủa IAM policy dưới dạngCanonicalUser, lưu rồi làm mới, nó sẽ được diễn giải thành AWS account ID ListBucketVersionsvàListMultipartUploadscũng hoạt động tương tự dù không cófetch-owner
Object key S3 trông giống tên file nhưng hoạt động khác
- Object key của S3 phân biệt chữ hoa chữ thường
- Dù tên trông giống nhau, nếu khác chữ hoa chữ thường thì có thể upload nhiều object
- Nếu ứng dụng xử lý object key S3 như tên file không phân biệt hoa thường, có thể phát sinh vấn đề
- Ứng dụng ví dụ lưu mật khẩu người dùng trong file S3 và dùng tên file làm tên người dùng
- Khi đăng ký chỉ kiểm tra file có tồn tại hay không, còn khi đổi mật khẩu thì chuyển tên người dùng sang chữ thường rồi ghi vào file
- Dù
jeffđã tồn tại, vẫn có thể đăng kýJEFF, và người dùngJEFFcó thể ghi đè file củajeffkhi đổi mật khẩu
- Object key S3 có thể dùng bất kỳ ký tự UTF-8 nào
- Một số ký tự có thể gây vấn đề trong một số ứng dụng và giao thức
- Khoảng trắng, dấu gạch chéo, ký tự phần trăm, v.v. cũng là object key hợp lệ
Dù trông như “bucket riêng tư”, vẫn có thể còn đường truy cập
- Ngay cả khi ACL bị tắt, resource policy được đặt hẹp và block public access được bật, bucket vẫn có thể truy cập công khai
- Đường phổ biến nhất là Amazon CloudFront distribution
- Khi đặt CDN trước bucket S3, thường có ý định phân phối nội dung qua Internet
- Công cụ bảo mật có thể đánh giá bucket không công khai nếu resource policy của bucket được giới hạn cho CloudFront
- Trong ví dụ,
get-bucket-policy-statustrả vềIsPublic: false- Request trực tiếp đến bucket trả về
AccessDenied - Gửi cùng request đến domain CloudFront distribution thì nội dung object được trả về
- Request trực tiếp đến bucket trả về
- Cognito identity pool cũng có thể làm lộ bucket có resource policy bị giới hạn
- Sau khi đăng nhập thành công, Cognito cung cấp AWS credential tạm thời của vai trò đã cấu hình sẵn
- Nếu vai trò đó có quyền
s3:ListBucketvàs3:GetObject, người dùng có thể gọi S3 API
- Có hai cấu hình Cognito có thể tương đương truy cập công khai
- Self-registration: nếu người dùng Internet có thể đăng ký và đăng nhập vào app, về thực chất đó là truy cập công khai
- Guest access: cung cấp định danh duy nhất và AWS credential cho người dùng chưa xác thực
- Ví dụ guest access là luồng nhận
IdentityIdbằngget-id, nhận credential tạm thời bằngget-credentials-for-identity, rồi chạyaws s3 lsvới profile đó - CloudFront và Cognito identity pool thực tế được dùng rất nhiều trên Internet, nhưng là các đường truy cập công khai hiếm khi được công cụ bảo mật hiển thị
1 bình luận
Ý kiến trên Hacker News
Có nhiều điểm thú vị, nhưng tôi khó đồng ý với việc xem chuyện hệ thống tệp phân biệt chữ hoa/thường là một điều đáng phàn nàn
Tôi nghĩ vốn dĩ nó nên như vậy, và việc macOS không làm thế mới là điều gây khó chịu
Việc tên tệp phân biệt chữ hoa/thường có thể gây bất ngờ ngay cả với người dùng không rành kỹ thuật. Nếu ai đó nói đã gửi “Book Draft 1.docx” nhưng trong hộp thư lại có “Book draft 1.docx”, thường người ta sẽ không nói “có vẻ bạn gửi nhầm tệp khác rồi?”
Trong văn bản, chữ hoa/thường thường cũng không làm thay đổi ý nghĩa. “Hi, how are you?” và “hi, how are you?” có cùng nghĩa; chữ hoa làm đổi nghĩa chủ yếu khi phân biệt danh từ riêng với danh từ chung, mà đây hiếm khi là mối quan tâm trong tên tệp
Bỏ qua sở thích cá nhân, tôi khó hiểu việc nhà phát triển hay quản trị hệ thống lại ngạc nhiên hoặc khó chịu vì hệ thống tệp phân biệt chữ hoa/thường. Nếu cần, nhà phát triển có thể trừu tượng hóa điều đó cho người dùng cuối, chẳng hạn như trong kết quả tìm kiếm
Nó cũng không giống như lập trình, nơi việc ép code style có thể giúp tăng tính dễ đọc. Ngay cả trong lập trình, trước khi IDE đủ thông minh để bắt lỗi gõ sai tên biến, đây cũng từng là nguyên nhân gây bug. Một trong những điểm tôi thích ở Pascal là, khác với C, nó không buộc phải bận tâm đến chữ hoa/thường
Bạn có thể đặt tên tệp theo phong cách mình muốn và cách viết đó được giữ nguyên, nhưng khi tìm kiếm hoặc xử lý thì không cần nhớ chính xác phong cách đó. Vì tìm kiếm không phân biệt chữ hoa/thường
Phân biệt chữ hoa/thường còn là phần dễ; điều kém trực quan hơn là đường dẫn S3 là giả
S3 chấp nhận tải lên “/builds/1/installer.exe” và cũng hiển thị danh sách trong /builds, nhưng thực tế bạn chỉ tải lên một key tên là '/builds/1/installer.exe' có chứa ký tự '/' trong tên
Vì vậy “/builds/1//installer.exe” và “/builds//1/installer.exe” cũng có thể được tải lên và là các tệp hoàn toàn khác nhau. Chúng chỉ là tên key, không có thư mục thật
[1] https://docs.aws.amazon.com/AmazonS3/latest/userguide/direct...
Năm nay hệ thống vận hành của chúng tôi cũng gặp một bug kỳ lạ, phải 5 người cùng xem mới tìm ra. Nguyên nhân là một object có tên đúng nghĩa là “/”, và phần mềm đã cố xử lý nó như một đường dẫn thay vì một tệp
Khó mà tin dùng S3 hay các dịch vụ AWS khác. Không có gì trực quan, có quá nhiều thành phần chuyển động, và quá nhiều tài liệu phải đọc
Dù vậy, như bài gốc nêu, bạn vẫn có thể vô tình công khai mọi thứ ra thế giới. Tôi thà dùng các dịch vụ thực sự đơn giản như Hetzner Storage Boxes hay DigitalOcean Spaces
Gần đây tôi phát hiện rằng nếu tải lên qua pipe một tệp video lớn hơn vài MB, Location trả về sẽ thiếu https://. Vì vậy với mỗi lần upload tệp, tôi phải kiểm tra xem Location có bắt đầu bằng https không, nếu không thì thêm vào
Đương nhiên, trong issue GitHub của S3 Node client thì họ nói “có vẻ là bug của DigitalOcean”, còn trên forum DigitalOcean thì họ nói “có vẻ là bug của S3 Node client”
Rất nhiều tính năng và điểm đặc thù vốn được thiết kế để hỗ trợ một số tình huống đặc biệt nay đã trở thành một phần của giao thức thông thường. Có vẻ vì lý do kinh doanh, họ cố làm sao để không ai phải quay lưng rời đi
Cũng phải cẩn thận khi xóa hàng chục tỷ đối tượng. Nếu gọi trực tiếp API xóa thì có thể tốn kém
Thay vào đó, có thể thiết lập miễn phí quy tắc vòng đời đặt thời điểm hết hạn là now cho wildcard hoặc cho toàn bộ bucket. Khi đó việc tính phí lưu trữ sẽ dừng ngay lập tức và AWS sẽ tự xử lý việc xóa
Điều này cũng tránh việc máy chủ API S3 bị dội bởi số lượng request mỗi giây quá lớn
Việc các multipart upload thất bại vẫn âm thầm nằm lại, và nếu không cấu hình vòng đời một cách rõ ràng thì còn bị tính cả chi phí lưu trữ, thật sự rất tệ
Tôi cứ tưởng chữ S trong “Simple” là đơn giản
Đề xuất của tôi là các part của upload chưa hoàn tất chỉ tồn tại 24 giờ sau hoạt động cuối cùng, và trong thời gian đó cũng không tính phí lưu trữ. ahenry@ đã bác bỏ điều đó
Trên một máy chủ rất cũ, có một cron script chạy hằng đêm trong gần 10 năm, bắt đầu một multipart upload. Nó dùng để đẩy bản sao lưu vào một bucket, nhưng bucket đó cũng lưu nội dung người dùng upload, nên việc nó lớn lên từng chút mỗi ngày trông có vẻ bình thường
Script ở trạng thái “không hoạt động”, nên chúng tôi không phụ thuộc vào dữ liệu sao lưu; trên S3 cũng không thấy file nào, và kích thước bucket tăng đều nhưng không quá mức. Thế rồi mùa xuân này nhìn lại thì thấy nó đang lưu gần 3TB multipart upload chưa hoàn tất
Tất nhiên tôi biết câu chuyện này đầy rẫy các thực hành tệ
Tôi có cảm giác các cuộc thảo luận về phân biệt/không phân biệt chữ hoa chữ thường nhìn chung quá lấy tiếng Anh làm trung tâm
Nói cách khác, đặc biệt trong IT, các cuộc thảo luận liên quan đến ngôn ngữ quá thường xuyên lấy tiếng Anh làm trung tâm
Nói từ góc nhìn của một người không dùng tiếng Anh làm tiếng mẹ đẻ, trong lập trình đã có quá nhiều khái niệm và yếu tố rồi. Tốt hơn là đừng tăng thêm độ phức tạp bằng cách phải xét tới 101 ngôn ngữ khác
Unicode và múi giờ là những yếu tố tiêu biểu của việc cố xét đến nhiều ngôn ngữ và văn hóa hơn trong lập trình, nhưng kết quả là chúng tạo ra nỗi đau lớn nhất cho tất cả mọi người, kể cả lập trình viên không nói tiếng Anh
Tôi không muốn viết chương trình bằng tiếng mẹ đẻ của mình. Nhất là nếu cái giá phải trả là khi lập trình phải cân nhắc tất cả các ngôn ngữ chính. Việc các thảo luận IT lấy tiếng Anh làm trung tâm là ổn. Đa dạng là phức tạp, còn tiếng Anh không phải ngôn ngữ thuộc sở hữu của ai, mà chỉ là công cụ mọi người dùng để giao tiếp
Nhờ ngôn ngữ chung đó, tôi có thể diễn đạt suy nghĩ của mình với nhiều người ở Ấn Độ, Trung Quốc, Nhật Bản, Nam Mỹ, v.v. Khoảnh khắc họ quyết định nói bằng tiếng Anh, họ cũng sở hữu tiếng Anh. Không cần kéo chính trị đa dạng vào IT; tốt hơn là cứ để ở khía cạnh kỹ thuật
Ở một khía cạnh nào đó, hai hệ chữ âm tiết này có cảm giác giống như bảng chữ cái viết hoa/viết thường
Còn vài điều nữa
Multipart upload không thể thực hiện từ nhiều máy có thông tin xác thực của instance. Lý do là các principal khác nhau nên không thể truy cập multipart upload của nhau. Nếu muốn ghép một multipart upload từ nhiều máy, bạn cần một IAM user thực sự
Các request LIST không chỉ chậm mà còn rất đắt nếu thực hiện với số lượng lớn. Có các cách vòng tránh như “bucket inventory”, nhưng chúng không tiện cũng không rẻ
Việc tạo bucket dùng DNS ở bên trong, nên không có tính nhất quán đọc-sau-ghi. Vì vậy đôi khi bạn không thể truy cập ngay sau khi tạo bucket, hoặc không thể xóa bucket vừa tạo trước khi chờ đủ lâu để thay đổi được lan truyền. Xem https://github.com/julik/talks/blob/master/euruko-2019-no-su...
Có thể tạo đồng thời một object tên “foo” và một object tên “foo/bar”. Khi đó cấu trúc sẽ thành kiểu file ghi đè lên thư mục, khiến dữ liệu trong bucket không thể chuyển sang cấu trúc hệ thống file
S3 phân biệt chữ hoa/chữ thường, nên có thể tạo các object không thể chuyển sang cấu trúc hệ thống file. Kho lưu trữ file của Rails từng bị hỏng nặng trên macOS vì giả định storage có phân biệt chữ hoa/chữ thường, và đã được sửa để luôn dùng định danh chữ thường
Phần lớn cấu hình S3 cho phép GET nhưng không cho phép HEAD. Có vẻ đây là cách để ngăn dò xem object có tồn tại hay không, nhưng tôi không chắc. Dù sao đi nữa, luồng thân thiện với cache để kiểm tra kích thước object bằng request HEAD sẽ không hoạt động, đặc biệt với pre-signed URL. Thay vào đó phải đi vòng bằng GET với Range rất nhỏ, chẳng hạn chỉ lấy byte đầu tiên
Nếu tạo nhiều pre-signed URL, có khả năng tăng tốc độ tạo lên 10–40 lần: https://github.com/WeTransfer/wt_s3_signer
Bạn vẫn phải trả chi phí lưu trữ cho các multipart upload chưa hoàn tất. Cần đặc biệt cẩn thận nếu kiến trúc của bạn cho phép người dùng bắt đầu những upload kiểu này. Có một thiết lập tự động xóa các multipart upload chưa hoàn tất sau một khoảng thời gian; nếu không muốn khổ sở thì nên bật nó
Nghịch lý là S3 từng mang tính cách mạng và hiện vẫn là một sản phẩm tuyệt vời ở nhiều tầng. Chỉ là càng nhiều tính năng thì càng nhiều bẫy
Tôi đã tạo một pipeline hậu xử lý CSV dạng streaming trong Elixir để sửa và chèn cột bằng Stream.transform(https://hexdocs.pm/elixir/Stream.html#transform/3). Các module AWS và CSV của Elixir xử lý dữ liệu streaming đầu vào, nhưng nếu tổng lượng stream đầu ra nhỏ hơn 5MiB thì module AWS vẫn dùng multipart upload, khiến S3 báo lỗi, khá buồn
Có một vấn đề thú vị khác mà tôi và đồng nghiệp đã phân tích trong vài ngày mới chẩn đoán được. Sau khi một kết nối TCP đơn lẻ gửi 100 HTTP request, S3 sẽ lặng lẽ bỏ các request sau đó
https://github.com/aws/aws-sdk-go/issues/2825
Đây là pattern phổ biến khi muốn dùng keep-alive vì hiệu năng, nhưng cũng muốn ngăn client bám quá lâu và tạo hotspot trên load balancer
Một điểm nữa là ở storage class tiêu chuẩn, S3 có độ trễ cao nên không phù hợp để phục vụ web
Nhiều người nghĩ có thể host trực tiếp tài nguyên website như ảnh hoặc font từ S3, nhưng trải nghiệm người dùng có thể tệ đi
“applications can achieve consistent small object latencies (and first-byte-out latencies for larger objects) of roughly 100–200 milliseconds.”
Nguồn: https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimi...
Dùng CloudFront signed cookies, bạn cũng có thể cấp cho một người dùng cụ thể quyền truy cập CDN chỉ tới nội dung thuộc sở hữu của họ trong S3. Khá hay
Có thể cache các tài sản được truy cập thường xuyên để giảm độ trễ, đồng thời cũng giảm chi phí đáng kể
Việc uploader quyết định quy tắc nghe khá dữ dằn. Có phải điều đó nghĩa là với một website cấu hình lỏng lẻo, một người dùng đủ động cơ có thể khiến nội dung người dùng được upload lên Amazon Glacier, rồi sau đó được phục vụ từ đó không?
https://docs.aws.amazon.com/service-authorization/latest/ref...
Đặc biệt, các condition key nằm ở đây; bạn có thể thấy các key kiểm soát quyền truy cập theo storage class, tagging, v.v.
https://docs.aws.amazon.com/service-authorization/latest/ref...