CORS, CSRF, XSS 대응
웹 애플리케이션의 보안은 개발 과정에서 가장 중요한 고려사항 중 하나입니다.
CORS, CSRF, XSS는 현대 웹 애플리케이션이 직면한 주요 보안 위협으로, NestJS 애플리케이션에서 이에 대한 적절한 대응이 필수적입니다.
CORS (Cross-Origin Resource Sharing)
CORS는 다른 출처의 리소스에 대한 접근을 제어하는 보안 메커니즘입니다.
NestJS에서 CORS 구성
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: ['https://example.com', 'https://www.example.com'],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true,
});
await app.listen(3000);
}
bootstrap();
이 설정은 특정 도메인에서의 요청만 허용하고, 인증 정보를 포함한 요청을 가능하게 합니다.
CSRF (Cross-Site Request Forgery)
CSRF는 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 공격입니다.
NestJS에서 CSRF 방지
- csurf 미들웨어 사용
import * as csurf from 'csurf';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(csurf());
await app.listen(3000);
}
bootstrap();
- CSRF 토큰 검증
import { Controller, Get, Post, Req, Res } from '@nestjs/common';
import { Request, Response } from 'express';
@Controller('auth')
export class AuthController {
@Get('csrf-token')
getCsrfToken(@Req() req: Request, @Res() res: Response) {
res.json({ csrfToken: req.csrfToken() });
}
@Post('login')
login(@Req() req: Request) {
// CSRF 토큰은 자동으로 검증됩니다.
// 로그인 로직
}
}
XSS (Cross-Site Scripting)
XSS는 웹사이트에 악성 스크립트를 삽입하여 사용자의 브라우저에서 실행되게 하는 공격입니다.
XSS 방어 기법
- 입력 유효성 검사
import { IsString, IsEmail, MinLength } from 'class-validator';
export class CreateUserDto {
@IsString()
@MinLength(2)
name: string;
@IsEmail()
email: string;
}
- 출력 인코딩
import { Controller, Get } from '@nestjs/common';
import { escape } from 'he';
@Controller('users')
export class UsersController {
@Get(':id')
getUser(@Param('id') id: string) {
const user = this.userService.findOne(id);
return {
name: escape(user.name),
email: escape(user.email),
};
}
}
- HttpOnly 쿠키 사용
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cookieParser from 'cookie-parser';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(cookieParser());
app.use((req, res, next) => {
res.cookie('session', 'session-value', { httpOnly: true, secure: true });
next();
});
await app.listen(3000);
}
bootstrap();
Content Security Policy (CSP)
CSP는 XSS 공격을 방지하기 위한 추가적인 보안 계층을 제공합니다.
NestJS에서 CSP 구현
import helmet from 'helmet';
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", 'example.com'],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
})
);
보안 헤더 설정
NestJS에서 Helmet을 사용하여 다양한 보안 헤더를 쉽게 설정할 수 있습니다.
import helmet from 'helmet';
app.use(helmet());
이 설정은 X-XSS-Protection, X-Frame-Options, Strict-Transport-Security 등의 헤더를 자동으로 설정합니다.
입력 유효성 검사와 출력 인코딩
NestJS에서는 class-validator와 class-transformer를 사용하여 효과적인 입력 유효성 검사를 수행할 수 있습니다.
import { IsString, IsEmail, MinLength } from 'class-validator';
import { Transform } from 'class-transformer';
import { escape } from 'he';
export class CreateUserDto {
@IsString()
@MinLength(2)
@Transform(({ value }) => escape(value))
name: string;
@IsEmail()
@Transform(({ value }) => escape(value))
email: string;
}
서버 사이드 렌더링(SSR)에서의 보안
SSR을 사용하는 NestJS 애플리케이션에서는 클라이언트로 전송되는 HTML을 신중하게 처리해야 합니다.
- 템플릿 엔진 보안 설정
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';
import * as nunjucks from 'nunjucks';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const nunjucksEnv = nunjucks.configure('views', {
autoescape: true,
express: app,
});
await app.listen(3000);
}
bootstrap();
- 동적 데이터 처리
@Get()
@Render('index')
root(@Req() req) {
return {
title: 'My App',
user: {
name: escape(req.user.name),
},
};
}
종합적인 방어 전략
- 정기적인 보안 감사 : 의존성 검사, 코드 리뷰, 취약점 스캔
- 최신 버전 유지 : NestJS 및 모든 의존성 패키지를 최신 버전으로 유지
- 인증과 인가 : 강력한 인증 메커니즘 구현 및 적절한 접근 제어
- HTTPS 강제 : 모든 통신에 HTTPS 사용
- 에러 처리 : 상세한 에러 메시지를 클라이언트에 노출하지 않음
- 로깅과 모니터링 : 보안 관련 이벤트 로깅 및 실시간 모니터링
- 보안 교육 : 개발 팀의 보안 인식 제고
CORS, CSRF, XSS에 대한 대응은 웹 보안의 기본이지만 매우 중요한 부분입니다.
CORS 설정을 통해 리소스 접근을 제어하고, CSRF 토큰을 사용하여 위조 요청을 방지하며 다양한 XSS 방어 기법을 적용하여 악성 스크립트 실행을 차단해야 합니다.
Content Security Policy의 구현은 XSS 공격에 대한 추가적인 방어 계층을 제공하며 적절한 보안 헤더 설정은 다양한 웹 취약점으로부터 애플리케이션을 보호합니다. 입력 유효성 검사와 출력 인코딩은 데이터 처리의 모든 단계에서 철저히 적용되어야 합니다.
서버 사이드 렌더링을 사용하는 경우, 템플릿 엔진의 보안 설정과 동적 데이터 처리에 특별한 주의를 기울여야 합니다.
자동 이스케이프 기능을 활성화하고, 사용자 입력 데이터를 항상 검증 및 이스케이프 처리해야 합니다.