10 điểm bởi GN⁺ 2024-11-05 | 1 bình luận | Chia sẻ qua WhatsApp
  • Việc cân nhắc bảo mật khi viết mã Go là một công việc phức tạp
  • Bài viết đưa ra một số thực hành cụ thể; nếu áp dụng liên tục, chúng sẽ giúp bạn viết mã vững chắc, an toàn và có hiệu năng tốt

Luôn cập nhật phiên bản Go mới nhất

  • Cần giữ phiên bản Go mà dự án sử dụng ở trạng thái mới nhất
  • Ngay cả khi không dùng các tính năng ngôn ngữ mới nhất, việc nâng cấp phiên bản Go vẫn giúp bạn nhận được mọi bản vá bảo mật cho các lỗ hổng đã được phát hiện
  • Các phiên bản Go mới cũng bảo đảm khả năng tương thích với các dependency mới nhất
  • Trên trang lịch sử phát hành Go, bạn có thể kiểm tra bản phát hành Go nào đã khắc phục vấn đề bảo mật và CVE nào, rồi cập nhật lên phiên bản mới nhất trong tệp go.mod của dự án
  • Sau khi nâng cấp phiên bản Go, cần kiểm tra xem có phát sinh vấn đề tương thích hay dependency hay không
  • Có thể dùng trình phân tích mã tĩnh để đánh giá chất lượng và mức độ an toàn của mã

vet

  • Có thể phân tích mã Go bằng lệnh go vet do chính Go cung cấp
  • Khi chạy lệnh go vet mà không có đối số, nó sẽ chạy với tất cả các tùy chọn mặc định được cho phép
  • Công cụ sẽ quét mã nguồn và báo cáo các vấn đề tiềm ẩn
  • Các vấn đề phổ biến nhất gồm lỗi goroutine, biến không được sử dụng, vùng mã không thể truy cập, v.v.

staticcheck

  • Staticcheck, một linter của bên thứ ba, giúp tìm bug, phát hiện vấn đề hiệu năng và áp dụng cả phong cách ngôn ngữ Go
  • Công cụ giải thích các vấn đề được phát hiện và đề xuất cách sửa kèm ví dụ
  • Ngoài việc chạy trong pipeline CI, bạn cũng có thể cài dưới dạng tệp thực thi độc lập để quét mã cục bộ
  • Hãy kiểm tra phiên bản đã cài và xác nhận rằng công cụ đã sẵn sàng để chạy quét
  • Nếu chạy không có đối số, mặc định nó sẽ gọi tất cả bộ phân tích mã
  • Xem ví dụ về những gì có thể phát hiện trong kho GitHub NGINX Agent
  • Kết quả quét có thể được chia thành 3 nhóm: package/method/function đã deprecated, biến/trường không dùng đến, và các vấn đề liên quan đến chất lượng mã

golangci-lint

  • Có thể cài golangci-lint bằng lệnh go install
  • Hãy kiểm tra phiên bản để xác nhận việc cài đặt đã thành công
  • Khi gọi mà không có đối số, tất cả linter sẽ được chạy
  • Kiểm tra xem công cụ hiển thị những cảnh báo và đề xuất nào trong kho agent đã sao chép trước đó
  • Linter sẽ chỉ ra chính xác tệp và dòng liên quan
  • Hãy đánh giá mã, chỉnh sửa, rồi chạy lại linter và thực thi toàn bộ unit test
  • Nếu test đều vượt qua, hãy commit mã đã cập nhật và push lên remote

Phát hiện race condition

  • Race condition có thể xảy ra khi nhiều goroutine cố truy cập cùng một tài nguyên đồng thời
  • Nó được phát hiện khi có ít nhất một goroutine cố thay đổi tài nguyên đó
  • Go hỗ trợ sẵn việc kiểm thử các trạng thái này bằng công cụ test cùng đối số -race
  • Trình phát hiện race chỉ đánh giá phần mã thực sự được chạy và bỏ qua các nhánh mã không được thực thi, vì vậy trước tiên nên chạy trình phân tích mã tĩnh để bảo đảm không có dead code
  • Chạy test song song sẽ làm tăng khả năng phát hiện các vấn đề đồng thời

Quét mã nguồn để tìm lỗ hổng

govulncheck

  • Đây là công cụ quét codebase đối chiếu với các lỗ hổng đã biết được liệt kê trong cơ sở dữ liệu CVEs
  • Công cụ do nhóm Go phát triển, và một cơ sở dữ liệu chuyên về lỗ hổng Go cung cấp thông tin cho bộ quét
  • Sau khi cài phiên bản mới nhất, hãy thử các chức năng cơ bản
  • Sao chép kho habit rồi chạy công cụ từ thư mục gốc
  • Không phát hiện lỗ hổng nào
  • Khi quét tệp nhị phân, có thể phát hiện ra những lỗ hổng khác
  • Hãy nâng cấp Go lên phiên bản mới nhất, lấy các dependency, rồi xác nhận phần mềm và dependency không chứa CVE

gosec

  • Đây là trình phân tích mã tĩnh giúp tìm ra các cấu hình mã không an toàn
  • Có thể chạy trên máy cục bộ hoặc trong pipeline CI bằng GitHub Action
  • Công cụ có nhiều tùy chọn và danh sách quy tắc khác nhau để cấu hình việc quét
  • Sau khi sao chép kho GitHub chứa mã Go cần quét, hãy bắt đầu quét từ thư mục gốc
  • Trong báo cáo quét, bạn có thể xem danh sách các vấn đề tiềm ẩn được sắp xếp theo mức độ nghiêm trọng và độ tin cậy
  • Hãy kiểm tra CWE được báo cáo và tìm hiểu chi tiết về các điểm yếu được liệt kê

Fuzzing

  • Đây là phương pháp cuối cùng để kiểm tra chất lượng mã và phát hiện lỗ hổng
  • Đó là một dạng kiểm thử tự động đặc biệt, thao tác dữ liệu đầu vào được tạo ngẫu nhiên bằng cách sử dụng phạm vi bao phủ kiểm thử của mã
  • Phương pháp này rất hữu ích để tìm các lỗi bảo mật tiềm ẩn như buffer overflow, SQL injection, tấn công DoS, tấn công XSS, v.v.
  • Vì nhiều tổ hợp đầu vào được tạo tự động, nhà phát triển không cần tự nghĩ ra hàng trăm hay hàng nghìn tổ hợp dữ liệu đầu vào

1 bình luận

 
GN⁺ 2024-11-05
Ý kiến trên Hacker News
  • govulncheck là công cụ kiểm tra liệu mã dễ bị tổn thương có thực sự có thể bị truy cập hay không, nên hữu ích hơn việc chỉ kiểm tra các dependency của chương trình
  • Đừng quên tham khảo dự án capslock của Google
  • Có kèm theo những mẹo hữu ích về go vetgo test -race
  • Go không an toàn về bộ nhớ, nhưng dễ viết mã an toàn hơn so với nhiều ngôn ngữ khác
    • Nhờ cú pháp rõ ràng của Go, có thể dễ dàng hiểu được hành vi của hàm và cấu trúc dữ liệu
    • Lý do các công cụ AI hoạt động tốt với Go là vì ngữ cảnh bên trong hàm rất rõ ràng
  • Semgrep là một công cụ tuyệt vời thực hiện các kiểm tra cho ngôn ngữ và framework phổ biến thông qua phân tích tĩnh
    • Có thể xem các quy tắc mở của Semgrep trên GitHub
  • Có ý kiến đặt câu hỏi về danh tiếng bảo mật của Go
    • Go nhìn chung được xem là an toàn và ổn định, ở mức tương tự các công cụ khác như .NET
  • Vừa biết thêm về gosec
  • Trong 9 năm bảo trì ứng dụng Go, có thể nâng cấp phiên bản Go và module một cách dễ dàng
    • GitHub tự động thông báo lỗ hổng, và trong 99% trường hợp mọi thứ vẫn hoạt động mà không cần thay đổi
  • Go thực ra không an toàn về bộ nhớ
    • Tính nguyên tử chỉ được đảm bảo với các giá trị có kích thước một word; các giá trị hai word như con trỏ interface hoặc slice có thể làm tổn hại đến tính an toàn bộ nhớ trong môi trường đồng thời
  • Go thì tốt, nhưng gần đây việc dùng generics ngày càng nhiều đang làm giảm tính dễ đọc của mã
    • So với mã Go trước đây hầu như không dùng generics, giờ đọc khó hơn nhiều