Node.js Express 애플리케이션에서 CSRF 공격 방지하는 방법
웹 애플리케이션 보안의 중요한 측면 중 하나는 CSRF(Cross-Site Request Forgery) 공격을 방지하는 것입니다. CSRF 공격은 사용자가 자신의 의지와 무관하게 공격자가 의도한 행위를 웹 애플리케이션에서 실행하게 만드는 보안 취약점입니다.
CSRF 보호를 위한 npm 패키지 설치
Express 애플리케이션에서 CSRF 공격을 방지하기 위해, csurf
와 cookie-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 토큰이 유효한 경우에만 데이터를 처리합니다. 이렇게 하면, 사용자가 자신의 의지와는 무관하게 악의적인 요청을 보내는 것을 방지할 수 있습니다.
참고 사이트
더 자세한 정보와 보안 관련 내용은 Express 공식 보안 가이드와 OWASP CSRF 방지 치트 시트를 참고하세요.
관련 이전 게시글
- Express에서 에러 처리하는 방법: 404와 500 에러 등
- Express의 express.static 내장 메서드로 정적 파일 읽어오는 방법
- Node.js에서 sanitize-html 미들웨어로 XSS 공격 방지하기
- Express의 Compression 미들웨어: 압축을 통한 응답 속도 향상
- Express 요청 데이터 파싱: 내장 메서드와 body-parser 미들웨어
이 글이 도움이 되셨다면 공유 부탁 드립니다.