웹 보안: 필수 보안 관행
개발팀
3분 읽기
보안OWASP웹개발
웹 보안: 필수 보안 관행
웹 애플리케이션의 보안은 개발 단계부터 고려해야 할 중요한 요소입니다.
OWASP Top 10
1. Injection (SQL, XSS, etc.)
// 나쁜 예: SQL Injection 위험
const query = `SELECT * FROM users WHERE email = '${email}'`;
// 좋은 예: Prepared Statement
const query = 'SELECT * FROM users WHERE email = ?';
db.query(query, [email]);
2. XSS (Cross-Site Scripting) 방지
// 나쁜 예: 사용자 입력을 직접 렌더링
const html = `<p>${userInput}</p>`;
// 좋은 예: 이스케이프 처리
const escapeHtml = (text) => {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
};
3. CSRF (Cross-Site Request Forgery) 방지
// CSRF 토큰 생성 및 검증
const generateCSRFToken = () => crypto.randomBytes(32).toString('hex');
// 폼에 토큰 포함
<form method="POST">
<input type="hidden" name="csrf" value="<%= csrfToken %>">
</form>
// 서버에서 검증
if (req.body.csrf !== req.session.csrfToken) {
return res.status(403).json({ error: 'CSRF token invalid' });
}
인증 보안
// 암호 해싱 (bcrypt 사용)
const bcrypt = require('bcryptjs');
const hashPassword = async (password) => {
const salt = await bcrypt.genSalt(10);
return bcrypt.hash(password, salt);
};
const comparePassword = async (password, hash) => {
return bcrypt.compare(password, hash);
};
JWT 토큰 보안
// JWT 서명 및 검증
const jwt = require('jsonwebtoken');
const generateToken = (userId) => {
return jwt.sign({ userId }, process.env.JWT_SECRET, {
expiresIn: '24h',
algorithm: 'HS256'
});
};
const verifyToken = (token) => {
try {
return jwt.verify(token, process.env.JWT_SECRET);
} catch (error) {
return null;
}
};
환경 변수 관리
# .env 파일 (git에서 제외)
DATABASE_URL=postgresql://user:password@localhost/db
JWT_SECRET=your-secret-key-here
API_KEY=your-api-key
# 절대 커밋하지 마세요!
# .gitignore에 .env 추가
echo ".env" >> .gitignore
HTTPS 및 SSL/TLS
// Express에서 HTTPS 강제
const helmet = require('helmet');
app.use(helmet());
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`);
}
next();
});
CORS 정책 설정
const cors = require('cors');
app.use(cors({
origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
Rate Limiting
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15분
max: 100, // 최대 100 요청
message: '너무 많은 요청이 발생했습니다.'
});
app.use('/api/', limiter);
입력 검증
const { body, validationResult } = require('express-validator');
app.post('/users', [
body('email').isEmail().normalizeEmail(),
body('password').isLength({ min: 8 }),
body('name').trim().isLength({ min: 1 })
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// 검증 통과
});
보안 체크리스트
- HTTPS/SSL 활성화
- 암호 해싱 구현
- CSRF 토큰 사용
- XSS 방지 (입력 이스케이프)
- SQL Injection 방지 (Prepared Statements)
- CORS 정책 설정
- Rate Limiting 구현
- 입력 검증 및 새니타이제이션
- 보안 헤더 설정
- 의존성 보안 업데이트
웹 보안은 지속적인 관심과 개선이 필요한 영역입니다.