Security

Security

์ด ์žฅ์—์„œ๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ธฐ์ˆ ์„ ๋ฐฐ์›๋‹ˆ๋‹ค.

Helmet

Helmet์€ HTTP ํ—ค๋”๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์„ค์ •ํ•˜์—ฌ ์ž˜ ์•Œ๋ ค์ง„ ์ผ๋ถ€ ์›น ์ทจ์•ฝ์ ์œผ๋กœ๋ถ€ํ„ฐ ์•ฑ์„ ๋ณดํ˜ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ Helmet์€ ๋ณด์•ˆ ๊ด€๋ จ HTTP ํ—ค๋”๋ฅผ ์„ค์ •ํ•˜๋Š” 12 ๊ฐœ์˜ ์ž‘์€ ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜ ๋ชจ์Œ์ž…๋‹ˆ๋‹ค (๋”๋ณด๊ธฐ). ๋จผ์ € ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค.

$ npm i --save helmet

์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๊ธ€๋กœ๋ฒŒ ๋ฏธ๋“ค์›จ์–ด๋กœ ์ ์šฉํ•˜์‹ญ์‹œ์˜ค.

import * as helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());

CORS

CORS (Cross-Origin Resource Sharing)๋Š” ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ํ›„๋“œ ์•„๋ž˜์—์„œ Nest๋Š” cors ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒจํ‚ค์ง€๋Š” ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. CORS๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด enableCors()๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);

๋˜ํ•œ ๊ตฌ์„ฑ ๊ฐ์ฒด๋ฅผ ์ด ํ•จ์ˆ˜์˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์†์„ฑ์€ ๊ณต์‹ cors ์ €์žฅ์†Œ์— ์ฒ ์ €ํ•˜๊ฒŒ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ Nest ์˜ต์…˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

const app = await NestFactory.create(ApplicationModule, { cors: true });
await app.listen(3000);

์กฐ๊ฑด ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ๋Œ€์‹  cors ๊ตฌ์„ฑ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค (์—ฌ๊ธฐ ์ฐธ์กฐ).

CSRF

์‚ฌ์ดํŠธ ๊ฐ„ ์š”์ฒญ ์œ„์กฐ (CSRF ๋˜๋Š” XSRF๋ผ๊ณ  ํ•จ)๋Š” ์›น ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์‹ ๋ขฐํ•˜๋Š” ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋ฌด๋‹จ ๋ช…๋ น์ด ์ „์†ก๋˜๋Š” ์›น ์‚ฌ์ดํŠธ์˜ ์•…์˜์ ์ธ ์•…์šฉ ์œ ํ˜•์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๊ณต๊ฒฉ์„ ์™„ํ™”ํ•˜๊ธฐ ์œ„ํ•ด csurf ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค.

$ npm i --save csurf

์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๊ธ€๋กœ๋ฒŒ ๋ฏธ๋“ค์›จ์–ด๋กœ ์ ์šฉํ•˜์‹ญ์‹œ์˜ค.

import * as csurf from 'csurf';
// somewhere in your initialization file
app.use(csurf());

Rate limiting

๋ฌด์ฐจ๋ณ„ ๋Œ€์ž… ๊ณต๊ฒฉ์œผ๋กœ๋ถ€ํ„ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ณดํ˜ธํ•˜๋ ค๋ฉด ์ผ์ข…์˜ ์†๋„ ์ œํ•œ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šด ์ข‹๊ฒŒ๋„ NPM์—๋Š” ์ด๋ฏธ ๋‹ค์–‘ํ•œ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์ค‘ ํ•˜๋‚˜๊ฐ€ express-rate-limit์ž…๋‹ˆ๋‹ค.

$ npm i --save express-rate-limit

์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๊ธ€๋กœ๋ฒŒ ๋ฏธ๋“ค์›จ์–ด๋กœ ์ ์šฉํ•˜์‹ญ์‹œ์˜ค.

import * as rateLimit from 'express-rate-limit';
// somewhere in your initialization file
app.use(
  rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // limit each IP to 100 requests per windowMs
  }),
);

info ํžŒํŠธ FastifyAdapter๋กœ ์ž‘์—…ํ•˜๋Š” ๊ฒฝ์šฐ fastify-rate-limit๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ด๋ณด์‹ญ์‹œ์˜ค.

Last updated