Website được lưu trữ trên Bluesky
(danielmangum.com)- Daniel Mangum cho thấy rằng bằng cách tận dụng cấu trúc tải blob lên và tham chiếu record của AT Protocol, có thể phục vụ tệp
text/htmlđược tải lên Bluesky PDS như một trang web mở trong trình duyệt - Điểm mấu chốt là blob đã tải lên không được công khai ngay; chỉ khi một record tham chiếu đến blob thì PDS mới chuyển nó sang trạng thái có thể truy cập công khai
- Embed hình ảnh Bluesky thông thường chỉ cho phép MIME type
image/*, nhưng record của lexicon chưa biết hoặc embed tùy chỉnh dựa trên open union vẫn có thể lưu tham chiếu đến blobtext/html getBlobcó thể truy cập mà không cần xác thực, và yêu cầu tớibsky.socialsẽ được chuyển hướng đến PDS thực làporcini.us-east.host.bsky.networkđể trả về HTML- Bluesky áp dụng header CSP và
nosniffchogetBlob, đồng thời giới hạn tải blob mặc định ở 5MB, nhưng dịch vụ vận hành PDS vẫn phải gánh rủi ro lưu trữ tệp tùy ý cùng chi phí lưu trữ và truyền tải
Cách tải một website lên bằng blob của AT Protocol
- Trường hợp này dựa trên cách hoạt động của AT Protocol và API PDS hơn là tính năng thông thường của ứng dụng Bluesky
- Bluesky cung cấp PDS entryway để truy cập PDS của người dùng, đồng thời phơi bày nhiều instance PDS qua tên miền
bsky.social - Cũng có thể truy cập trực tiếp từng instance PDS, và website ví dụ được mở qua endpoint
com.atproto.sync.getBlobtrênporcini.us-east.host.bsky.network - Tác giả đã trao đổi với đội ngũ Bluesky trước khi công bố bài viết; đây không phải cách dùng ứng dụng theo chủ đích nhưng là hành vi đã được biết đến, và không thuộc quy trình công bố lỗ hổng
Vì sao records và blobs được tách riêng
- Trong AT Protocol, dữ liệu ứng dụng được chia lớn thành records và blobs
- records là các thực thể cốt lõi do người dùng tạo ra, có thể mang cấu trúc và metadata
- blobs là dữ liệu phi cấu trúc lớn hơn như hình ảnh, và thường chỉ được lộ ra khi có record tham chiếu đến
- Khi tạo một bài đăng có ảnh trên Bluesky, với người dùng mọi thứ trông như một thao tác duy nhất, nhưng ở cấp API thì việc tải blob và tạo record là tách rời
- Theo blob specification, blob phải được tải lên PDS trước khi được record tham chiếu
- Tại thời điểm tải lên, server không biết blob sẽ được dùng trong Lexicon nào, nên ban đầu chỉ áp dụng các giới hạn blob chung, rồi áp dụng các ràng buộc dựa trên Lexicon ở thời điểm tạo record
- Blob tải lên thành công sẽ đi vào vùng lưu trữ tạm thời; ở trạng thái này nó không thể được tải xuống hay phân phối, và cũng không xuất hiện trong kết quả
listBlobs - Khi tạo record thành công và record đó tham chiếu blob, server sẽ chuyển blob sang trạng thái có thể truy cập công khai
Tải blob HTML lên và chuyển sang công khai
- Token xác thực được lấy bằng cách đổi thông tin đăng nhập người dùng qua phương thức XRPC
com.atproto.server.createSession - Trong ví dụ,
com.atproto.sync.listBlobsđược dùng để kiểm tra số blob hiện có, và trước khi tải lên con số là391 - Nội dung website là một tệp
index.htmlđơn giản và được tải lên bằngcom.atproto.repo.uploadBlobContent-Typelàtext/html- Metadata blob trả về gồm CID
bafkreic5fmelmhqoqxfjz2siw5ey43ixwlzg5gvv2pkkz7o25ikepv4zeq,mimeType: text/html,size: 268
- Ngay sau khi tải lên, thử lấy bằng
com.atproto.sync.getBlobthì chưa thể truy cập, và số lượnglistBlobsvẫn giữ ở391 - Nếu tham chiếu blob HTML bằng embed ảnh của bài đăng Bluesky, schema
app.bsky.embed.imagesẽ thất bại vì yêu cầu MIME typeimage/*- Nếu để nguyên
text/htmlsẽ gặp lỗiWrong type of file. It is text/html but it must match image/*. - Nếu đổi
mimeTypethànhimage/jpegsẽ gặp lỗi do MIME type của blob đã lưu khác với MIME type được tham chiếu
- Nếu để nguyên
Công khai blob bằng record lexicon chưa biết
- Kiểu blob không phải riêng của Bluesky mà là một phần của mô hình dữ liệu AT Protocol
- Triển khai Bluesky PDS là mã nguồn mở, và
findBlobRefstìm tham chiếu$type: blobbằng cách duyệt đệ quy quaLexValue - PDS phải hỗ trợ các lexicon mới theo thời gian, nên cũng phải xử lý được cả các lexicon mà nó chưa biết
- Khi tạo một record kiểu
com.danielmangum.hack.websitevà tham chiếu blob HTML, PDS đã lưu record đó- Phản hồi có chứa
validationStatus: unknown - Do PDS không biết lexicon
com.danielmangum.hack.*nên không thể xác thực, nhưng vẫn cho phép lưu record
- Phản hồi có chứa
- Sau đó số lượng
listBlobstăng lên392, xác nhận blob đã được lưu bền vững getBlobcó thể được gọi mà không cần token xác thực, vì các chủ thể không xác thực nhưng cần xử lý blobs cùng records vẫn phải có khả năng lấy blob- Lệnh gọi
getBlobtrênbsky.socialtrả về chuyển hướng 302 tới URL PDS thực, và nếu theo chuyển hướng bằng-Lthì nội dung HTML được trả về nguyên vẹn
Header bảo mật, CDN và gánh nặng của truy cập trực tiếp
- Security Considerations trong đặc tả blob của AT Protocol bàn về rủi ro bảo mật nội dung khi phục vụ các tệp do người dùng tải lên từ web server
- Ví dụ điển hình là vấn đề XSS khi script hoặc nội dung SVG chạy trong cùng origin
- Việc áp dụng Content Security Policy cho endpoint
getBlobgần như là bắt buộc - Cách cung cấp trực tiếp kho blob cho trình duyệt và web agent trên thực tế không được hỗ trợ; ứng dụng cần đi qua CDN riêng, proxy hoặc dịch vụ web khác
- Handler
getBlobcủa Bluesky PDS áp dụng các header bảo mật được khuyến nghịx-content-type-options: nosniffcontent-security-policy: default-src 'none'; sandbox
- Giới hạn tải blob mặc định là 5MB
- Blob ảnh thông thường trong ứng dụng Bluesky không được phục vụ trực tiếp từ PDS mà qua URL CDN của
cdn.bsky.app- Có URL thumbnail cho feed và URL kích thước đầy đủ riêng biệt
- Record bài đăng chứa CID hình ảnh, và ứng dụng phải biết cách CDN phục vụ chúng
- Truy cập trực tiếp qua
getBlobvẫn được giữ lại trong GitHub issue vì nhu cầu gắn nhãn hình ảnh, export nội dung người dùng và các trường hợp sử dụng tương lai- Cùng thảo luận đó cũng đề cập khả năng người dùng hotlink nội dung hoặc dùng Bluesky như dịch vụ hosting miễn phí
- Bản triển khai ban đầu không có header bảo mật và về sau mới được bổ sung
- Các nền tảng mạng xã hội truyền thống giới hạn chặt hơn loại nội dung hợp lệ nên có thể siết blob mạnh hơn ngay lúc tải lên, nhưng tính mở rộng của Bluesky và AT Protocol đòi hỏi xử lý phức tạp hơn
Đưa embed tùy chỉnh vào bài đăng bằng open union
- Kiểu
app.bsky.feed.postđịnh nghĩa danh sách embed hợp lệ bằng union - Trong lexicon của AT Protocol, union mặc định là open nếu không được đánh dấu rõ là
closed- Vì các bản sửa đổi schema trong tương lai có thể thêm kiểu mới, nên implementation cần xác thực theo hướng khoan dung
- Nếu có cờ
closedthì tập kiểu sẽ được cố định
- Union embed của bài đăng Bluesky không được đánh dấu
closed - Vì vậy vẫn có thể tạo bài đăng với
$typeembed không được liệt kê - Trong ví dụ, một embed
com.danielmangum.hack.sitesđược đặt vào recordapp.bsky.feed.post, và bên trong nó tham chiếu blob HTMLvalidationStatustrong phản hồi làvalid- Trong ứng dụng Bluesky, embed đó bị bỏ qua một cách im lặng
- Tuy vậy record vẫn lưu bền nội dung và tham chiếu, nên các ứng dụng khác có thể render embed này
- Đặc tính lexicon như vậy có thể được tận dụng để gắn các mở rộng nhỏ lên trên các trường hợp dùng sẵn có; ví dụ được nêu là chạy các đoạn mã nhỏ trong bài đăng bên trong sandbox WebAssembly
1 bình luận
Ý kiến trên Hacker News
Cảm ơn Daniel đã trực tiếp hỏi đội ngũ, và blob hosting là lĩnh vực chắc chắn sẽ còn phải tiếp tục điều chỉnh khi họ hiểu rõ hơn về các con đường bị lạm dụng
Hiện giờ, việc thấy kiểu ứng dụng này thực sự chạy được khá thú vị, và PDS được thiết kế với chủ đích để database host trở thành thứ tương tự như web server lưu trữ website
Ngày trước rất vui khi nghịch nó, và tôi không biết nó đã chuyển sang Bluesky, khá thú vị
Bsky đã hỗ trợ cách gắn tên miền người dùng làm ALIAS tới redirect.bsky.com: https://bsky.app/profile/jacob.gold/post/3kh6rnpdzmp2v
Tôi tò mò nó chạy trong ngữ cảnh bảo mật nào nên đã kiểm tra URL blob của PDS bằng
curl, và trong header phản hồi cóaccess-control-allow-origin: *,content-security-policy: default-src 'none'; sandbox,x-content-type-options: nosniffv.v.access-control-allow-origin: *nghĩa là JavaScript trên trang web ở bất kỳ tên miền nào cũng có thể dùngfetch()để truy cập nội dung này, điều này khá thú vị, còndefault-src 'none'; sandboxlà cấu hình rất hạn chế, chặn việc tải thêm script hay hình ảnh và cũng chặn luôn việc thực thi JavaScript, nên khá ổn: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Co...ratelimit-limit: 3000có lẽ là giới hạn theo IPViệc đề xuất dùng WebAssembly ở cuối bài là đúng hướng, còn vấn đề click link có thể bị giới hạn bằng cách đặt mã không đáng tin cậy vào iframe và để phía cha dùng
child-srcchỉ cho phép một số tên miền nhất định hoặcdata:https://github.com/w3c/webappsec/issues/656#issuecomment-246...
https://www.w3.org/TR/CSP3/#exfiltration
sandboxthì có còn cầndefault-srcnữa không, hay đây là thiết lập trùng lặpTôi khá hào hứng với khả năng dùng Bluesky làm kho lưu trữ dữ liệu blob
Tôi và một người bạn đã nghĩ tới việc lưu DOOM WAD trên Bluesky để chia sẻ “map pack” như các bài đăng, và nếu theo dõi tài khoản, danh sách, starter pack thì có lẽ có thể sửa một client như GZDoom để nó tìm và xem các WAD do những tài khoản đó đăng lên
Giống Steam Workshop, nhưng đi qua Bluesky
Tôi cũng không rõ Bluesky đã từng nhắc đến hướng dẫn sử dụng kho blob hay chưa; file DOOM là ví dụ hay vì nhỏ, nhưng tôi cũng tò mò liệu nó có thể bị lạm dụng theo kiểu đẩy chi phí lưu trữ máy chủ dung lượng lớn ra bên ngoài không
Tôi không trực tiếp sống trong đúng thời kỳ đó, nhưng việc người dùng BlueSky lao vào phần nước sâu kỹ thuật làm tôi nhớ đến thời mọi người lần đầu học HTML trên MySpace
Thị trường mạng xã hội giờ đã bão hòa hơn rất nhiều, nhưng tôi tự hỏi liệu từ BlueSky có thể xuất hiện một thế hệ lập trình viên mới không
Bluesky chỉ cung cấp bước đầu tiên, và từ đó trở đi có vẻ là một cú nhảy khá lớn
Nếu là HTTP/HTML thì có thể chỉ cho người chỉ biết Python cơ bản hoặc ngôn ngữ lập trình khác cách dựng một server từ đầu trong vòng 14 phút
Tôi cho rằng cần giao thức truyền thông định địa chỉ bằng hash để các công ty công nghệ lớn không thể bóc lột cộng đồng, nhưng không chắc AT Protocol có đặt mục tiêu chuẩn đến mức tạo ra một cuộc cách mạng như HTTP hay không
Một trong những điểm mấu chốt ở đây là PDS được nói tới không phải chính sản phẩm Bluesky mà là một phần của Personal Data Server, nên rốt cuộc nó có thể trông như kho lưu trữ dữ liệu miễn phí vô hạn
Dịch vụ thuê bao mà đội ngũ Bluesky thỉnh thoảng nhắc tới có vẻ có thể liên quan đến chỗ này, và kiểu hosting cung cấp thêm dung lượng, băng thông, video chất lượng cao hơn trên PDS có vẻ rất phù hợp để bán dưới dạng gói premium
Vì có thể host ở nơi khác nên việc nói có thể tương tác vượt ra ngoài ứng dụng Bluesky nghe vẫn có lý
Có vẻ nên có một cái tên cho hiện tượng: hễ tạo ra thứ gì đó cho phép đưa nội dung lên Internet, sớm muộn cũng sẽ có người thử dùng nó để lưu trữ tệp tùy ý
Hồi còn không giới hạn, đã có khá nhiều dự án mã nguồn mở tìm cách sao lưu cả hệ thống tệp vào Gmail và các dịch vụ tương tự; sau khi Drive xuất hiện thì chuyện này còn nghiêm trọng hơn
Các dịch vụ miễn phí cần đặt giới hạn mặc định ngay từ đầu vì có thể đoán trước kiểu vấn đề này sẽ xảy ra
https://en.wikipedia.org/wiki/Inner-platform_effect
Nếu thấy chủ đề này thú vị thì atfile cũng đáng xem: https://github.com/electricduck/atfile
Khá hay, và có thể xem ngay issue GitHub thú vị được liên kết ở cuối bài
pfrazee, một nhân vật nổi tiếng của Bluesky, cũng xuất hiện ở đó: https://github.com/bluesky-social/atproto/issues/523
Mình đặt nhiều kỳ vọng vào AT, và hẳn trong Fediverse cũng có nhiều người thông minh đã làm những việc tuyệt vời, nhưng mô hình này có vẻ bền vững và thực tế hơn
Mặc định cung cấp theo kiểu tập trung, nhưng khi cần hoặc với người dùng nâng cao thì hỗ trợ phi tập trung thực sự
Cần có cách tạo lợi nhuận từ việc mirror firehose; chẳng hạn một lựa chọn thay thế Discord nơi một số người dùng trả tiền để lưu trữ video dài hơn, một cấu trúc kiểu Patreon nơi relay quản lý khóa truy cập và giải mã rồi thu phí, hay một chợ xã hội kiểu Bandcamp cũng có vẻ khả thi
Dù sao đây cũng là một nền tảng mở, nên ngay bây giờ cũng không có lý do gì để không làm
https://www.blockchaincapital.com/blog/bluesky-13m-users-and...
https://bsky.social/about/blog/09-11-2024-video
Có cảm giác cách này sẽ bị lạm dụng cho phishing hoặc phát tán mã độc
Hễ tạo một trang lưu trữ thì gần như chắc chắn sẽ có người dùng nó vào mục đích xấu; điều này gần như là một định luật của điện toán
Matrix attachments cũng từng gặp đúng vấn đề này
*.bsky.networksẽ bắt đầu bị Google Safe Browsing, Palo Alto, Bluecoat và những bên khác chặnĐây là liên kết trực tiếp đến máy chủ Bluesky của tác giả, tức PDS, nên dĩ nhiên là thứ nằm trong quyền kiểm soát của tác giả
Nhìn vào thay đổi API gần đây của Strava, mình lại nghĩ đến việc quyền truy cập dữ liệu được lưu trên nền tảng của họ bị hạn chế đến mức nào
Với vị thế là dịch vụ thống trị trong lĩnh vực fitness, họ hoàn toàn có thể dần dần đưa các tính năng ra sau bức tường thuê bao
Dù có những lo ngại về quyền riêng tư và an toàn, mình vẫn tự hỏi liệu AT Protocol có thể phù hợp làm nền tảng lưu trữ cho tệp GPX hay FIT hay không
Tuy vậy, theo mình biết thì AT Protocol vẫn chưa hỗ trợ bài đăng riêng tư hoặc chỉ chia sẻ hạn chế, và với Strava thì đây có vẻ là một tính năng khá cốt lõi