嘿,大家好!我是 Danko Peng,一個有 25 年科技經驗的 AI 策略顧問,現在專門幫人用 Vibe Coding 衝 MVP,但絕不讓安全變成絆腳石。如果你最近在玩 ChatGPT 或 Cursor,幾分鐘就 vibe 出一個聊天 app 或 todo 清單,恭喜你——你已經是 Vibe Coding 的入門玩家了!但等等,興奮完後,有沒有想過:這堆 AI 生成的碼,真的安全嗎?

Vibe Coding 就是用自然語言 prompt AI,快速「感覺」出程式碼的潮流方式。它讓非工程師也能當 coder,開發速度快上 70%,但壞消息是:漏洞率也高達 50%。為什麼?因為 AI 只管「可跑」,不管「可攻」。想像一下,你的 app 上線後,黑客用 SQL 注入偷用戶資料,或 API KEY 外洩讓你刷爆 OpenAI 帳單。這不是科幻——GitGuardian 報告說,2025 年上半年就有上萬個 AI 碼洩漏事件。

![圖片說明](/api/media/public/objects/public%2Fsites%2F1%2F1757272615178_az29g75msal.jpeg)

這篇文章就是你的安全入門指南!基於我即將在 2025 年 10 月 5 日開的線上課程,我們一步步拆解 5 個基礎防護,從藏 API KEY 開始,到自寫後端結束。全程用生活比喻 + 程式碼範例,零基礎也能跟上。目標?讓你讀完後,能獨立加安全層到 AI 碼,避開 90% 常見坑。走起!(全文約 3200 字,邊讀邊試碼,保證收穫滿滿。)

## 第一關:API KEY 別亂放——藏好你的「家裡鑰匙」

Vibe Coding 的第一個大坑,就是 API KEY 硬編碼。當你 prompt AI:「幫我寫個用 OpenAI 的聊天 API」,它很可能吐出這種爛碼:

```javascript
const API_KEY = 'sk-abc123你的超明顯秘密';  // 壞!直接寫死
fetch('https://api.openai.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ model: 'gpt-4o', messages: [{ role: 'user', content: 'hello' }] })
}).then(response => response.json()).then(data => console.log(data));
```

看起來酷?但這等於把家門鑰匙貼在門口!一 commit 到 GitHub,誰都能看到。結果?黑客用你的 KEY 亂呼叫 API,你帳單爆表,或更慘,偷你 app 資料。根據 OWASP(開放式網頁應用安全項目)的 AI 安全指南,這是「敏感資訊洩漏」的經典案例,2025 年已造成數百萬美元損失。

怎麼修?用環境變數藏起來。步驟超簡單:

1. **裝 dotenv**:在你的 Node.js 專案跑 `npm init -y && npm install dotenv`。
2. **建 .env 檔**:在專案根目錄新檔,寫 `OPENAI_API_KEY=sk-abc123你的秘密`。記住,絕不 commit 它!
3. **改碼**:在 app.js 頂端加 `require('dotenv').config();`,然後用 `process.env.OPENAI_API_KEY` 讀取。

安全版範例:

```javascript
require('dotenv').config();
const API_KEY = process.env.OPENAI_API_KEY;  // 好!從環境讀

if (!API_KEY) {
  console.error('KEY 沒設!快去 .env 加。');
  process.exit(1);
}

fetch('https://api.openai.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ model: 'gpt-4o', messages: [{ role: 'user', content: 'hello' }] })
}).then(response => response.json()).then(data => console.log(data.choices[0].message.content));
```

現在,跑起來安全多了!生產環境呢?用 Vercel 或 Heroku 的 dashboard 設環境變數,自動注入。還要掃描舊坑:用 TruffleHog 工具(免費 CLI)跑 `trufflehog git file://. --since-commit HEAD~10`,它會挖出 commit 歷史的洩漏。

新手提示:prompt AI 時加「用環境變數讀 API KEY,別硬編碼」,它會乖乖生成安全碼。常見錯誤?忘加 `.gitignore` 忽略 .env——這檔超重要,裡面寫 `.env` 和 `node_modules/`。試試看:用 Cursor 生成一個不安全 fetch,修好後 commit 到私有 repo。恭喜,你過了第一關!(本節約 550 字)

## 第二關:用戶密碼安全存——用「鐵門鎖」防黑客猜測

登入系統是 app 的心臟,但 Vibe Coding 常生成這種弱雞碼:直接存明文密碼,或用簡單 if 比對。prompt:「寫個用戶登入」,AI 可能給:

```javascript
// 超爛!明文存
const users = [{ username: 'admin', password: '123456' }];

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);
  if (user) res.json({ success: true });
  else res.status(401).json({ error: '登入失敗' });
});
```

黑客一看,brute force 猜密碼 5 分鐘就破!這違反 OWASP Top 10 的「破壞性認證」,2025 年已導致無數資料外洩。比喻:明文密碼像把日記鎖在公園長椅上,等人來讀。

解方:用 bcrypt hash 密碼(加鹽變亂碼,不可逆),再用 JWT(JSON Web Token)發「通行證」。步驟:

1. **裝套件**:`npm install bcrypt jsonwebtoken express`。
2. **註冊時 hash**:用 `bcrypt.hash(password, 12)` 存 DB(MongoDB 或 SQLite)。
3. **登入驗證**:用 `bcrypt.compare(輸入密碼, hash)` 比對,OK 後發 JWT。
4. **後續請求**:middleware 驗 token。

完整範例(Express 後端):

```javascript
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());

// 假 DB(生產用真資料庫)
let users = [];  // 註冊後存 { username, hash }

app.post('/register', async (req, res) => {
  const { username, password } = req.body;
  const hash = await bcrypt.hash(password, 12);  // 強度 12
  users.push({ username, password: hash });
  res.json({ message: '註冊 OK' });
});

app.post('/login', async (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username);
  if (!user || !await bcrypt.compare(password, user.password)) {
    return res.status(401).json({ error: '用戶或密碼錯' });
  }
  
  // 發 JWT:payload + 簽名 + 過期
  const token = jwt.sign({ username: user.username }, '你的 JWT 秘密', { expiresIn: '1h' });
  res.json({ token, message: '登入成功' });
});

// Middleware 驗 token
const verifyToken = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: '沒 token' });
  try {
    jwt.verify(token, '你的 JWT 秘密');
    next();
  } catch (err) {
    res.status(403).json({ error: 'Token 無效' });
  }
};

app.get('/profile', verifyToken, (req, res) => {
  res.json({ message: '歡迎!你的 profile' });
});

app.listen(3000, () => console.log('安全登入伺服器跑起來!'));
```

前端用?存 token 到 httpOnly cookie(防 XSS),不是 localStorage。加 rate limit(express-rate-limit 套件),防猜密碼轟炸。

新手提示:prompt 加「用 bcrypt hash 密碼 + JWT token,包含過期和錯誤處理」。錯誤?弱簽名 key(用 HS256 改 RS256),或忘鹽化。試碼:註冊個帳號,登入拿 token,用 Postman 驗 profile。過關!(本節約 650 字)

## 第三關:頁面別隨便進——加「門衛」守後台

你的 app 前台炫酷,後台呢?Vibe Coding 常忘 auth,admin 頁直接暴露。prompt:「建 dashboard」,AI 給純 React 組件,沒守門。黑客掃描端口,進去改訂單或刪資料。OWASP 叫這「破壞性存取控制」,比喻:後台像公司金庫,沒門衛誰都能進。

防護:用 auth guard 包頁面 + RBAC(角色基權限)。工具:Next.js 的 middleware,或 React HOC。

步驟:
1. **存 token**:登入後放 cookie。
2. **守門組件**:檢查 token + 角色。
3. **角色檢查**:JWT payload 加 `{ role: 'admin' }`。

範例(React + Next.js):

```javascript
// utils/auth.js
import jwt from 'jsonwebtoken';
import { useRouter } from 'next/router';
import { useEffect } from 'react';

export function verifyToken(token) {
  try {
    return jwt.verify(token, '你的 JWT 秘密');
  } catch {
    return null;
  }
}

// components/ProtectedRoute.js
export default function ProtectedRoute({ children, requiredRole }) {
  const router = useRouter();
  
  useEffect(() => {
    const token = document.cookie.split('; ').find(row => row.startsWith('token='))?.split('=')[1];
    if (!token) {
      router.push('/login');
      return;
    }
    
    const decoded = verifyToken(token);
    if (!decoded || (requiredRole && decoded.role !== requiredRole)) {
      router.push('/unauthorized');
    }
  }, [router, requiredRole]);
  
  return children;
}

// pages/admin.js
import ProtectedRoute from '../components/ProtectedRoute';

export default function Admin() {
  return (
    <ProtectedRoute requiredRole="admin">
      <h1>Admin Dashboard</h1>
      <p>只有 admin 看得到!</p>
    </ProtectedRoute>
  );
}
```

加 CORS(next.config.js 設),防跨域攻擊。RBAC 進階:用 Canva 畫權限圖,admin 全開,user 只讀。

提示:prompt「生成 Next.js protected route,用 JWT + RBAC」。錯誤?忘過期檢查,token 永生。試:建 login 頁,導到 admin,登出清 cookie。安全了!(本節約 500 字)

## 第四關:代碼藏好點——GitHub 當你的「保險箱」

Vibe Coding 快,但 commit 亂來,.env 飛上網。公開 repo 像裸奔,私有 repo 則是堡壘。GitHub 數據:私有化減 breach 70%。OWASP 供應鏈風險,就從這裡來。

步驟:
1. **創私有**:GitHub 新 repo 選 Private。
2. **.gitignore**:加 `.env`、`*.key`。
3. **掃描**:Dependabot 自動查依賴漏洞。

範例 Git 流程:

```bash
# 初始化
git init
echo ".env\nnode_modules/" > .gitignore
git add .gitignore
git commit -m "初始安全設定"

# 移除已 commit .env
git rm --cached .env
git commit -m "移除敏感檔"

# Push 私有
git remote add origin https://github.com/your/safe-vibe-repo.git
git branch -M main
git push -u origin main
```

加 Actions:建 `.github/workflows/scan.yml`:

```yaml
name: Security Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run CodeQL
        uses: github/codeql-action/analyze@v3
```

提示:prompt「生成 .gitignore for Node.js + security scan workflow」。錯誤?team 分享用 .env.example(假 KEY)。試:fork 公開 repo,私有化後掃描。藏好了!(本節約 450 字)

## 第五關:自己寫後端吧——從 Supabase 解放,掌控命脈

Supabase 像速食——快,但黑箱。2024 年 auth 漏洞讓資料全開。自寫後端讓你加 middleware,防注入。比喻:Supabase 外賣,自寫自己煮,懂每味。

步驟:
1. **遷移**:Supabase export SQL → Prisma schema。
2. **建 Express**:加 helmet(安全 header)。
3. **防注入**:用參數化查詢。

範例(Prisma + Express):

```javascript
// schema.prisma
generator client { provider = "prisma-client-js" }
datasource db { provider = "sqlite" url = "file:./dev.db" }
model Todo { id Int @id @default(autoincrement()) text String }

const express = require('express');
const helmet = require('helmet');
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
const app = express();

app.use(helmet());  // CSP、XSS 防護
app.use(express.json());

app.get('/todos', verifyToken, async (req, res) => {  // 加 auth middleware
  const todos = await prisma.todo.findMany();
  res.json(todos);
});

app.post('/todos', verifyToken, async (req, res) => {
  const { text } = req.body;  // Prisma 自動 sanitization
  const todo = await prisma.todo.create({ data: { text } });
  res.json(todo);
});

app.listen(3000);
```

提示:prompt「生成 Prisma Express CRUD,包含 helmet + input validation」。錯誤?忘 sanitization,用 validator.js 過濾。試:遷 Supabase todo 到這,比較速度。自由了!(本節約 500 字)

## 結語:Vibe 安全,從今天開始

恭喜!你讀到這裡,已掌握 Vibe Coding 資安基礎:藏 KEY、鎖密碼、守頁面、藏碼、自寫端。記住,安全不是後加——prompt 時就想,review AI 碼像檢查朋友的開車。

Vibe Coding 是未來,但安全讓它永續。從小 app 開始,建出你的安全帝國!有問題?留言或 email hello@dankopeng.com。一起 vibe 安全~ 🚀