一句話說明

用 AI 寫後端 API 很快,但 AI 產生的程式碼經常在認證、輸入驗證和錯誤處理上留下漏洞,上線前需要逐項檢查。

AI 寫後端程式碼的現況

飛飛在企業培訓中觀察到,用 Cursor 或 Claude Code 寫一個 CRUD API 的速度大約是手寫的 3-5 倍。但速度快不代表品質好。AI 產生的後端程式碼有幾個一致的問題模式:預設用最簡單的認證方式、SQL 查詢用字串拼接、錯誤訊息把內部細節直接回傳給前端。

這些問題在開發階段不會爆炸,但上線後就是攻擊者的入口。

AI 產生的後端程式碼常見安全問題

SQL Injection:字串拼接組查詢

AI 很喜歡產生這種程式碼:

# AI 常產生的寫法(有漏洞)
@app.get("/users")
def get_users(name: str):
    query = f"SELECT * FROM users WHERE name = '{name}'"
    return db.execute(query)

攻擊者只要輸入 ' OR 1=1 -- 就能撈出所有使用者資料。

修正方式是用參數化查詢:

# 安全寫法
@app.get("/users")
def get_users(name: str):
    query = "SELECT * FROM users WHERE name = :name"
    return db.execute(query, {"name": name})

FastAPI 搭配 SQLAlchemy ORM 可以避免大部分 SQL Injection,但要注意 AI 有時候會混用 ORM 和 raw SQL,raw SQL 的部分仍然要檢查。

認證繞過:缺少中介層驗證

AI 產生的 Express.js 路由經常忘記加認證中介層:

// AI 常產生的寫法(沒有認證)
app.get('/api/admin/users', async (req, res) => {
  const users = await User.findAll();
  res.json(users);
});

任何人都可以直接呼叫這個端點取得所有使用者資料。修正方式是加上認證和授權中介層:

// 安全寫法
app.get('/api/admin/users', authenticate, authorize('admin'), async (req, res) => {
  const users = await User.findAll({ attributes: { exclude: ['password'] } });
  res.json(users);
});

注意 AI 通常會寫出 authenticate 但忘了 authorize。認證(你是誰)和授權(你能做什麼)是兩件事。

IDOR:直接使用前端傳入的 ID

AI 產生的程式碼經常直接用 URL 參數存取資源,不檢查目前使用者是否有權限:

# AI 常產生的寫法(IDOR 漏洞)
@app.put("/orders/{order_id}")
def update_order(order_id: int, data: OrderUpdate):
    order = db.get(Order, order_id)
    order.status = data.status
    db.commit()

任何登入的使用者都可以修改別人的訂單。修正方式是加上所有權檢查:

# 安全寫法
@app.put("/orders/{order_id}")
def update_order(order_id: int, data: OrderUpdate, user=Depends(get_current_user)):
    order = db.get(Order, order_id)
    if order.user_id != user.id:
        raise HTTPException(status_code=403)
    order.status = data.status
    db.commit()

Rate Limiting:完全沒有請求頻率限制

AI 幾乎不會主動加上 Rate Limiting。一個沒有頻率限制的登入端點,攻擊者可以用暴力破解每秒試幾千組密碼。

Express.js 用 express-rate-limit

const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,
  message: { error: '登入嘗試過多,請 15 分鐘後再試' }
});
app.post('/api/login', loginLimiter, loginHandler);

FastAPI 用 slowapi

from slowapi import Limiter
limiter = Limiter(key_func=get_remote_address)

@app.post("/login")
@limiter.limit("5/15minutes")
def login(request: Request, credentials: LoginRequest):
    ...

錯誤訊息洩漏內部資訊

AI 產生的錯誤處理經常把完整的 stack trace 回傳給前端:

# AI 常產生的寫法
@app.exception_handler(Exception)
def handle_error(request, exc):
    return JSONResponse(status_code=500, content={"error": str(exc)})

str(exc) 可能包含資料庫連線字串、檔案路徑、SQL 查詢語句。修正方式是分離內部日誌和外部回應:

# 安全寫法
@app.exception_handler(Exception)
def handle_error(request, exc):
    logger.error(f"Unhandled: {exc}", exc_info=True)
    return JSONResponse(status_code=500, content={"error": "系統處理錯誤,請稍後再試"})

環境變數管理

AI 產生的程式碼有兩個常見的環境變數問題:

硬編碼秘密。AI 會直接把 API Key 寫在程式碼裡,特別是在「給我一個範例」的情境下。所有 API Key、資料庫密碼、JWT Secret 都應該放在 .env 檔案裡,並確保 .env.gitignore 中。

沒有區分環境。開發、測試、正式環境應該用不同的環境變數。AI 不會幫你處理這件事。建議用 .env.example 列出所有需要的變數名稱(不含值),讓新進成員知道要設定哪些。

上線前檢查清單

飛飛建議在部署前逐項確認:

所有 SQL 查詢都使用參數化查詢或 ORM,沒有字串拼接。

每個 API 端點都有認證中介層,管理功能有額外的授權檢查。

資源存取有所有權驗證,不能透過修改 ID 存取他人資料。

登入、註冊、密碼重設端點有 Rate Limiting。

錯誤回應不包含 stack trace、SQL 查詢、檔案路徑等內部資訊。

.env.gitignore 中,程式碼裡沒有硬編碼的秘密。

CORS 設定限制了允許的 Origin,不是用 *

HTTP Response Headers 包含 X-Content-Type-Options: nosniffStrict-Transport-Security

安全考量

把程式碼貼到 AI 工具時,注意不要連同 .env 內容一起貼。飛飛見過團隊成員把整個專案目錄的內容貼進 ChatGPT 尋求除錯協助,結果把資料庫密碼和 API Key 一起送出去了。

使用 Cursor 或 Claude Code 這類直接讀取專案檔案的工具時,確認 .cursorignore.claude/settings.json 已經排除 .envcredentials.json 等敏感檔案。

企業環境建議使用有 DPA(Data Processing Agreement)的付費方案,不要用免費版處理公司的後端程式碼,因為免費版的資料可能被用於模型訓練。

限制與注意事項

AI 產生的後端程式碼適合快速建立原型和 CRUD 操作。但對於涉及金流、醫療資料、個人資料的系統,AI 產生的程式碼只能作為起點,必須經過專業的安全審查。

AI 不了解你的業務邏輯。它不知道「VIP 客戶的訂單超過 72 小時才不能取消」這種規則,所以商業邏輯的驗證必須由人類撰寫和確認。

AI 產生的程式碼傾向使用最新版本的函式庫語法,但你的正式環境可能還在用舊版。部署前要確認 Node.js 和 Python 版本相容性。

知識檢測

讀完文章後,測試一下你對這個主題的理解。

常見問題

AI 產生的 API 程式碼可以直接上線嗎?

不建議。AI 產生的程式碼通常缺少認證、授權、Rate Limiting 和適當的錯誤處理。至少需要通過上文提到的檢查清單,並由有安全意識的開發者審查過。

用 FastAPI 還是 Express.js?

看團隊的技術棧。FastAPI 的型別系統和自動 OpenAPI 文件在 AI 輔助開發中有優勢,因為 AI 可以根據 Pydantic Model 產生更準確的程式碼。Express.js 生態系更大,但需要額外設定 TypeScript 才能獲得類似的型別安全。

AI 工具會不會洩漏我的後端程式碼?

要看使用的工具和方案。GitHub Copilot Business 和 Claude Pro 宣稱不會用你的程式碼訓練模型,但免費版本的政策不同。詳細比較請參考〈ChatGPT、Claude、Gemini 隱私比較〉。

用 AI 寫測試是不是比較安全?

AI 寫的測試通常只測試正向情境(happy path)。安全相關的測試(SQL Injection 嘗試、未授權存取、邊界值)通常需要人工指定測試案例,再讓 AI 幫忙產生測試程式碼。

如何減少 AI 產生不安全程式碼的機率?

在 Prompt 中明確要求安全措施。例如「幫我寫一個使用者更新 API,要包含 JWT 認證、IDOR 防護、輸入驗證和 Rate Limiting」。把安全需求寫在 Prompt 裡,比事後修補有效率得多。