Tạo yêu cầu hỗ trợ
Đăng nhập Đăng ký
Locker support Locker support
Kết quả

No results found.

Trang chủ Locker Secrets Manager Hướng dẫn gỡ bỏ dữ liệu bí mật trong mã nguồn phần mềm
Vietnamese English
Hướng dẫn gỡ bỏ dữ liệu bí mật trong mã nguồn phần mềm

Phiên bản 02. Cập nhật:

  • Link Invoke-WebRequest
  • Với secrets lưu trong mã nguồn
  • Với secrets lưu trong file cấu hình

Việc lưu trữ các dữ liệu nhạy cảm ngay trong mã nguồn (secrets hardcoding) là một loại lỗ hổng bảo mật. Thông qua việc vô tình làm lộ mã nguồn, hoặc các tấn công đọc file ở máy chủ, những secrets này có thể bị kẻ tấn công thu thập, và từ đó giành quyền truy cập trái phép vào những hệ thống có liên quan.

Vì vậy, cần tuyệt đối tránh hình thức lưu trữ không an toàn này trong quá trình phát triển phần mềm. Dưới đây là cách phát hiện và gỡ bỏ các secrets trong mã nguồn dự án của bạn một cách an toàn với phần mềm Locker Secrets Manager.

Cài đặt Locker CLI

Với Windows

Start-Process powershell -Verb runAs
New-Item -Path "$HOME\.locker" -ItemType Directory -Force
Invoke-WebRequest -Uri "https://locker.io/secrets/download/cli-windows " -OutFile "$HOME\.locker\locker.exe"
$oldPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)
$newPath = "$oldPath;$HOME\.locker"
[System.Environment]::SetEnvironmentVariable("Path", $newPath, [System.EnvironmentVariableTarget]::Machine)

Với Linux

mkdir -p ~/.locker
wget https://locker.io/secrets/download/cli-linux -O ~/.locker/locker
chmod +x ~/.locker/locker
sudo ln -sf ~/.locker/locker /usr/local/bin/locker

Với macOS

arm

mkdir -p ~/.locker
wget https://locker.io/secrets/download/cli-mac-arm64 -O ~/.locker/locker
chmod +x ~/.locker/locker
sudo ln -sf ~/.locker/locker /usr/local/bin/locker

x64

mkdir -p ~/.locker
wget https://locker.io/secrets/download/cli-mac-x64 -O ~/.locker/locker
chmod +x ~/.locker/locker
sudo ln -sf ~/.locker/locker /usr/local/bin/locker

Phát hiện Secrets trong dự án

Sử dụng lệnh scan như sau

locker scan --source <path-to-source-code>

Chúng ta sẽ thu được kết quả như hình dưới, bao gồm:

  • Đường dẫn đến tệp tin chứa secrets
  • Giá trị secret tìm thấy
  • Thứ tự dòng chứa secret
  • Loại secret
  • Mã commit
Notion image

Thay đổi cách lưu Secrets an toàn

Với các phát hiện sau khi scan ra, chúng ta sẽ cần thay đổi cách lưu chúng an toàn hơn thay vì hardcoding.

Khởi tạo dự án tại Locker Secrets

  • Tạo một tài khoản Locker Secrets tại đây nếu bạn chưa có tài khoản
  • Tạo mới project, tương ứng với dự án chứa secrets của bạn
  • Tạo Access Key trong Project, đây là cặp khóa bạn sẽ sử dụng cho Locker SDK ở các bước tiếp theo

Với secrets lưu trong mã nguồn

Với số lượng secrets lưu trong mã nguồn nhỏ, bạn có thể tiến hành cập nhật thủ công lại theo các bước sau

  • Thêm các secrets bị hardcoding tương ứng lên Locker Secrets Project bạn vừa tạo thông qua giao diện web
  • Cài đặt Secrets SDK tương ứng với ngôn ngữ bạn đang sử dụng tại đây.
  • Sử dụng cặp Access Key và Secret Access Key ở trên để khởi tạo trong SDK Config object
  • Tìm kiếm thủ công vị trí secret của bạn bị hardcoding, tiến hành thay thế lại bằng cách sử dụng SDK để gọi biến secret tương ứng đã được lưu từ trước đó.
💡
Ghi chú: Tính năng cập nhật tự động secrets đang được hoàn thiện và sẽ được cập nhật trong các phiên bản tiếp theo.

Ví dụ minh họa với ngôn ngữ Python

Giả sử bạn có file settings.py bị hardcoding như sau

# ...
DEFAULT_CONFIG = {
  "database": {
    "host": "mysql.myserver.com",
    "port": 3306,
    "username": "my_database",
    "password": "Ol1PPgsG4htlBb0q7THJP7nWyBJXbAJg"
  },
  "request": {
    "access_key_id": "ak29NASAs",
    "secret_token": "qHg34VAGQZwCkUy4UjZQAsCVeH6TvsJg"
  }
}

# ...

Locker CLI đã phát hiện bạn hardcoding ở các dòng

"password": "Ol1PPgsG4htlBb0q7THJP7nWyBJXbAJg"
...
"secret_token": "qHg34VAGQZwCkUy4UjZQAsCVeH6TvsJg"

Bạn sẽ cần tiến hành tạo các secret lên Locker Project qua giao diện web tương ứng như sau:

DATABASE_PASSWORD: Ol1PPgsG4htlBb0q7THJP7nWyBJXbAJg
REQUEST_SECRET_TOKEN: qHg34VAGQZwCkUy4UjZQAsCVeH6TvsJg

Cài đặt Locker Secret SDK và tiến hành thay thế việc hardcoding bằng việc sử dụng SDK

requirements.txt

...
lockerpm
...

Lưu trữ cặp Locker Access Key của bạn đã tạo từ trước đó bằng biến môi trường.

Linux/MacOS

export ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
export SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>

Windows

Powershell

$Env:ACCESS_KEY_ID = '<YOUR_ACCESS_KEY_ID>'
$Env:SECRET_ACCESS_KEY = '<SECRET_ACCESS_KEY>'

Command Prompt

set ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
set SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>

Tiến hành khai báo, khởi tạo Locker Secret Manager object

secret_management.py

import os
from locker import Locker

client = Locker(
    access_key_id=os.get_env(ACCESS_KEY_ID),
    secret_access_key=os.get_env(SECRET_ACCESS_KEY),
)

Thay thế việc hardcoding bằng cách dùng SDK gọi biến tại nơi lộ lọt secret của bạn

settings.py

from secret_management import client
# ...
DEFAULT_CONFIG = {
  "database": {
    "host": "mysql.myserver.com",
    "port": 3306,
    "username": "my_database",
    "password": client.get("DATABASE_PASSWORD"),
  },
  "request": {
    "access_key_id": "ak29NASAs",
    "secret_token": client.get("REQUEST_SECRET_TOKEN")
  }
}
# ...

Với số lượng secrets lớn, bạn có thể dùng tùy chọn scan fix

Tùy chọn này sẽ thực hiện nạp toàn bộ các secrets của bạn lên dự án Locker tương ứng. Đồng thời nó cũng sẽ tự động thay thế các secrets của bạn trong mã nguồn bằng việc sử dụng SDK gọi biến tương ứng trên dự án Locker:

  • Lưu trữ cặp Locker Access Key của bạn đã tạo từ trước đó bằng biến môi trường.
  • Sử dụng lệnh scan fix
locker scan fix --source <path-to-source-code> --language <program-language>
  • Rà soát lại mã nguồn của bạn, đảm các các secrets được gọi và dùng đúng mục đích
💡
Hiện tại tùy chọn scan fix mới được hỗ trợ với ngôn ngữ Python. Các ngôn ngữ khác sẽ được chúng tôi cập nhật thêm trong thời gian tới.

Ví dụ minh họa với ngôn ngữ Python:

Giả sử bạn có file settings.py bị hardcoding như sau

# ...
DEFAULT_CONFIG = {
  "database": {
    "host": "mysql.myserver.com",
    "port": 3306,
    "username": "my_database",
    "password": "Ol1PPgsG4htlBb0q7THJP7nWyBJXbAJg"
  },
  "request": {
    "access_key_id": "ak29NASAs",
    "secret_token": "qHg34VAGQZwCkUy4UjZQAsCVeH6TvsJg"
  }
}

# ...

Locker CLI đã phát hiện bạn hardcoding ở các dòng

"password": "Ol1PPgsG4htlBb0q7THJP7nWyBJXbAJg"
...
"secret_token": "qHg34VAGQZwCkUy4UjZQAsCVeH6TvsJg"

Lưu trữ cặp Locker Access Key của bạn đã tạo từ trước đó bằng biến môi trường, tương tự như với việc cập nhật thu công ở trên.

Sử dụng lệnh scan fix như sau

locker scan fix --source . --language python

Sau khi sử dụng lệnh này, các secrets sẽ tự động được nạp tự động lên project của bạn với tên key tăng dần như SECRET1, SECRET2 và đồng thời khởi tạo Locker SDK instance và thay thế trong mã nguồn của bạn

secret_manager.py

import os
from locker import Locker
locker_client = Locker(
	access_key_id=os.getenv("LOCKER_ACCESS_KEY_ID"),
	secret_access_key=os.getenv("LOCKER_SECRET_ACCESS_KEY")
)

settings.py

from secret_management import locker_client
# ...
DEFAULT_CONFIG = {
  "database": {
    "host": "mysql.myserver.com",
    "port": 3306,
    "username": "my_database",
    "password": locker_client.get("SECRET1"),
  },
  "request": {
    "access_key_id": "ak29NASAs",
    "secret_token": locker_client.get("SECRET2")
  }
}
# ...

Với secrets lưu trong file chứa biến môi trường

  • Kiểm tra xem file chứa biến môi trường này có cần thiết với dự án không. Nếu không tiến hành xóa bỏ file biến môi trường này
  • Nếu dự án bạn cần các secret trong file chứa biến môi trường này, cấu hình locker với cặp Access Key đã tạo bằng lệnh
locker configuration --access-key-id {access key id} --secret-access-key {secret access key}
  • Lưu secret vào Vault của Locker Secret với lệnh locker secret create:
locker secret create --key {secret key} --value {secret value} --description {secret description (optional)} --environment {secret environment (if the secret is associated with a specific environment)}
  • Sử dụng lệnh locker secret run để chạy dự án với các secret đã được lưu:
locker secret run --environment dev --command your_command

Lệnh locker run sẽ đưa các secret ở một môi trường chỉ định (đã được lưu trên Locker Secret trước đó) vào như là các biến môi trường trong lệnh chạy chương trình của bạn.

  • Xóa secrets lưu trong file chứa biến môi trường của bạn.

Với secrets lưu trong file cấu hình

  • Cấu hình Locker CLI với cặp Access Key và Secret Key bạn đã tạo trước đó
locker configuration --access-key-id {YOUR_ACCESS_KEY_ID} --secret-access-key {YOUR_SECRET_ACCESS_KEY}
  • Dựa theo kết quả scan, xác định vị trí file cấu hình có chứa các secrets của bạn, sử dụng Locker CLI để import các secrets bị lộ lọt này lên project của bạn
locker secret import --source {CONFIG_FILE_LOCATION}
  • Nếu trong chương trình của bạn có sử dụng các secrets lưu trong file cấu hình, tiến hành thay thế phần mã nguồn sử dụng file config này bằng Locker SDK
  • Cuối cùng là tiến hành xóa bỏ các secrets trong file cấu hình.
 

Dưới đây là minh họa với ngôn ngữ Python

Giả sử bạn có file cấu hình chứa secrets bị lộ lọt như sau config.ini

[DEFAULT]
Timeout = 30
SecretKey = this.is.secret
Forward = 1
MaxRetries = 10

[mysql1]
Port = 3306
Host = mysql1.example
Username = root
Password = root

[mysql2]
Port = 3307
Host = mysql2.example
Username = root
Password = root

Mã nguồn load file cấu hình trên của bạn giả sử như sau:

import configparser


class Config:
    def __init__(self):
        self.config_parser = configparser.ConfigParser()
        self.config_parser.read('config.ini')
        self.set_attr()

    def set_attr(self):
        for sec in self.config_parser.sections():
            for key, value in self.config_parser.items(sec):
                setattr(self, f"{sec}_{key}", value)

Khi này, bạn cần import các secrets này lên Locker project của bạn bằng lệnh

locker secret import --source config.ini

Thay thế mã nguồn load file cấu hình với Locker Python SDK

from locker import Locker

LOCKER_ACCESS_KEY_ID = os.getenv('LOCKER_ACCESS_KEY_ID')
LOCKER_SECRET_ACCESS_KEY = os.getenv('LOCKER_SECRET_ACCESS_KEY')

class Config:
    def __init__(self):
        self.locker = Locker(access_key_id=LOCKER_ACCESS_KEY_ID, secret_access_key=LOCKER_SECRET_ACCESS_KEY)
        self.set_attr()

    def set_attr(self):
        secrets = self.locker.list()
        for arg in secrets:
            setattr(self, arg['key'], arg['value'])

Cuối cùng chúng ta xóa bỏ file cấu hình ra khỏi thư mục.

Gỡ bỏ secrets khỏi Git repo

Không giống như cách tổ chức tệp tin thông thường trong máy tính, Git là một phần mềm với cơ chế lưu tệp tin và tổ chức dữ liệu phức tạp dựa trên phiên bản. Vì thế, nếu bạn xóa hoặc thay đổi nội dung của một tệp tin, nó chỉ đơn giản là xóa và thay đổi ở phiên bản hiện tại trong khi những nội dung đó vẫn tồn tại ở các phiên bản trước, và chúng có thể truy xuất được thông qua các git commit.

Với những dữ liệu nhạy cảm và bí mật, để xóa bỏ hoàn toàn, chúng ta buộc phải xóa toàn bộ lịch sử git commit có liên quan đến tệp tin chứa dữ liệu đó. Có 2 phương pháp chính có thể sử dụng cho công việc này:

  • BFG Repo-Cleaner (gọi tắt là BFG) là một công cụ dùng để viết lại lịch sử commit với chức năng tương tự git filter-branch nhưng tốc độ nhanh hơn 10-720 lần.

Hướng dẫn dưới đây sẽ thực hiện với BFG

Cài đặt

  • Để chạy BFG máy tính bạn cần có môi trường Java. Vui lòng tải xuống và cài đặt Java tương ứng với hệ điều hành của bạn, nếu Java chưa được cài trước đó

Sử dụng BFG để xóa secrets

  • Trước khi chạy BFG hãy tạo một bản sao lưu cho dự án của bạn phòng trường hợp sai sót dẫn đến mất mát dữ liệu
  • Clone repo về máy với flag --mirror. Điều này sẽ giúp chúng ta có được đầy đủ git index và metadata của dự án mà không cần có dữ liệu thực
    • git clone --mirror https://github.com/owner/repo.git
  • Xóa sự tồn tại của file chứa secrets trên toàn bộ lịch sử commit
    • java -jar bfg.jar <file_name> some-big-repo.git
  • Xóa bộ sưu tập rác của repo
    • cd some-big-repo.git
      git reflog expire --expire=now --all && git gc --prune=now --aggressive
 
Trang này có hữu ích với bạn??
Không
Tham gia cộng đồng của chúng tôi