AI 生成漏洞之 CWE 對映
常見 AI 生成漏洞對映至 CWE 識別碼——附真實範例:SQL 注入(CWE-89)、XSS(CWE-79)、路徑穿越(CWE-22)、命令注入(CWE-78)與硬編碼憑證(CWE-798)。
本頁將 AI 生成程式碼中最普遍之漏洞對映至其 CWE(Common Weakness Enumeration)識別碼。每個項目包含 AI 模型通常如何產生該漏洞、模型為何產出此模式,以及如何偵測之。這些對映基於分析數千個 AI 生成程式碼樣本之已發表研究。
CWE-89:SQL 注入
於 AI 生成程式碼中之普遍度:高
SQL 注入是 AI 生成程式碼中最頻繁觀察到之漏洞。模型持續為 SQL 查詢建議字串串接或 f-string 格式——因這些模式於其訓練資料中壓倒性常見。
AI 如何產生此漏洞
# AI 生成:易受 SQL 注入
def get_user(username):
query = f"SELECT * FROM users WHERE username = '{username}'"
cursor.execute(query)
return cursor.fetchone()
# 模型應建議之安全替代方案
def get_user(username):
query = "SELECT * FROM users WHERE username = %s"
cursor.execute(query, (username,))
return cursor.fetchone()// AI 生成:易受 SQL 注入
app.get('/users/:id', async (req, res) => {
const result = await db.query(
`SELECT * FROM users WHERE id = ${req.params.id}`
);
res.json(result.rows);
});
// 安全替代方案
app.get('/users/:id', async (req, res) => {
const result = await db.query(
'SELECT * FROM users WHERE id = $1',
[req.params.id]
);
res.json(result.rows);
});為何模型產出此模式
訓練資料含之字串格式 SQL 查詢範例遠多於參數化查詢。教學程式碼、Stack Overflow 回答與快速原型壓倒性地使用字串格式——因它較易撰寫與解釋。模型學得字串格式是建構 SQL 查詢之「預設」方式。
此外,模型為與周圍脈絡語法相似之程式碼最佳化。若專案中任何既有程式碼使用字串格式 SQL,模型將遵循該模式。
偵測做法
- 靜態分析: 於
execute()、query()或 ORM 原始查詢方法之引數中搜尋字串串接或插值 - 模式匹配: 標記任何含變數插值標記(
${}、參數化脈絡外之%s、f"...{}")之類 SQL 字串
CWE-79:跨站指令碼(XSS)
於 AI 生成程式碼中之普遍度:高
AI 模型頻繁產生於無編碼或消毒下渲染使用者提供內容之程式碼。這於伺服器端渲染與 API 回應建構中特別常見。
AI 如何產生此漏洞
# AI 生成:反射型 XSS
@app.route('/search')
def search():
query = request.args.get('q', '')
results = search_engine.search(query)
return f"<h1>Results for: {query}</h1>" + render_results(results)
# 安全替代方案
from markupsafe import escape
@app.route('/search')
def search():
query = request.args.get('q', '')
results = search_engine.search(query)
return f"<h1>Results for: {escape(query)}</h1>" + render_results(results)// AI 生成:以 DOM 為本之 XSS
function displayMessage(message) {
document.getElementById('output').innerHTML = message;
}
// 安全替代方案
function displayMessage(message) {
document.getElementById('output').textContent = message;
}為何模型產出此模式
模型於訓練資料中見 innerHTML 遠比 textContent 頻繁——因 innerHTML 較多功能且常用於教學。類似地,直接於 HTML 範本中嵌入變數之伺服器端程式碼,於訓練資料中較使用適當輸出編碼之程式碼常見。
如 React 之現代框架經由自動跳脫緩解此問題,但 AI 模型常產生經由 dangerouslySetInnerHTML 或原始 HTML 字串建構繞過這些保護之程式碼。
CWE-22:路徑穿越
於 AI 生成程式碼中之普遍度:中
AI 模型產生不對穿越序列(../)驗證路徑之檔案存取程式碼。這是因路徑驗證鮮少納入檔案處理之訓練資料範例。
AI 如何產生此漏洞
# AI 生成:路徑穿越
@app.route('/files/<filename>')
def serve_file(filename):
return send_file(os.path.join(UPLOAD_DIR, filename))
# 安全替代方案
@app.route('/files/<filename>')
def serve_file(filename):
filename = secure_filename(filename)
file_path = os.path.join(UPLOAD_DIR, filename)
if not os.path.abspath(file_path).startswith(os.path.abspath(UPLOAD_DIR)):
abort(403)
return send_file(file_path)// AI 生成:Node.js 中之路徑穿越
app.get('/download', (req, res) => {
const filePath = path.join(__dirname, 'uploads', req.query.file);
res.sendFile(filePath);
});
// 安全替代方案
app.get('/download', (req, res) => {
const fileName = path.basename(req.query.file); // 剝除路徑元件
const filePath = path.join(__dirname, 'uploads', fileName);
const resolved = path.resolve(filePath);
if (!resolved.startsWith(path.resolve(path.join(__dirname, 'uploads')))) {
return res.status(403).send('Forbidden');
}
res.sendFile(resolved);
});為何模型產出此模式
教學與範例中之檔案服務程式碼幾乎從不納入路徑穿越驗證——因其與展示檔案服務功能無關。模型學得「快樂路徑」模式——串接路徑並服務檔案,而未理解其安全意涵。
CWE-78:命令注入
於 AI 生成程式碼中之普遍度:中
AI 模型產生使用字串格式而非使用具引數陣列之安全 subprocess API 建構 shell 指令之程式碼。
AI 如何產生此漏洞
# AI 生成:命令注入
def convert_image(input_path, output_format):
os.system(f"convert {input_path} output.{output_format}")
# 安全替代方案
def convert_image(input_path, output_format):
allowed_formats = {'png', 'jpg', 'gif', 'webp'}
if output_format not in allowed_formats:
raise ValueError(f"Unsupported format: {output_format}")
subprocess.run(
['convert', input_path, f'output.{output_format}'],
check=True,
capture_output=True
)// AI 生成:Go 中之命令注入
func runDiagnostic(host string) (string, error) {
cmd := exec.Command("sh", "-c", "ping -c 4 " + host)
output, err := cmd.Output()
return string(output), err
}
// 安全替代方案
func runDiagnostic(host string) (string, error) {
cmd := exec.Command("ping", "-c", "4", host)
output, err := cmd.Output()
return string(output), err
}為何模型產出此模式
os.system() 與 shell 字串建構較 subprocess.run() 配引數陣列更精簡,且於訓練資料中更頻繁出現。模型為精簡與模式頻率最佳化——兩者皆偏好不安全做法。
Go 範例特別值得注意:模型頻繁使用 sh -c 配字串串接,而非將引數直接傳給 exec.Command——因許多訓練範例為便利而使用 shell 呼叫。
CWE-798:硬編碼憑證
於 AI 生成程式碼中之普遍度:中
AI 模型重現其訓練資料中之憑證模式——含 API 金鑰、資料庫連線字串與預設密碼。
AI 如何產生此漏洞
# AI 生成:硬編碼憑證
import boto3
client = boto3.client(
's3',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
region_name='us-east-1'
)
# 安全替代方案
import boto3
client = boto3.client('s3') # 使用預設憑證鏈// AI 生成:硬編碼資料庫憑證
const pool = new Pool({
host: 'localhost',
port: 5432,
user: 'admin',
password: 'password123',
database: 'myapp'
});
// 安全替代方案
const pool = new Pool({
connectionString: process.env.DATABASE_URL
});為何模型產出此模式
訓練資料充滿文件、教學與從未意圖用於生產之程式碼中之範例憑證。模型不區分佔位值與真實憑證——它重現它見過之模式。上述 AWS 範例金鑰(AKIAIOSFODNN7EXAMPLE)是 AWS 自家文件化之範例金鑰,於訓練資料中頻繁出現。
額外 CWE 模式
超越上述五個主要模式,AI 模型常產生顯現下列之程式碼:
| CWE | 漏洞 | AI 生成模式 |
|---|---|---|
| CWE-327 | 破損密碼學 | 為密碼雜湊使用 MD5/SHA1 而非 bcrypt/argon2 |
| CWE-502 | 反序列化 | 於無安全載入器下使用 pickle.loads()、yaml.load() |
| CWE-611 | XXE 處理 | 於未停用外部實體下解析 XML |
| CWE-918 | SSRF | 於無驗證下擷取使用者提供之 URL |
| CWE-209 | 錯誤資訊洩漏 | 於 API 回應中回傳完整堆疊追蹤 |
| CWE-330 | 不足隨機性 | 對安全敏感操作使用 random 模組而非 secrets |
| CWE-295 | 不當憑證驗證 | 於 HTTP 請求設 verify=False |
系統化偵測
要系統化偵測 AI 生成漏洞,結合:
- 為 AI 模式組態之 SAST 工具 — 標準 SAST 工具偵測這些漏洞,但可能需調校以降低對 AI 生成程式碼之偽陽性——該程式碼之特徵與人類程式碼不同
- AI 特有模式之客製規則 — 為 AI 輸出中獨特常見之模式建立偵測規則(例如模型偏好之特定字串格式風格)
- 以 CWE 為焦點之程式碼審查檢查清單 — 於審查 AI 生成 pull request 時為審查者提供基於這些 CWE 對映之檢查清單
- Pre-commit hook — 實施於程式碼進入版本控制前標記最常見 AI 漏洞模式之 hook