mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-14 13:53:29 +08:00
fix: harden unicode safety checks
This commit is contained in:
@@ -21,13 +21,13 @@ description: Use this skill when adding authentication, handling user input, wor
|
||||
|
||||
### 1. 密鑰管理
|
||||
|
||||
#### ❌ 絕不這樣做
|
||||
#### FAIL: 絕不這樣做
|
||||
```typescript
|
||||
const apiKey = "sk-proj-xxxxx" // 寫死的密鑰
|
||||
const dbPassword = "password123" // 在原始碼中
|
||||
```
|
||||
|
||||
#### ✅ 總是這樣做
|
||||
#### PASS: 總是這樣做
|
||||
```typescript
|
||||
const apiKey = process.env.OPENAI_API_KEY
|
||||
const dbUrl = process.env.DATABASE_URL
|
||||
@@ -107,14 +107,14 @@ function validateFileUpload(file: File) {
|
||||
|
||||
### 3. SQL 注入預防
|
||||
|
||||
#### ❌ 絕不串接 SQL
|
||||
#### FAIL: 絕不串接 SQL
|
||||
```typescript
|
||||
// 危險 - SQL 注入漏洞
|
||||
const query = `SELECT * FROM users WHERE email = '${userEmail}'`
|
||||
await db.query(query)
|
||||
```
|
||||
|
||||
#### ✅ 總是使用參數化查詢
|
||||
#### PASS: 總是使用參數化查詢
|
||||
```typescript
|
||||
// 安全 - 參數化查詢
|
||||
const { data } = await supabase
|
||||
@@ -139,10 +139,10 @@ await db.query(
|
||||
|
||||
#### JWT Token 處理
|
||||
```typescript
|
||||
// ❌ 錯誤:localStorage(易受 XSS 攻擊)
|
||||
// FAIL: 錯誤:localStorage(易受 XSS 攻擊)
|
||||
localStorage.setItem('token', token)
|
||||
|
||||
// ✅ 正確:httpOnly cookies
|
||||
// PASS: 正確:httpOnly cookies
|
||||
res.setHeader('Set-Cookie',
|
||||
`token=${token}; HttpOnly; Secure; SameSite=Strict; Max-Age=3600`)
|
||||
```
|
||||
@@ -299,18 +299,18 @@ app.use('/api/search', searchLimiter)
|
||||
|
||||
#### 日誌記錄
|
||||
```typescript
|
||||
// ❌ 錯誤:記錄敏感資料
|
||||
// FAIL: 錯誤:記錄敏感資料
|
||||
console.log('User login:', { email, password })
|
||||
console.log('Payment:', { cardNumber, cvv })
|
||||
|
||||
// ✅ 正確:遮蔽敏感資料
|
||||
// PASS: 正確:遮蔽敏感資料
|
||||
console.log('User login:', { email, userId })
|
||||
console.log('Payment:', { last4: card.last4, userId })
|
||||
```
|
||||
|
||||
#### 錯誤訊息
|
||||
```typescript
|
||||
// ❌ 錯誤:暴露內部細節
|
||||
// FAIL: 錯誤:暴露內部細節
|
||||
catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: error.message, stack: error.stack },
|
||||
@@ -318,7 +318,7 @@ catch (error) {
|
||||
)
|
||||
}
|
||||
|
||||
// ✅ 正確:通用錯誤訊息
|
||||
// PASS: 正確:通用錯誤訊息
|
||||
catch (error) {
|
||||
console.error('Internal error:', error)
|
||||
return NextResponse.json(
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#### 最小權限原則
|
||||
|
||||
```yaml
|
||||
# ✅ 正確:最小權限
|
||||
# PASS: 正確:最小權限
|
||||
iam_role:
|
||||
permissions:
|
||||
- s3:GetObject # 只有讀取存取
|
||||
@@ -32,7 +32,7 @@ iam_role:
|
||||
resources:
|
||||
- arn:aws:s3:::my-bucket/* # 只有特定 bucket
|
||||
|
||||
# ❌ 錯誤:過於廣泛的權限
|
||||
# FAIL: 錯誤:過於廣泛的權限
|
||||
iam_role:
|
||||
permissions:
|
||||
- s3:* # 所有 S3 動作
|
||||
@@ -65,14 +65,14 @@ aws iam enable-mfa-device \
|
||||
#### 雲端密鑰管理器
|
||||
|
||||
```typescript
|
||||
// ✅ 正確:使用雲端密鑰管理器
|
||||
// PASS: 正確:使用雲端密鑰管理器
|
||||
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
|
||||
|
||||
const client = new SecretsManager({ region: 'us-east-1' });
|
||||
const secret = await client.getSecretValue({ SecretId: 'prod/api-key' });
|
||||
const apiKey = JSON.parse(secret.SecretString).key;
|
||||
|
||||
// ❌ 錯誤:寫死或只在環境變數
|
||||
// FAIL: 錯誤:寫死或只在環境變數
|
||||
const apiKey = process.env.API_KEY; // 未輪換、未稽核
|
||||
```
|
||||
|
||||
@@ -99,7 +99,7 @@ aws secretsmanager rotate-secret \
|
||||
#### VPC 和防火牆設定
|
||||
|
||||
```terraform
|
||||
# ✅ 正確:限制的安全群組
|
||||
# PASS: 正確:限制的安全群組
|
||||
resource "aws_security_group" "app" {
|
||||
name = "app-sg"
|
||||
|
||||
@@ -118,7 +118,7 @@ resource "aws_security_group" "app" {
|
||||
}
|
||||
}
|
||||
|
||||
# ❌ 錯誤:對網際網路開放
|
||||
# FAIL: 錯誤:對網際網路開放
|
||||
resource "aws_security_group" "bad" {
|
||||
ingress {
|
||||
from_port = 0
|
||||
@@ -142,7 +142,7 @@ resource "aws_security_group" "bad" {
|
||||
#### CloudWatch/日誌設定
|
||||
|
||||
```typescript
|
||||
// ✅ 正確:全面日誌記錄
|
||||
// PASS: 正確:全面日誌記錄
|
||||
import { CloudWatchLogsClient, CreateLogStreamCommand } from '@aws-sdk/client-cloudwatch-logs';
|
||||
|
||||
const logSecurityEvent = async (event: SecurityEvent) => {
|
||||
@@ -177,7 +177,7 @@ const logSecurityEvent = async (event: SecurityEvent) => {
|
||||
#### 安全管線設定
|
||||
|
||||
```yaml
|
||||
# ✅ 正確:安全的 GitHub Actions 工作流程
|
||||
# PASS: 正確:安全的 GitHub Actions 工作流程
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
@@ -237,7 +237,7 @@ jobs:
|
||||
#### Cloudflare 安全設定
|
||||
|
||||
```typescript
|
||||
// ✅ 正確:帶安全標頭的 Cloudflare Workers
|
||||
// PASS: 正確:帶安全標頭的 Cloudflare Workers
|
||||
export default {
|
||||
async fetch(request: Request): Promise<Response> {
|
||||
const response = await fetch(request);
|
||||
@@ -281,7 +281,7 @@ export default {
|
||||
#### 自動備份
|
||||
|
||||
```terraform
|
||||
# ✅ 正確:自動 RDS 備份
|
||||
# PASS: 正確:自動 RDS 備份
|
||||
resource "aws_db_instance" "main" {
|
||||
allocated_storage = 20
|
||||
engine = "postgres"
|
||||
@@ -327,10 +327,10 @@ resource "aws_db_instance" "main" {
|
||||
### S3 Bucket 暴露
|
||||
|
||||
```bash
|
||||
# ❌ 錯誤:公開 bucket
|
||||
# FAIL: 錯誤:公開 bucket
|
||||
aws s3api put-bucket-acl --bucket my-bucket --acl public-read
|
||||
|
||||
# ✅ 正確:私有 bucket 並有特定存取
|
||||
# PASS: 正確:私有 bucket 並有特定存取
|
||||
aws s3api put-bucket-acl --bucket my-bucket --acl private
|
||||
aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json
|
||||
```
|
||||
@@ -338,12 +338,12 @@ aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json
|
||||
### RDS 公開存取
|
||||
|
||||
```terraform
|
||||
# ❌ 錯誤
|
||||
# FAIL: 錯誤
|
||||
resource "aws_db_instance" "bad" {
|
||||
publicly_accessible = true # 絕不這樣做!
|
||||
}
|
||||
|
||||
# ✅ 正確
|
||||
# PASS: 正確
|
||||
resource "aws_db_instance" "good" {
|
||||
publicly_accessible = false
|
||||
vpc_security_group_ids = [aws_security_group.db.id]
|
||||
|
||||
Reference in New Issue
Block a user