1. Tổng quan
Các kỹ thuật bảo mật mã nguồn là một bộ các phương pháp có thể được dùng để cải thiện tính bảo mật của mã nguồn. Những kỹ thuật này có thể giúp xác định và khắc phục cá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ỏi bị sửa đổi.
Một số kỹ thuật mã nguồn an toàn thường gặp bao gồm:
- Linting: Linting là quá trình kiểm tra mã nguồn để tìm lỗi và vấn đề về phong cách. Việc này được thực hiện bằng cách sử dụng một công cụ lint. Đâ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ác 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 về 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 kiểm thử bảo mật giúp 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ể dùng các công cụ SAST để tìm lỗ hổng bảo mật trong nhiều ngôn ngữ lập trình, bao gồm cả Go, Java, Python, C++ và C#.
- Quá trình quét giấy phép: Quá trình 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 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ể dùng những kỹ thuật này để cải thiện tính bảo mật của mã nguồn ở mọi giai đoạn trong vòng đời phát triển phần mềm. Bạn có thể dùng tính năng kiểm tra để xác định lỗi sớm trong quá trình phát triển, dùng SAST để tìm lỗ hổng bảo mật trước khi mã được biên dịch hoặc triển khai, 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 những 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 các vụ xâm nhập bảo mật.
Kiến thức bạn sẽ học được
Phòng thí nghiệm 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.
- Xơ vải
- 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 được dùng trong phòng thí nghiệm này sẽ được thực hiện trong Cloud Shell.
2. Thiết lập và 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ị của những người tham gia dự án này. Đây là một chuỗi ký tự mà các API của Google không 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à mã duy nhất trên tất cả các dự án trên Google Cloud và không thể thay đổi (bạn không thể thay đổi mã này 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ã dự án được tạo, bạn có thể tạo một mã dự án ngẫu nhiên khác. Hoặc bạn có thể thử tên người dùng 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ẽ giữ nguyên trong suốt thời gian diễn ra dự án. - Để bạn biết, có một giá trị thứ ba là Số dự án mà một số API sử dụng. Tìm hiểu thêm về cả 3 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 thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Để tắt các tài nguyên nhằm tránh bị tính phí ngoài phạm vi 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í trị giá 300 USD.
Khởi động Trình chỉnh sửa Cloud Shell
Bài tập này được thiết kế và kiểm thử để sử dụng với Google Cloud Shell Editor. Để 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 Cloud Shell

- Một ngăn mới sẽ mở ra ở cuối cửa sổ
- Nhấp vào nút Mở trình chỉnh sửa

- Trình chỉnh sửa sẽ mở ra với một 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 CHƯA mở, hãy dùng tổ hợp phím `ctrl+`` để mở một cửa sổ dòng lệnh 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 được dùng trong bài tập thực hành 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. Xơ vải
Linting được dùng để kiểm tra các lỗi hoặc khiếm khuyết phổ biến dựa trên kiểu liên quan đến cú pháp. Linting 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 quá trình đánh giá mã, chia sẻ kiến thức và độ rõ ràng của mã diễn ra nhanh hơn.
Ngoài ra, Linting còn xác định các lỗi cú pháp thường gặp có thể dẫn đến các lỗ hổng bảo mật thường gặp, 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 Go Linter (staticcheck) trong thư mục gốc của dự án
staticcheck
Xem xét kết quả đầu ra
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 các biến vào chuỗi
Xem trạng thái thoát lệnh.
echo $?
Trong trường hợp này, vì lệnh 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 dùng trong quy trình CI/CD để xác định mức độ thành công/thất bại của công cụ.
Chỉnh sửa tệp main.go và sửa mã:
- Thêm dấu gạch chéo(
//) ở đầu để chú thích dòng bên dướiLINTING - Step 1trong phương thứcmain(). - Huỷ chú thích hai dòng ngay bên dưới
LINTING - Step 2bên trong phương thứcmain()bằng cách xoá các dấu gạch chéo ở đầu.
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 gây ra lỗi nên trạng thái thoát sẽ là zero.
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 quy trình phân tích mã tĩnh để tìm các điểm yếu và lỗ hổng thường gặp ( CWE)
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 bằng tệp chính sách đối với mã nguồn
gosec -conf policies/gosec-policy.json -fmt=json ./...
Kết quả đầu ra 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 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 tính bảo mật vì chúng có thể yêu cầu bạn theo luật phải công khai mã nguồn mà bạn có thể không muốn công khai. Khái niệm này được gọi là giấy phép "copyleft", yêu cầu bạn phải công khai mã nguồn nếu 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ự như sau:
🚫 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 thành lớp học lập trình này!
Kiến thức bạn học được
- 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: ngày 23 tháng 3 năm 2023