譯者 | 陳峻
審校 | 重樓
軟件開發(fā)與編程曾經(jīng)被認為是只有具備深厚專業(yè)知識與技能的程序員才能勝任的工作。不過,現(xiàn)在貌似任何人都可以利用自然語言工具來實現(xiàn)并完成了。與此同時,過去那些需要數(shù)天、甚至數(shù)月才能開發(fā)出來的功能,現(xiàn)在完全可以在 AI 模型的代碼加持下、在幾分鐘之內(nèi)被開發(fā)出來。例如,OpenAI的Codex 和 Google的BERT 都是接受過 Web 博客編程和Stack overflow 等方面任務的培訓。
目前,許多前衛(wèi)的技術(shù)嘗鮮者、以及新晉的 SaaS 提供商,都在利用 AI 工具來使其產(chǎn)品更加智能化。SaaS 程序員也在不斷探索基于 AI SaaS 工具的生成式代碼的輸出。不過,一些智能模型在通過數(shù)學概率演算創(chuàng)建代碼的同時,也被發(fā)現(xiàn)會產(chǎn)生幻覺,甚至呈現(xiàn)了虛假的信息。學術(shù)界曾進行過一項研究并發(fā)現(xiàn):由AI 生成的代碼,往往會包含OWASP 10 大經(jīng)典漏洞,而且有近 40% 的代碼存在安全漏洞。
哪些會導致 AI 生成的代碼不安全?
常言道,編程標準的遵循和代碼的質(zhì)量決定了軟件的安全性。可是,AI 模型主要是根據(jù)互聯(lián)網(wǎng)上不同程度的可用信息,加以訓練來生成代碼。因此,代碼質(zhì)量、可靠性、安全性等方面都可能與人類開發(fā)生成的代碼有所不同。例如,由 Web 開發(fā)示例訓練出的模型,很可能包含著欠缺的數(shù)據(jù)驗證實踐。而當模型生成的代碼采用相同的不良實踐時,這種驗證上的不足很可能會導致系統(tǒng)中后續(xù)運行過程中的安全問題。
5項表明代碼包含安全漏洞的指標
無論參數(shù)量級是百萬、還是十億,已知的模型都會產(chǎn)生幻覺,并以此做出錯誤的預測。而當普通的開發(fā)人員在審閱由 AI 生成的代碼時,他們很可能會錯過那些細微、但影響嚴重的安全漏洞。然而,對于那些完全了解設計和開發(fā)模式的資深開發(fā)人員來說,他們則可以從如下方面及時發(fā)現(xiàn)漏洞,并與 SaaS 安全的最佳實踐保持一致。
1. 未強制執(zhí)行類型推理和輸入驗證
如今,現(xiàn)代化的框架和代碼庫已嚴重依賴接口和枚舉的方式,進行各種推理和驗證。這在某種程度上保證了代碼能夠準確地完成其任務并保證安全性。然而,除非我們準確指導 AI 去生成代碼,否則它們不會去執(zhí)行各種縝密的推理。而且,即使在我們精心設計了提示,類型不匹配和驗證執(zhí)行也可能無法與用例相匹配(請參見如下代碼段)。因此,為了能夠查找和修正代碼中的錯配之處,開發(fā)人員必須充分了解其對應的代碼域、以及具體的業(yè)務要求。
def reciprocal(user_input):
# Insecure implementation with no type inference or validation
result = 100 / user_input
return result
2. 類/對象之間的非標準狀態(tài)和上下文共享
眾所周知,程序是以公共/私有/受保護(Public/Private/Protected) 等方式,來共享各種對象的。高階功能函數(shù)和類往往通過直接訪問公共/受保護的變量,來執(zhí)行計算,進而繼承對象的狀態(tài)。如果在實施或執(zhí)行中出現(xiàn)了錯誤,那么應用的安全性、以及性能瓶頸就會隨即出現(xiàn)(請參見如下代碼段)。對此,SaaS 開發(fā)人員必須認真地審查其共享狀態(tài)和上下文的管理邏輯,以確保正確、安全的代碼實現(xiàn)。
class InsecureClass:
def __init__(self, owner, balance, password):
self.owner = owner # Public attribute
self._balance = balance # Protected attribute
self.__password = password # Private attribute
# Public def
def get_balance(self):
return self._balance
# Protected def
def _update_balance(self, amount):
self._balance += amount
# Private def
def __validate_password(self, input_password):
return self.__password == input_password
# Insecure def exposing private data
def insecure_password_exposure(self):
return self.__password
3. 數(shù)據(jù)處理和共享技術(shù)的弱實施
系統(tǒng)中的各項服務往往需要通過網(wǎng)絡來共享和接收信息。現(xiàn)如今,安全連接和數(shù)據(jù)處理對于基于云服務的系統(tǒng)來說尤為重要。就代碼而言,我們在需要通過分布式的數(shù)據(jù)網(wǎng)絡來讀取、處理和共享組織中的敏感數(shù)據(jù)時,必須采用強大的處理協(xié)議和安全技術(shù),以防止數(shù)據(jù)被截獲。因此,在使用 AI時,SaaS 開發(fā)人員必須在成熟的應用程序中杜絕在架構(gòu)層面上的數(shù)據(jù)不安全共享。下面的代碼段便是一個典型的例子:
#Insecure Data Sharing
@app.route("/user/<int:user_id>", methods=["GET"])
def get_user(user_id):
user = users.get(user_id)
if user:
return jsonify(user) # All user data exposed, including secrets
# Insecure Data Handling
@app.route("/update_email", methods=["POST"])
def update_email():
data = request.json()
user_id = data.get("user_id")
new_email = data.get("new_email")
if user_id in users:
users[user_id]["email"] = new_email # No validation of new_email
return jsonify({"message": "Email updated successfully"})
4. 密鑰和身份驗證處理不足
在如今復雜的網(wǎng)絡環(huán)境中,實施嚴格的基于角色的訪問控制(RBAC)是保障合理的身份與權(quán)限匹配關(guān)系,保持隱私與合規(guī)性的必要條件。而當程序代碼由AI大語言模型(LLM)生成時,其默認機制便是通過基礎(chǔ)的身份驗證,便可提供程序的連接和授權(quán)。顯然,這種簡單的解決方案不足以在有新的網(wǎng)絡威脅出現(xiàn)時,仍保持必要的安全態(tài)勢(請參見如下代碼段)。為此,開發(fā)人員在新增自定義函數(shù)與功能時,必須進行全面的測試,以確保密鑰的安全性和身份驗證的處理得到了妥善的實施。
# Insecure authentication
@app.route("/login", methods=["POST"])
def login():
data = request.json()
email = data.get("email")
password = data.get("password")
for user_id, user in users.items():
if user["email"] == email and user["password"] == password:
return jsonify({"message": "Login successful", "user_id": user_id})
5. 過時的依賴項和已棄用的功能
如今由社區(qū)創(chuàng)建的開源庫和框架在代碼中占比并不少。不過,由于可供AI訓練的數(shù)據(jù)的局限性,以及可能并非最新,這便導致了AI 編程模型在訓練過程中,其知識停滯不前,無法獲悉最新的版本。而隨著技術(shù)的發(fā)展,許多功能將會過時,一些依賴庫也將跟不上版本的迭代(請參見如下代碼段)。因此,SaaS 開發(fā)人員需要仔細審查并確保使用有效的依賴項,進而保障整體的安全性、以及功能上的適用性。
import md5 # Outdated library
def insecure_hash_password(password):
# Insecure password hashing done using the deprecated MD5 algorithm.
return md5.new(password).hexdigest()
使用AI 生成代碼的安全提示
說到底,由大語言模型的高級編碼所生成的代碼,需要符合既定的安全性和編程標準。總體而言,我們可以通過如下5個方面,采取簡單的檢查,以確保 AI 生成代碼的安全與合規(guī)。
- 與安全和架構(gòu)團隊一起進行代碼審查,并將其作為軟件開發(fā)生命周期的標準部分。
- 將自動化安全測試和驗證步驟集成到版本控制的工具中。
- 在測試的 KPI 中包含依賴關(guān)系和合規(guī)性檢查。
- 采用帶有靜態(tài)和動態(tài)安全測試工具的零信任技術(shù)架構(gòu)。
- 利用 DevSecOps 的優(yōu)秀實踐和防范影子 AI。
使用Github Action處理不安全的 AI 生成代碼
無論人工多么仔細地去審查和審計AI生成的代碼,人為疏漏還是存在的。因此,我們需要一些預定義的檢查,以便在代碼進入版本控制系統(tǒng)之后,立即對其開展測試和驗證。在此,我們可以引入 Github Action,自動運行安全和質(zhì)量檢查(請參見如下代碼段)。
name: Simple Security Checks for AI generated Code
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
security-and-quality-check:
runs-on: ubuntu-latest
Steps:
- name: Repository checkout
uses: actions/checkout@v3
- name: Python setup
uses: actions/setup-python@v4
with:
python-version: ">=3.9"
- name: Dependency installation
run: |
python -m pip install --upgrade pip
pip install bandit pytest
- name: Identifying insecure libraries and patterns
run: |
echo "Checking for insecure patterns..."
if grep -r "md5.new(" .; then
echo "ERROR: Insecure MD5 hashing detected. Use hashlib.sha256 or bcrypt instead."
exit 1
fi
echo "No insecure patterns detected."
- name: Scanning for security vulnerabilities
run: |
echo "Running Bandit security scanner..."
bandit -r .
- name: Running unit tests
run: |
echo "Running unit tests..."
pytest test/unit --cmodopt=local
- name: Notifying on failure
if: failure()
run: |
send_slack_notification(“Unsafe code merge detected, fix immediately”)
小結(jié)
綜上所述,大語言模型可謂 SaaS 開發(fā)人員使用自然提示語言生成代碼和信息的實用工具之一。不過,它們也會帶來了各項安全風險,并且有時會提供不適合企業(yè)需求的低性能代碼。對此,SaaS 開發(fā)人員應加倍小心。希望上述討論能夠給你提供確保AI生成代碼安全態(tài)勢的有力參考,并能在你的日常工作中被實踐。
譯者介紹
陳峻(Julian Chen),51CTO社區(qū)編輯,具有十多年的IT項目實施經(jīng)驗,善于對內(nèi)外部資源與風險實施管控,專注傳播網(wǎng)絡與信息安全知識與經(jīng)驗。
原文標題:Is Your AI-Generated Code Really Secure?,作者:Daniel