보안 모범 사례와 취약점 스캐닝
NestJS 애플리케이션의 보안은 개발 과정에서 지속적으로 고려해야 할 중요한 요소입니다.
주요 보안 위협을 이해하고 적절한 방어 전략을 구현하는 것이 필수적입니다.
주요 보안 위협 및 방어 전략
- 인증 및 권한 부여 취약점
- 주입 공격 (SQL 인젝션, NoSQL 인젝션)
- 크로스 사이트 스크립팅 (XSS)
- 크로스 사이트 요청 위조 (CSRF)
- 민감한 데이터 노출
- 취약한 의존성
안전한 인증 및 권한 부여
NestJS에서 안전한 인증 시스템 구현
- Passport와 JWT 사용
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_SECRET,
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
- 역할 기반 접근 제어 (RBAC)
import { SetMetadata } from '@nestjs/common';
export const ROLES_KEY = 'roles';
export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);
@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard)
export class UsersController {
@Get()
@Roles('ADMIN')
findAll() {
// 관리자만 접근 가능
}
}
의존성 취약점 관리
npm audit을 사용한 취약점 검사
npm audit
npm audit fix
Snyk를 CI/CD 파이프라인에 통합
# .gitlab-ci.yml 예시
stages:
- test
- security
security:
stage: security
script:
- npm install -g snyk
- snyk test
- snyk monitor
OWASP Top 10 대응
1. 인젝션 방지
- TypeORM 사용 시 쿼리 파라미터화
const users = await this.userRepository
.createQueryBuilder('user')
.where('user.username = :username', { username: username })
.getMany();
2. 취약한 인증
- 강력한 비밀번호 정책 구현
import { IsString, Matches } from 'class-validator';
export class CreateUserDto {
@IsString()
@Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/, {
message: 'Password too weak',
})
password: string;
}
3. 민감한 데이터 노출
- 환경 변수 사용 및 암호화
import { ConfigService } from '@nestjs/config';
import * as bcrypt from 'bcrypt';
@Injectable()
export class UserService {
constructor(private configService: ConfigService) {}
async create(createUserDto: CreateUserDto) {
const hashedPassword = await bcrypt.hash(createUserDto.password, 10);
// 비밀번호 저장 로직
}
}
보안 테스팅 도구 통합
1. 정적 애플리케이션 보안 테스팅 (SAST)
- SonarQube 통합
# sonar-project.properties
sonar.projectKey=my-nestjs-project
sonar.sources=src
sonar.tests=test
sonar.typescript.lcov.reportPaths=coverage/lcov.info
2. 동적 애플리케이션 보안 테스팅 (DAST)
- OWASP ZAP 사용
docker run -t owasp/zap2docker-stable zap-baseline.py -t https://your-nestjs-app.com
웹 애플리케이션 보안 강화
- 보안 헤더 설정
import helmet from 'helmet';
app.use(helmet());
- HTTPS 적용
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as fs from 'fs';
async function bootstrap() {
const httpsOptions = {
key: fs.readFileSync('./secrets/private-key.pem'),
cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(AppModule, { httpsOptions });
await app.listen(3000);
}
bootstrap();
- 안전한 쿠키 설정
app.use(
session({
secret: 'my-secret',
resave: false,
saveUninitialized: false,
cookie: { secure: true, httpOnly: true, sameSite: 'strict' },
}),
);
정기적인 보안 감사와 침투 테스트
- 자동화된 보안 스캔 스케줄링
- 외부 보안 전문가에 의한 정기적인 침투 테스트 수행
- 발견된 취약점에 대한 즉각적인 대응 및 패치 적용
DevSecOps 통합
- CI/CD 파이프라인에 보안 검사 통합
# .gitlab-ci.yml 예시
stages:
- build
- test
- security
- deploy
security:
stage: security
script:
- npm audit
- snyk test
- sonar-scanner
- 보안 요구사항을 개발 초기 단계부터 고려
- 개발팀과 보안팀 간의 협력 강화
종합적인 보안 전략
- 보안 인식 교육 : 개발자 대상 정기적인 보안 교육 실시
- 최소 권한 원칙 적용 : 필요한 최소한의 권한만 부여
- 정기적인 보안 업데이트 : 의존성 및 NestJS 프레임워크 최신 버전 유지
- 보안 설계 검토 : 새로운 기능 개발 시 보안 측면 검토
- 인시던트 대응 계획 수립 : 보안 사고 발생 시 신속한 대응 체계 마련
- 지속적인 모니터링 : 로그 분석 및 이상 징후 탐지 시스템 구축
- 제3자 라이브러리 관리 : 사용하는 모든 외부 라이브러리의 보안성 검토
- 암호화 표준 준수 : 강력한 암호화 알고리즘 사용 및 주기적인 갱신
- 컨테이너 보안 : 도커 이미지 취약점 스캔 및 보안 설정 적용
- 클라우드 보안 : 클라우드 제공업체의 보안 모범 사례 준수
보안은 단순히 몇 가지 도구나 기술을 적용하는 것으로 끝나지 않습니다.
개발 생명주기 전반에 걸쳐 지속적이고 포괄적인 접근이 필요합니다.
안전한 인증 및 권한 부여 시스템 구축, 의존성 취약점 관리, OWASP Top 10과 같은 주요 보안 위험에 대한 대응, 그리고 다양한 보안 테스팅 도구의 활용은 기본적인 출발점입니다.
웹 애플리케이션 보안을 강화하기 위해 보안 헤더 설정, HTTPS 적용, 안전한 쿠키 사용 등의 기술적 조치를 취하는 것이 중요합니다.