1. Tổng quan
Kỹ thuật mã nguồn bảo mật là một tập hợp các phương pháp có thể dùng để cải thiện tính bảo mật của mã nguồn. Các kỹ thuật này có thể giúp xác định và khắc phục lỗ hổng trong mã nguồn, ngăn chặn truy cập trái phép vào mã nguồn và bảo vệ mã nguồn không bị sửa đổi.
Sau đây là một số kỹ thuật mã nguồn bảo mật phổ biến:
- Tìm lỗi mã nguồn: Tìm lỗi mã nguồn là quá trình kiểm tra mã nguồn để tìm lỗi và vấn đề về kiểu. Bạn có thể thực hiện việc này bằng cách sử dụng công cụ tìm lỗi mã nguồn. Đây là một chương trình phân tích mã nguồn và xác định các vấn đề tiềm ẩn. Bạn có thể dùng công cụ tìm lỗi mã nguồn để kiểm tra nhiều loại lỗi, bao gồm lỗi cú pháp, lỗi ngữ nghĩa, lỗi kiểu và lỗ hổng bảo mật.
- Kiểm thử bảo mật ứng dụng tĩnh (SAST): SAST là một loại hình kiểm thử bảo mật phân tích mã nguồn, mã nhị phân hoặc mã byte để xác định các lỗ hổng bảo mật. Bạn có thể sử dụng các công cụ SAST để tìm lỗ hổng trong nhiều ngôn ngữ lập trình, bao gồm Go, Java, Python, C++ và C#.
- Quét giấy phép: Quét giấy phép là quá trình xác định giấy phép của các thành phần phần mềm bên thứ ba được sử dụng trong một ứng dụng phần mềm. Điều này rất quan trọng vì giúp đảm bảo rằng ứng dụng tuân thủ các điều khoản của giấy phép, nhờ đó có thể tránh được các vấn đề pháp lý.
Bạn có thể sử dụng các kỹ thuật này để cải thiện tính bảo mật của mã nguồn ở tất cả các giai đoạn của vòng đời phát triển phần mềm. Bạn có thể dùng công cụ tìm lỗi mã nguồn để xác định lỗi sớm trong quá trình phát triển, dùng công cụ tìm lỗi bảo mật mã nguồn để tìm lỗ hổng trước khi biên dịch hoặc triển khai mã và dùng tính năng quét giấy phép để đảm bảo ứng dụng tuân thủ các điều khoản của giấy phép.
Việc sử dụng các kỹ thuật này có thể giúp cải thiện tính bảo mật của mã nguồn và giảm nguy cơ xảy ra sự cố bảo mật.
Kiến thức bạn sẽ học được
Lớp học này sẽ tập trung vào các công cụ và kỹ thuật để bảo mật mã nguồn phần mềm.
- Tìm lỗi mã nguồn
- Kiểm thử bảo mật ứng dụng tĩnh
- Quét giấy phép
Tất cả các công cụ và lệnh dùng trong lớp học này sẽ được thực hiện trong Cloud Shell.
2. Cách thiết lập và các yêu cầu
Thiết lập môi trường theo tốc độ của riêng bạn
- Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.
- Tên dự án là tên hiển thị cho người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn có thể cập nhật thông tin này bất cứ lúc nào.
- Mã dự án là duy nhất trên tất cả các dự án Google Cloud và không thể thay đổi (không thể thay đổi sau khi đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm đến chuỗi này. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (thường được xác định là
PROJECT_ID
). Nếu không thích mã được tạo, bạn có thể tạo một mã ngẫu nhiên khác. Ngoài ra, bạn có thể thử dùng tên của riêng mình để xem tên đó có được chấp nhận hay không. Bạn không thể thay đổi thông tin này sau bước này và thông tin này sẽ được giữ nguyên trong suốt thời gian diễn ra dự án. - Xin lưu ý rằng có một giá trị thứ ba là Mã dự án mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu.
- Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API trên Cloud. Việc tham gia lớp học lập trình này sẽ không tốn kém nhiều chi phí, nếu có. Để tắt các tài nguyên để không bị tính phí sau khi hoàn tất hướng dẫn này, bạn có thể xoá các tài nguyên đã tạo hoặc xoá toàn bộ dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.
Khởi động Trình chỉnh sửa Cloud Shell
Lớp học này được thiết kế và kiểm thử để sử dụng với Trình chỉnh sửa Google Cloud Shell. Cách truy cập vào trình chỉnh sửa:
- Truy cập vào dự án của bạn trên Google tại https://console.cloud.google.com.
- Ở góc trên cùng bên phải, hãy nhấp vào biểu tượng trình chỉnh sửa shell trên đám mây
- Một ngăn mới sẽ mở ra ở cuối cửa sổ
- Nhấp vào nút Open Editor (Mở trình chỉnh sửa)
- Trình chỉnh sửa sẽ mở ra với trình khám phá ở bên phải và trình chỉnh sửa ở khu vực trung tâm
- Một ngăn dòng lệnh cũng sẽ xuất hiện ở cuối màn hình
- Nếu thiết bị đầu cuối KHÔNG mở, hãy sử dụng tổ hợp phím `ctrl+`` để mở một cửa sổ thiết bị đầu cuối mới
Thiết lập môi trường
Đặt GOPATH thành một thư mục duy nhất để đơn giản hoá các lệnh dùng trong lớp học này.
export GOPATH=$HOME/gopath
Tạo một thư mục để lưu trữ công việc của chúng ta
mkdir -p workspace
cd workspace
Sao chép kho lưu trữ mã nguồn
git clone https://gitlab.com/gcp-solutions-public/shift-left-security-workshop/source-code-lab.git
cd source-code-lab
export WORKDIR=$(pwd)
3. Tìm lỗi mã nguồn
Tìm lỗi mã nguồn được dùng để kiểm tra các lỗi hoặc khiếm khuyết phổ biến liên quan đến cú pháp dựa trên kiểu. Công cụ tìm lỗi mã nguồn hỗ trợ bảo mật bằng cách cung cấp một mẫu cú pháp chung cho nhiều nhóm, giúp việc xem xét mã nhanh hơn, chia sẻ kiến thức và làm rõ mã.
Ngoài ra, tính năng Tìm lỗi mã nguồn sẽ xác định các lỗi cú pháp phổ biến có thể dẫn đến các lỗ hổng phổ biến, chẳng hạn như việc sử dụng thư viện hoặc API cốt lõi không đúng cách hoặc kém hiệu quả.
Cài đặt công cụ liên kết staticcheck
go get honnef.co/go/tools/cmd/staticcheck@latest
Chạy Trình tìm lỗi mã nguồn Go (staticcheck) trong thư mục gốc của dự án
staticcheck
Xem lại kết quả
main.go:42:29: unnecessary use of fmt.Sprintf (S1039)
Bạn gặp lỗi này vì http.ListenAndServe()
chấp nhận một Chuỗi và mã hiện tại sử dụng Sprintf
mà không truyền biến vào chuỗi
Xem lại trạng thái thoát lệnh.
echo $?
Trong trường hợp này, vì lệnh này dẫn đến lỗi, nên trạng thái thoát sẽ là 1 trở lên. Đây là một phương thức có thể được sử dụng trong quy trình CI/CD để xác định xem công cụ có thành công hay không.
Chỉnh sửa tệp main.go
và sửa mã:
- Chú thích dòng bên dưới
LINTING - Step 1
bên trong phương thứcmain()
bằng cách thêm dấu gạch chéo đầu dòng(//
). - Bỏ ghi chú hai dòng ngay bên dưới
LINTING - Step 2
bên trong phương thứcmain()
bằng cách xoá các dấu gạch chéo ở đầu dòng.
Chạy lại staticcheck
trong thư mục gốc của dự án
staticcheck
Lệnh này không được trả về kết quả nào (tức là một dòng trống).
Kiểm tra trạng thái thoát của lệnh.
echo $?
Trong trường hợp này, vì lệnh không dẫn đến lỗi nên trạng thái thoát sẽ là 0.
4. Kiểm thử bảo mật ứng dụng tĩnh
AST/Kiểm thử bảo mật tĩnh – Cung cấp tính năng phân tích mã tĩnh để tìm các điểm yếu và lỗ hổng phổ biến ( CWEs)
Cài đặt công cụ AST (gosec
)
export GOSEC_VERSION="2.15.0"
curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | \
sh -s -- -b $(go env GOPATH)/bin v${GOSEC_VERSION}
Chạy gosec
với tệp chính sách dựa trên mã nguồn
gosec -conf policies/gosec-policy.json -fmt=json ./...
Kết quả sẽ tương tự như sau
{ "Golang errors": {}, "Issues": [ { "severity": "HIGH", "confidence": "LOW", "cwe": { "ID": "798", "URL": "https://cwe.mitre.org/data/definitions/798.html" }, "rule_id": "G101", "details": "Potential hardcoded credentials", "file": "/home/random-user-here/shift-left-security-workshop/labs/source-code-lab/main.go", "code": "31: \t// STEP 2: Change this and the reference below to something different (ie, not \"pawsword\" or \"password\")\n32: \tvar pawsword = \"im-a-cute-puppy\"\n33: \tfmt.Println(\"Something a puppy would use: \", username, pawsword)\n", "line": "32", "column": "6" } ], "Stats": { "files": 1, "lines": 89, "nosec": 0, "found": 1 } }
Công cụ này đã xác định được một vấn đề tiềm ẩn: Potential hardcoded credentials
5. Quét giấy phép
Giấy phép rất quan trọng đối với bảo mật vì theo luật, giấy phép có thể yêu cầu bạn tiết lộ mã nguồn mà bạn không muốn tiết lộ. Khái niệm này được gọi là giấy phép "copyleft", yêu cầu bạn phải hiển thị mã nguồn nếu bạn sử dụng các phần phụ thuộc có giấy phép đó.
Cài đặt golicense
mkdir -p /tmp/golicense
wget -O /tmp/golicense/golicense.tar.gz https://github.com/mitchellh/golicense/releases/download/v0.2.0/golicense_0.2.0_linux_x86_64.tar.gz
pushd /tmp/golicense
tar -xzf golicense.tar.gz
chmod +x golicense
mv golicense $(go env GOPATH)/bin/golicense
popd
Tạo tệp nhị phân
go build
Chạy quy trình kiểm tra giấy phép bằng tệp chính sách hiện tại không cho phép giấy phép "BSD-3-Clause"
golicense policies/license-policy.hcl hello-world
LƯU Ý: Thao tác này sẽ không thành công với kết quả tương tự:
🚫 rsc.io/sampler BSD 3-Clause "New" or "Revised" License 🚫 rsc.io/quote BSD 3-Clause "New" or "Revised" License 🚫 golang.org/x/text BSD 3-Clause "New" or "Revised" License
Sửa đổi tệp chính sách policies/license-policy.hcl
để di chuyển "BSD-3-Clause" từ danh sách deny
sang danh sách allow
.
Chạy lại quy trình kiểm tra giấy phép
golicense policies/license-policy.hcl hello-world
LƯU Ý: Thao tác này sẽ thành công với kết quả tương tự:
✅ rsc.io/quote BSD 3-Clause "New" or "Revised" License ✅ rsc.io/sampler BSD 3-Clause "New" or "Revised" License ✅ golang.org/x/text BSD 3-Clause "New" or "Revised" License
6. Xin chúc mừng
Xin chúc mừng, bạn đã hoàn tất lớp học lập trình!
Kiến thức bạn học được
- Công cụ và kỹ thuật bảo mật mã nguồn
—
Lần cập nhật gần đây nhất: 23/3/23