Lập trình 22/09/2026 6 phút

Quản lý bí mật: đừng hardcode, đừng log secret — và một kiểu Secret tự che trong Go

Hai cách rò rỉ bí mật phổ biến nhất không phải do bị hack: hardcode secret vào code (lộ qua git) và vô tình in secret ra log/error/JSON. Bài này đo thật trong Go: một config với mật khẩu kiểu string thường lộ nguyên trong cả log và JSON; một kiểu Secret tự che (override String/MarshalJSON) in ra *** ở mọi nơi nhưng code vẫn dùng được giá trị thật qua Reveal(). Mặc định an toàn thay vì nhớ che từng chỗ.

Lập trình 22/09/2026 9 phút

Broken Access Control: lỗ hổng #1 OWASP và IDOR — vì sao server biết bạn là ai nhưng vẫn để bạn đọc dữ liệu người khác

Đăng nhập xong không có nghĩa được làm mọi thứ. Broken Access Control đứng #1 OWASP Top 10 vì rất dễ dính: server xác thực đúng bạn là ai, nhưng quên kiểm bạn có quyền với ĐỐI TƯỢNG này không. Bài này tái hiện IDOR trong lab cô lập: Alice chỉ đổi một số id trong URL là đọc được đơn hàng nhạy cảm của Bob (HTTP 200); thêm một dòng kiểm sở hữu phía server, cùng request đó trả về 403. Phòng thủ, không tấn công.

Lập trình 22/09/2026 6 phút

gRPC cho backend từ con số 0: gọi hàm từ xa như hàm nội bộ, và Protobuf nhỏ hơn JSON 2 lần

gRPC không phải REST nhanh hơn — nó là một mô hình khác: định nghĩa dịch vụ trong .proto, protoc sinh code type-safe cho cả server lẫn client, chạy trên HTTP/2 với payload nhị phân Protobuf. Bài mở màn sê-ri dựng server+client gRPC thật bằng Go trong Docker, gọi một unary RPC, và đo thật: cùng message Order, Protobuf 41 byte so với JSON 88 byte, 1000 call hết 42ms (~23.800 call/giây localhost).

Lập trình 22/09/2026 6 phút

Protobuf wire format mổ đến từng byte: vì sao nó nhỏ hơn JSON 3,5 lần và message rỗng tốn 0 byte

Protobuf nhỏ hơn JSON không phải nhờ phép màu — mà nhờ ba quyết định thiết kế gọn gàng. Bài này dùng proto.Marshal rồi hexdump từng byte trong go-lab để giải mã: mỗi field là một tag (field_number dịch bit cộng wire_type) rồi tới value, số nguyên mã hoá bằng varint (số nhỏ chỉ 1 byte), và field mang giá trị mặc định không được ghi lên dây chút nào. Kết quả thật: cùng dữ liệu, JSON 46 byte còn Protobuf 13 byte, message rỗng tốn 0 byte.

Lập trình 22/09/2026 5 phút

Bốn kiểu RPC của gRPC: unary, server/client/bidirectional streaming — thứ REST không có sẵn

REST chỉ có một kiểu: một request, một response. gRPC có bốn, nhờ HTTP/2 cho phép streaming hai chiều ngay trong contract. Bài này chạy thật cả bốn trong go-lab: unary Double(21) trả 42; server streaming CountUp(5) trả về 5 message; client streaming SumAll gửi 4 nhận 1 (total=100); bidirectional RunningSum gửi/nhận xen kẽ 3 lần. Chỉ cần thêm từ khoá stream vào .proto, và biết khi nào dùng kiểu nào.

Lập trình 22/09/2026 6 phút

Tiến hoá schema Protobuf: vì sao field number là bất biến, và unknown field cứu dữ liệu qua tay service cũ

Protobuf nhận diện field bằng SỐ chứ không bằng tên — hiểu điều này là hiểu toàn bộ quy tắc tiến hoá schema. Bài này đo thật trong go-lab ba kịch bản: V1 ghi, V2 (thêm field) đọc được, field mới lấy default; V2 ghi có email, service V1 cũ đọc không thấy nhưng GIỮ LẠI email qua round-trip nhờ unknown field; và đổi field number khiến amount biến mất hoàn toàn. Rút ra luật quan trọng nhất của Protobuf.