Files
gh-lightsoft-dev-claude-plu…/commands/security-check.md
2025-11-30 08:37:48 +08:00

20 KiB
Raw Blame History

description
description
Comprehensive security scanning for secrets, vulnerabilities, and code issues

Security Checker

프로젝트의 보안 취약점을 포괄적으로 검사합니다. 환경 변수 노출, 하드코딩된 시크릿, 의존성 취약점, 코드 보안 이슈 등을 자동으로 탐지합니다.

Steps to follow:

1. 민감 정보 노출 검사 (최우선 순위)

보안에서 가장 중요한 부분입니다. 철저하게 검사하세요.

A. .gitignore 검증

1단계: .gitignore 파일 읽기

  • Read 도구로 .gitignore 파일 내용 확인
  • 파일이 없으면 경고

2단계: 필수 항목 확인 다음 항목이 포함되어 있는지 체크:

.env
.env.local
.env.development
.env.production
.env.*.local
node_modules/
.DS_Store
Thumbs.db
*.log
*.key
*.pem
credentials.json
secrets.json
config/secrets.*
.aws/
.gcloud/

누락된 항목은 경고로 표시

B. 환경 변수 파일 검사

검색할 파일들:

.env
.env.local
.env.development
.env.production
.env.test
.env.staging

Glob 도구로 검색:

**/.env*

각 파일에 대해:

  1. 파일이 존재하는지 확인

  2. .gitignore에 포함되어 있는지 확인

  3. 매우 중요: Git 히스토리에 커밋된 적이 있는지 확인

    git log --all --full-history -- .env
    

    결과가 있으면 심각한 보안 문제:

    • 언제 커밋되었는지
    • 어떤 커밋 해시인지
    • 조치 방법 안내 (git filter-branch)

C. 하드코딩된 시크릿 탐지

Grep 도구로 전체 프로젝트 검색 (node_modules, .git 제외)

다음 패턴들을 검색:

1. API 키 패턴:

(api[_-]?key|apikey|api[_-]?secret)\s*[:=]\s*['""][^'""]{20,}['""]

2. AWS 키:

AKIA[0-9A-Z]{16}

3. Private 키:

-----BEGIN (RSA |EC |DSA )?PRIVATE KEY-----

4. 데이터베이스 연결 문자열 (비밀번호 포함):

(mongodb|postgresql|mysql):\/\/[^:]+:[^@]+@

5. 패스워드 하드코딩:

(password|passwd|pwd)\s*[:=]\s*['""][^'""]+['""]

6. 토큰:

(token|bearer|jwt)\s*[:=]\s*['""][^'""]{20,}['""]

7. GitHub 토큰:

gh[pousr]_[A-Za-z0-9_]{36,}

8. Stripe 키:

(sk|pk)_(test|live)_[A-Za-z0-9]{24,}

9. Google API 키:

AIza[0-9A-Za-z_-]{35}

10. Slack 토큰:

xox[baprs]-[0-9]{10,12}-[0-9]{10,12}-[A-Za-z0-9]{24,}

각 매칭에 대해:

  • 파일 경로와 라인 번호 기록
  • 매칭된 내용 (일부 마스킹)
  • 심각도: 매우 높음

예외 처리:

  • 주석 내용은 낮은 우선순위
  • 테스트 파일 (*.test.js, *.spec.js)은 표시하되 우선순위 낮춤
  • example, placeholder, your-key-here 같은 명확한 예시는 제외

D. Git 히스토리 검사

민감한 키워드가 과거 커밋에 있는지 검사:

git log -p | grep -iE "(password|api.key|secret|token|bearer|private.key)" | head -50

발견되면:

  • 어떤 커밋에서 발견되었는지
  • 파일명
  • 경고: 이미 Git 히스토리에 기록되었으므로 단순 삭제로는 부족
  • 조치 방법:
    # BFG Repo-Cleaner 사용 권장
    bfg --delete-files .env
    git reflog expire --expire=now --all
    git gc --prune=now --aggressive
    

2. 의존성 보안 검사

A. package.json 확인

1단계: package.json 읽기

  • Read 도구로 package.json 파일 읽기
  • dependencies와 devDependencies 확인

2단계: npm audit 실행

npm audit --json

결과 분석:

  • Critical: 즉시 수정 필요
  • High: 빠른 시일 내 수정
  • Moderate: 수정 권장
  • Low: 주시 필요

각 취약점에 대해:

  • 패키지 이름
  • 현재 버전
  • 취약점 설명
  • 권장 버전
  • 수정 방법

3단계: 오래된 패키지 확인

npm outdated

Major 버전이 뒤쳐진 패키지 표시

B. 의존성 라이선스 확인 (선택적)

위험한 라이선스 (GPL 등) 체크

3. 코드 보안 취약점 검사

A. SQL Injection 위험

위험한 패턴 검색 (Grep):

(query|execute)\s*\(\s*['""`].*\$\{.*\}.*['""`]
(query|execute)\s*\(\s*['""].*\+.*['""]

구체적 예시:

// 위험
db.query("SELECT * FROM users WHERE id = " + userId)
db.query(`DELETE FROM ${table} WHERE id = ${id}`)

// 안전
db.query("SELECT * FROM users WHERE id = ?", [userId])
db.query("SELECT * FROM users WHERE id = $1", [userId])

발견된 각 케이스:

  • 파일 및 라인 번호
  • 위험한 코드
  • 안전한 대체 코드 제안
  • 심각도: 높음

B. XSS (Cross-Site Scripting) 취약점

위험한 패턴 검색:

\.innerHTML\s*=
dangerouslySetInnerHTML
document\.write\(
eval\(

구체적 예시:

// 위험
element.innerHTML = userInput
<div dangerouslySetInnerHTML={{ __html: userData }} />
document.write(input)

// 안전
element.textContent = userInput
DOMPurify.sanitize(userInput)

심각도: 중간-높음

C. Command Injection

위험한 패턴:

exec\([^)]*\$\{
spawn\([^)]*\+
child_process.*\$\{

구체적 예시:

// 위험
exec(`rm -rf ${userInput}`)
spawn('sh', ['-c', command + userInput])

// 안전
execFile('rm', ['-rf', userInput])  // 인자를 배열로

심각도: 매우 높음

D. Path Traversal

위험한 패턴:

(readFile|writeFile|sendFile)\([^)]*\+
(readFile|writeFile|sendFile)\([^)]*\$\{

구체적 예시:

// 위험
fs.readFile(req.query.file)
res.sendFile(userPath)

// 안전
const safePath = path.join(__dirname, 'uploads', path.basename(filename))
fs.readFile(safePath)

심각도: 높음

E. 정규식 ReDoS (Regular Expression Denial of Service)

위험한 패턴:

  • 중첩된 반복: (a+)+
  • 백트래킹이 과도한 패턴
\(\.\*\)\+
\(\.\+\)\+

심각도: 중간

4. 설정 보안 검사

A. CORS 설정

파일 검색:

  • Express: cors()
  • 다른 프레임워크의 CORS 설정

위험한 설정 검색:

cors\(\s*\{\s*origin:\s*['"]\*['""]
Access-Control-Allow-Origin:\s*\*

발견 시:

  • 파일 및 위치
  • 현재 설정
  • 권장 설정:
    // 안전한 설정
    cors({
      origin: ['https://yourdomain.com', 'https://app.yourdomain.com']
    })
    

심각도: 중간

B. 보안 헤더 확인

검색할 헤더:

  • helmet 패키지 사용 여부
  • 수동 헤더 설정 여부

확인할 헤더:

  1. X-Frame-Options: Clickjacking 방지
  2. Content-Security-Policy: XSS 방지
  3. X-Content-Type-Options: MIME 스니핑 방지
  4. Strict-Transport-Security: HTTPS 강제
  5. X-XSS-Protection: XSS 필터

package.json에서 helmet 검색:

  • 없으면 권장

서버 파일에서 헤더 설정 검색:

setHeader\(['""]X-Frame-Options
setHeader\(['""]Content-Security-Policy
helmet\(\)

없으면 경고

C. HTTPS 강제 여부

검색:

(app\.use\(|middleware.*)(https|ssl|secure)

Production에서 HTTPS 강제하는지 확인

5. 인증/인가 보안

A. JWT 검증

위험한 패턴:

jwt\.decode\(

안전한 패턴:

jwt\.verify\(

decode만 사용하고 verify 안 하면 경고

예시:

// 위험
const decoded = jwt.decode(token)  // 검증 없음!

// 안전
const decoded = jwt.verify(token, SECRET_KEY)

B. 비밀번호 해싱

검색:

  • bcrypt, argon2, scrypt 사용 여부
  • 평문 비밀번호 저장 여부

위험한 패턴:

password\s*[:=]\s*req\.(body|params|query)\.password
INSERT.*password.*VALUES.*\$\{

안전한 패턴:

bcrypt\.(hash|compare)
argon2\.(hash|verify)

C. 세션 보안

검색:

  • express-session 설정
  • httpOnly, secure, sameSite 쿠키 옵션
// 안전한 설정
session({
  cookie: {
    httpOnly: true,
    secure: true,  // HTTPS only
    sameSite: 'strict'
  }
})

6. 프론트엔드 보안 (React/Vue/등)

A. 외부 스크립트 로딩

위험한 패턴:

<script\s+src=['""]http://
eval\(

CDN은 HTTPS 사용 권장

B. localStorage에 민감 정보

검색:

localStorage\.setItem\([^)]*token
localStorage\.setItem\([^)]*password
sessionStorage\.setItem\([^)]*token

권장: httpOnly 쿠키 또는 메모리에만 저장

7. Docker/컨테이너 보안 (선택적)

Dockerfile이 있으면:

A. Root 사용자 회피

# 위험
RUN apt-get install

# 안전
USER node
RUN apt-get install

B. 시크릿을 이미지에 복사하지 않음

# 위험
COPY .env /app/.env

# 안전: 환경 변수로 주입

8. 상세 보안 리포트 생성

모든 검사를 완료한 후, 다음 형식으로 종합 리포트를 생성하세요:


# 🔒 보안 검사 리포트

생성 일시: 2024-11-14 15:30:00
프로젝트: [프로젝트명]

---

## 📊 전체 요약

| 심각도 | 개수 |
|--------|------|
| 🚨 심각 (Critical) | 3 |
| ⚠️ 경고 (High) | 5 |
| 💡 주의 (Medium) | 8 |
|  정보 (Low) | 2 |

**전체 보안 점수: 68/100** (개선 필요)

---

## 🚨 심각 (즉시 수정 필요)

### 1. .env 파일이 .gitignore에 없음 ❌

**위치**: 루트 디렉토리
**발견 내용**: `.env` 파일이 존재하지만 `.gitignore`에 포함되지 않음
**위험도**: 매우 높음
**영향**: 환경 변수가 Git에 커밋되어 GitHub에 노출될 위험

**즉시 조치:**
```bash
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
git add .gitignore
git commit -m "Add .env to gitignore"

추가 확인: Git 히스토리에 이미 커밋되었는지 확인

git log --all --full-history -- .env

2. 하드코딩된 API 키 발견

파일: src/config/api.js:15 발견 내용:

const API_KEY = "your_actual_api_key_here_redacted";

위험도: 매우 높음 영향: API 키가 소스 코드에 노출되어 누구나 확인 가능

즉시 조치:

  1. .env 파일로 이동:

    # .env
    API_KEY=your_actual_api_key_here
    
  2. 코드 수정:

    const API_KEY = process.env.API_KEY;
    
  3. 중요: 노출된 키는 즉시 폐기하고 새로 발급

    • Stripe 대시보드에서 해당 키 삭제
    • 새 키 발급 후 .env에만 저장

3. Git 히스토리에 .env 파일 커밋 발견

커밋: a1b2c3d (2024-10-15) 파일: .env 위험도: 매우 높음 영향: GitHub에 이미 푸시되었다면 환경 변수가 공개 이력에 남음

즉시 조치:

# 1. BFG Repo-Cleaner 설치 (권장)
brew install bfg  # macOS
# 또는 https://rtyley.github.io/bfg-repo-cleaner/

# 2. .env 파일을 히스토리에서 완전 제거
bfg --delete-files .env

# 3. 히스토리 정리
git reflog expire --expire=now --all
git gc --prune=now --aggressive

# 4. Force push (주의: 팀원과 조율 필요)
git push origin --force --all

주의: Force push는 팀 전체에 영향을 미치므로 반드시 팀원들과 조율

노출된 모든 시크릿 교체 필요


⚠️ 경고 (빠른 수정 권장)

1. npm audit에서 5개의 취약점 발견

세부 내용:

Critical (1개)

  • lodash 4.17.15
    • 취약점: Prototype Pollution
    • CVSS: 9.8
    • 수정 버전: 4.17.21
    • 조치: npm install lodash@latest

High (2개)

  • axios 0.21.0

    • 취약점: SSRF (Server-Side Request Forgery)
    • CVSS: 8.1
    • 수정 버전: 0.21.4
  • minimist 1.2.5

    • 취약점: Prototype Pollution
    • 수정 버전: 1.2.8

Moderate (2개)

  • url-parse 1.5.3
  • ws 7.4.5

즉시 조치:

npm audit fix
# 또는 수동으로
npm install lodash@latest axios@latest minimist@latest

2. SQL Injection 위험 코드 발견 (3곳)

위치 1: src/db/users.js:42

위험한 코드:

const query = "SELECT * FROM users WHERE id = " + req.params.id;
db.query(query);

위험도: 높음 공격 시나리오: id=1 OR 1=1; DROP TABLE users;--

수정 방법:

// Parameterized Query 사용
const query = "SELECT * FROM users WHERE id = ?";
db.query(query, [req.params.id]);

// 또는 ORM 사용 (Sequelize, TypeORM 등)
const user = await User.findByPk(req.params.id);

위치 2: src/api/products.js:58

위험한 코드:

db.query(`DELETE FROM products WHERE category = '${category}'`);

수정 방법:

db.query("DELETE FROM products WHERE category = ?", [category]);

위치 3: src/services/search.js:23

위험한 코드:

const sql = `SELECT * FROM items WHERE name LIKE '%${searchTerm}%'`;

수정 방법:

const sql = "SELECT * FROM items WHERE name LIKE ?";
db.query(sql, [`%${searchTerm}%`]);

3. XSS 취약점 발견 (2곳)

위치 1: src/components/Profile.jsx:28

위험한 코드:

profileDiv.innerHTML = userData.bio;

위험도: 중간-높음 공격 시나리오: bio에 <script>alert('XSS')</script> 삽입

수정 방법:

// 방법 1: textContent 사용
profileDiv.textContent = userData.bio;

// 방법 2: sanitize 라이브러리
import DOMPurify from 'dompurify';
profileDiv.innerHTML = DOMPurify.sanitize(userData.bio);

위치 2: src/pages/Comments.tsx:45

위험한 코드:

<div dangerouslySetInnerHTML={{ __html: comment.text }} />

수정 방법:

// sanitize 후 사용
<div dangerouslySetInnerHTML={{
  __html: DOMPurify.sanitize(comment.text)
}} />

// 또는 일반 텍스트로
<div>{comment.text}</div>

4. CORS 설정이 너무 관대함

파일: server.js:10 현재 설정:

app.use(cors({ origin: '*' }));

위험도: 중간 영향: 모든 도메인에서 API 접근 가능 (CSRF 공격 위험)

수정 방법:

// 특정 도메인만 허용
app.use(cors({
  origin: [
    'https://yourdomain.com',
    'https://app.yourdomain.com'
  ],
  credentials: true
}));

// 또는 환경 변수로
app.use(cors({
  origin: process.env.ALLOWED_ORIGINS.split(','),
  credentials: true
}));

5. 보안 헤더 미설정

발견 내용: Express 서버에 보안 헤더가 설정되지 않음

누락된 헤더:

  • X-Frame-Options (Clickjacking 방지)
  • Content-Security-Policy (XSS 방지)
  • X-Content-Type-Options (MIME 스니핑 방지)
  • Strict-Transport-Security (HTTPS 강제)

수정 방법:

npm install helmet
// server.js
const helmet = require('helmet');
app.use(helmet());

// 또는 세밀한 설정
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      scriptSrc: ["'self'"],
      imgSrc: ["'self'", "data:", "https:"]
    }
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  }
}));

💡 주의 (개선 권장)

1. JWT 검증 누락 가능성

파일: src/middleware/auth.js:18 발견 내용:

const decoded = jwt.decode(token);

권장: verify 사용

const decoded = jwt.verify(token, process.env.JWT_SECRET);

2. 오래된 패키지

다음 패키지들의 Major 버전이 크게 뒤쳐져 있습니다:

패키지 현재 최신 업데이트
react 16.14.0 18.2.0 Major
express 4.17.1 4.18.2 Minor
webpack 4.46.0 5.88.2 Major

조치: 점진적 업데이트 권장 (Breaking changes 확인 필요)


3. localStorage에 토큰 저장

파일: src/utils/auth.js:12

localStorage.setItem('authToken', token);

권장: httpOnly 쿠키 사용 (XSS로부터 보호)


양호

.gitignore 설정

node_modules/ 포함됨 *.log 포함됨 .DS_Store 포함됨

비밀번호 해싱

bcrypt 사용 확인 (src/auth/password.js:25)

HTTPS 사용

Production에서 HTTPS 강제 (server.js:45)


📈 상세 점수

카테고리 점수 상태
민감 정보 관리 25/40 🚨 심각
의존성 보안 15/20 ⚠️ 경고
코드 보안 18/30 ⚠️ 경고
설정 보안 10/20 💡 주의
인증/인가 8/10 양호

전체 점수: 76/120 → 63/100


🎯 즉시 조치 항목 (우선순위)

오늘 반드시 수정:

  1. .env.gitignore에 추가
  2. src/config/api.js의 하드코딩된 API 키 제거
  3. 노출된 API 키 폐기 및 재발급

이번 주 내 수정:

  1. ⚠️ Git 히스토리에서 .env 제거
  2. ⚠️ SQL Injection 코드 수정 (3곳)
  3. ⚠️ npm audit fix 실행
  4. ⚠️ XSS 취약점 수정 (2곳)

이번 달 내 개선:

  1. 💡 helmet.js 설치 및 설정
  2. 💡 CORS 설정 강화
  3. 💡 주요 패키지 업데이트

📚 보안 개선 권장 사항

단기 (1주)

  • 모든 심각/경고 항목 수정
  • pre-commit hook 설정 (시크릿 검사)
  • 팀 보안 가이드라인 작성

중기 (1개월)

  • 정기적 보안 스캔 CI/CD 통합
  • 의존성 자동 업데이트 (Dependabot)
  • 보안 교육 실시

장기 (분기)

  • 침투 테스트 수행
  • 보안 감사 (Security Audit)
  • Bug Bounty 프로그램 고려

🔧 자동 수정 가능 항목

다음 항목은 자동으로 수정할 수 있습니다. 진행할까요?

  1. .gitignore.env 추가
  2. npm audit fix 실행
  3. helmet 설치 및 기본 설정
  4. 오래된 패키지 업데이트 (Minor 버전만)

🔐 보안 체크리스트

다음 보안 검사를 통과했습니다:

  • 환경 변수 관리

    • .env가 .gitignore에 있음
    • Git 히스토리에 시크릿 없음
    • 하드코딩된 키 없음
  • 의존성 보안

    • 알려진 취약점 없음
    • 최신 버전 사용
  • 코드 보안

    • SQL Injection 방지
    • XSS 방지
    • CSRF 방지
  • 서버 설정

    • 보안 헤더 설정
    • HTTPS 사용
    • CORS 적절히 설정

전체 체크리스트: 8/16 완료 (50%)


⏭️ 다음 단계

  1. 즉시: 심각 항목 3개 수정
  2. 오늘 중: npm audit fix 실행
  3. 내일: SQL Injection 및 XSS 코드 수정
  4. 이번 주: 보안 헤더 설정 및 CORS 강화
  5. 정기적: 매주 보안 스캔 실행 (/security-check)

보안은 지속적인 프로세스입니다. 정기적으로 점검하세요! 🔒


---

### 9. 자동 수정 제안 (선택적)

사용자에게 물어본 후, 안전하게 자동 수정 가능한 항목 처리:

#### A. .gitignore 업데이트
```bash
cat >> .gitignore << EOF
# Environment variables
.env
.env.local
.env.*.local

# Secrets
*.key
*.pem
credentials.json
secrets.json
EOF

B. npm audit fix

npm audit fix

C. helmet 설치

npm install helmet

사용자에게 확인 후 실행

10. CI/CD 통합 제안

.github/workflows/security-check.yml 생성 제안:

name: Security Check

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run npm audit
        run: npm audit
      - name: Check for secrets
        uses: trufflesecurity/trufflehog@main

Important Notes:

우선순위

  1. 민감 정보 노출 - 가장 높음
  2. 의존성 취약점 - 높음
  3. 코드 취약점 - 중간-높음
  4. 설정 문제 - 중간

False Positive 최소화

  • 테스트 파일은 우선순위 낮춤
  • 주석은 별도 표시
  • example, placeholder 같은 명확한 예시는 제외

사용자 경험

  • 한국어로 명확하게 설명
  • 각 문제에 대한 구체적인 수정 방법 제시
  • 위험도와 영향을 명확히 설명
  • 즉시 조치 항목과 장기 개선 항목 구분

에러 처리

  • Git이 없는 프로젝트도 처리
  • package.json이 없으면 해당 섹션 스킵
  • 권한 문제 등 예외 상황 안내

보안

  • 리포트에 실제 시크릿 전문을 노출하지 말 것 (마스킹)
  • 민감한 정보는 일부만 표시 (예: api_key_abc...xyz)