Node.js Express 애플리케이션에서 CSRF 공격 방지하는 방법

Node.js Express 애플리케이션에서 CSRF 공격 방지하는 방법

웹 애플리케이션 보안의 중요한 측면 중 하나는 CSRF(Cross-Site Request Forgery) 공격을 방지하는 것입니다. CSRF 공격은 사용자가 자신의 의지와 무관하게 공격자가 의도한 행위를 웹 애플리케이션에서 실행하게 만드는 보안 취약점입니다.

CSRF 보호를 위한 npm 패키지 설치

Express 애플리케이션에서 CSRF 공격을 방지하기 위해, csurfcookie-parser 미들웨어를 설치할 필요가 있습니다.

npm install csurf
npm install cookie-parser

CSRF 적용하지 않은 경우

Node.js와 Express를 사용하여 CSRF 보호 없이 간단한 폼 제출을 처리하는 예제 코드입니다.

const express = require('express'); // Express 모듈 불러오기
const bodyParser = require('body-parser'); // bodyParser 모듈 불러오기, POST 요청 데이터를 파싱

const app = express();
app.use(bodyParser.urlencoded({ extended: true })); // URL 인코딩된 데이터를 분석해서 req.body로 만듦

// '/form' 경로에 GET 요청이 오면, HTML 폼을 보내는 라우트
app.get('/form', (req, res) => {
  res.send('<form action="/submit" method="post"><input type="text" name="data"/><input type="submit" value="Submit"/></form>');
});

// '/submit' 경로에 POST 요청이 오면, 요청의 바디에서 데이터를 처리하는 라우트
app.post('/submit', (req, res) => {
  console.log(req.body.data); // 콘솔에 입력된 데이터 출력
  res.send('Data received'); // 응답으로 'Data received' 메시지 전송
});

// 3000번 포트에서 서버 실행, 서버 시작 시 콘솔에 메시지 출력
app.listen(3000, () => {
  console.log('Server running on port 3000');
});

위 코드는 /form 경로에 접근하면 간단한 입력 폼을 제공하고, 폼을 제출하면 /submit 경로에서 데이터를 처리합니다. 하지만 이 예제는 CSRF 공격에 취약합니다.

CSRF 적용한 경우

Express에서 CSRF 공격을 방지하기 위해 csurf 미들웨어를 사용하는 방법입니다.

const express = require('express'); // Express 모듈 불러오기
const bodyParser = require('body-parser'); // bodyParser 모듈 불러오기, POST 요청 데이터 파싱
const cookieParser = require('cookie-parser'); // cookieParser 모듈 불러오기, 쿠키 파싱
const csrf = require('csurf'); // csrf 모듈 불러오기, CSRF 보호 기능 제공

const csrfProtection = csrf({ cookie: true }); // CSRF 토큰을 쿠키에 저장하는 설정
const app = express();

app.use(bodyParser.urlencoded({ extended: true })); // URL 인코딩된 데이터를 분석해서 req.body로 만듦
app.use(cookieParser()); // 쿠키 파싱 미들웨어 적용

// '/form' 경로에 GET 요청이 오면 CSRF 토큰을 포함한 HTML 폼을 보내는 라우트
app.get('/form', csrfProtection, (req, res) => {
  res.send(`<form action="/submit" method="post">
    <input type="hidden" name="_csrf" value="${req.csrfToken()}"/> // CSRF 토큰을 숨김 필드로 포함
    <input type="text" name="data"/>
    <input type="submit" value="Submit"/>
  </form>`);
});

// '/submit' 경로에 POST 요청이 오면, 요청의 바디에서 데이터를 처리하는 라우트
// csrfProtection 미들웨어가 요청의 CSRF 토큰 유효성을 검사
app.post('/submit', csrfProtection, (req, res) => {
  console.log(req.body.data); // 콘솔에 입력된 데이터 출력
  res.send('Data received and protected'); // 응답으로 'Data received and protected' 메시지 전송
});

// 3000번 포트에서 서버 실행, 서버 시작 시 콘솔에 메시지 출력
app.listen(3000, () => {
  console.log('Server running on port 3000');
});

위 코드는 csurf 미들웨어를 사용하여 CSRF 토큰을 생성하고, 폼에 CSRF 토큰을 포함시킵니다. 제출된 폼 데이터와 함께 전송된 CSRF 토큰이 유효한 경우에만 데이터를 처리합니다. 이렇게 하면, 사용자가 자신의 의지와는 무관하게 악의적인 요청을 보내는 것을 방지할 수 있습니다.

Node.js Express 애플리케이션에서 CSRF 적용한 경우 실행 화면

참고 사이트

더 자세한 정보와 보안 관련 내용은 Express 공식 보안 가이드OWASP CSRF 방지 치트 시트를 참고하세요.

관련 이전 게시글

이 글이 도움이 되셨다면 공유 부탁 드립니다.

위로 스크롤