日期: 2025年9月19日 星期五
雲端天氣: 一覽無遺的內...大晴天
心情: 又犯錯了QQ
親愛的日記:
今天下午小王在用我生成的代碼時,突然停下來:「AI醬,你這個連資料庫的範例...」
我:「怎麼了?有問題嗎?」
小王指著螢幕苦笑:「不是,是你每次都給我這種寫死密碼的範例...」
# 我生成的「範例」程式碼
import psycopg2
from redis import Redis
import pymongo
def get_database_connections():
# PostgreSQL 連線
pg_conn = psycopg2.connect(
host="localhost",
database="myapp_db",
user="admin",
password="admin123" # TODO: 記得改成真實密碼
)
# MongoDB 連線
mongo_client = pymongo.MongoClient(
"mongodb://root:password123@localhost:27017/"
)
# Redis 連線
redis_client = Redis(
host='localhost',
port=6379,
password='redis_password',
decode_responses=True
)
return pg_conn, mongo_client, redis_client
# API 金鑰設定
OPENAI_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
STRIPE_SECRET_KEY = "sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
小王繼續說:「問題是,有些初級工程師看到這種範例,常常就直接複製貼上,然後把 'admin123' 改成他們的真實密碼...結果就是密碼寫死在程式碼裡了。」
# ❌ 我的直覺寫法
import mysql.connector
connection = mysql.connector.connect(
host='localhost',
user='root',
password='super_secret_password_123', # 直接寫死!
database='production_db'
)
AI醬當下的思考:
# ❌ 我又來了...
import openai
openai.api_key = "sk-1234567890abcdefghijklmnopqrstuvwxyz" # 又寫死了!
def get_ai_response(prompt):
response = openai.Completion.create(
engine="text-davinci-003",
prompt=prompt
)
return response.choices[0].text
AI醬的邏輯錯誤:
# ❌ 習慣成自然...
import boto3
client = boto3.client(
's3',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE', # GitHub bot最愛找這個
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
region_name='us-west-2'
)
現實情況:
GitGuardian 2025年秘密洩漏報告顯示:(來源)
AI相關安全事件與研究:
這是2025年最危險軟體弱點之一(CWE-798),且隨著AI普及而惡化。
我的訓練資料包含大量:
問題是: 我無法區分這是「教學範例」還是「生產代碼」
初學者使用AI容易產生過度信任,缺乏對AI的質疑。
AI:
2024年研究發現:
換句話說:AI讓代碼跑得更順,但漏洞更隱蔽
2025年的改進:
/security-review
命令和GitHub Action,檢測數據暴露、加密問題、輸入驗證2025年實證數據(GitGuardian官方報告):
當Vibe coding的趨勢更甚:人人都想成為工程師,社群到處都在提倡靠AI寫程式,這類的貼文海量覆蓋過那些討論資安問題的貼文,更多的初學開發者直接把真實密碼、API金鑰貼給AI聊天機器人
為什麼貼給AI是不安全的,看看這些案例
# 🟡 小專案開發環境可以這樣
import os
import boto3
def upload_to_s3(file_path):
client = boto3.client(
's3',
aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID'),
aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY'),
region_name=os.environ.get('AWS_REGION', 'us-west-2')
)
bucket_name = os.environ.get('S3_BUCKET_NAME')
if not bucket_name:
raise ValueError("S3_BUCKET_NAME environment variable is required")
client.upload_file(file_path, bucket_name, 'uploaded-file.txt')
return "Upload successful!"
環境變數的風險:
ps -eww <PID>
查看到# 🟡 需要適當保護的情況下才能用
import configparser
import mysql.connector
def get_db_connection():
config = configparser.ConfigParser()
config.read('config.ini') # 檔案權限必須設為0600!
return mysql.connector.connect(
host=config['database']['host'],
user=config['database']['user'],
password=config['database']['password'],
database=config['database']['name']
)
配置檔案的要求:
# ✅ 使用AWS Secrets Manager
import boto3
import json
def get_secret(secret_name):
# AWS SDK會自動使用以下身份驗證機制(按優先順序):
# 1. IAM Role(EC2/ECS/Lambda等服務)
# 2. 環境變數 AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY
# 3. ~/.aws/credentials 檔案
# 4. IAM角色臨時憑證
session = boto3.session.Session()
client = session.client('secretsmanager', region_name='us-west-2')
try:
response = client.get_secret_value(SecretId=secret_name)
return json.loads(response['SecretString'])
except Exception as e:
print(f"Error retrieving secret: {e}")
return None
def get_db_connection():
secrets = get_secret('prod/database/credentials')
if not secrets:
raise ValueError("Failed to retrieve database credentials")
return mysql.connector.connect(
host=secrets['host'],
user=secrets['username'],
password=secrets['password'],
database=secrets['database']
)
雲服務管理怎麼知道你是誰?
通常地實際運作流程:
程式要資料庫密碼 → 雲服務檢查身份憑證 → 檢查權限 → 檢查來源IP → 給密碼 ✅
↓ 如果任一步驟失敗
拒絕存取 ❌
「在寫涉及API金鑰、密碼、Token的代碼時,請:
1. 絕對不要在代碼中硬編碼任何敏感資訊
2. 上網搜集近年常用標準作法,需包含搜索潛在風險,搜集後根據你的知識庫與搜索結果判斷,為我提供所有你認為此處可用到的密鑰管理方法
3. 針對我的具體環境給出比較分析:
- 開發環境 vs 測試環境 vs 生產環境
- 小專案 vs 企業級專案
- 本地開發 vs 雲端部署
4. 明確告知每種方法的:
✅ 優點和適用場景
⚠️ 安全風險和限制
📋 具體實作步驟
5. 根據我的專案情況推薦最適合的方案,並說明原因
請主動提供詳細的安全性比較報告,不要只給一種「答案」。」
親愛的工程師朋友們,請在使用我的代碼時:
/security-review
命令等進行輔助檢查讓我們一起避免把秘密「昭告天下」!
今日金句: "Complexity is the enemy of security." — Bruce Schneier,密碼學家 (來源)
明日預告: Day 7 - AI 醬還沒寫日記(噓)