[javascript] Express.js에서의 CSRF 공격 방어 방법

Cross-Site Request Forgery (CSRF) 공격은 웹 애플리케이션에서 발생하는 일반적인 보안 취약성 중 하나입니다. 이 공격은 인증된 사용자의 권한을 이용하여 악의적인 요청을 보내는 것을 통해 공격자가 임의의 동작을 수행할 수 있게 됩니다.

Express.js는 Node.js 기반의 웹 프레임워크로서, CSRF 공격에 대한 방어 기능을 기본적으로 제공하지 않습니다. 하지만, 우리는 다음과 같은 방법을 사용하여 Express.js 애플리케이션에서 CSRF 공격을 방어할 수 있습니다.

1. CSRF 토큰 사용

CSRF 공격을 방어하기 위해서는 HTML 폼을 서버로 전송할 때 CSRF 토큰을 함께 전송하여 사용해야 합니다. 이 토큰은 세션과 연결되어 생성되며, 폼 제출 시 토큰을 검증하는 방식으로 공격을 방어합니다.

const csrf = require("csurf");
const csrfProtection = csrf({ cookie: true });

// CSRF 방어 미들웨어 사용
app.use(csrfProtection);

// CSRF 토큰 생성 및 전달
app.get("/form", (req, res) => {
  const token = req.csrfToken();
  res.render("form", { csrfToken: token });
});

// 폼 제출 및 CSRF 토큰 검증
app.post("/submit", (req, res) => {
  // 토큰 검증 코드
});

위 예제에서는 csurf 미들웨어를 사용하여 CSRF 토큰 생성 및 검증을 처리합니다. csrfProtection 미들웨어를 사용하여 모든 라우트에서 CSRF 공격 방어를 활성화하고, req.csrfToken()을 통해 토큰을 생성하여 폼의 hidden 필드나 헤더에 포함시킬 수 있습니다.

2. SameSite 쿠키 설정

SameSite 쿠키 설정은 CSRF 공격을 방어하는 또 다른 방법입니다. 이 설정은 쿠키가 같은 사이트에서만 전송되도록 하는 것으로, 외부 사이트로의 쿠키 전송을 차단하는 역할을 합니다.

app.use(cookieParser());

// SameSite 설정으로 CSRF 공격 방어
app.use(session({
  secret: "my-secret",
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true, sameSite: "strict" }
}));

위 예제에서는 Express.js의 cookie-parserexpress-session을 사용하여 SameSite 설정을 적용합니다. sameSite: "strict"로 설정하면 쿠키는 오직 같은 도메인 내에서만 전송됩니다.

3. 미들웨어 순서 확인

Express.js에서는 미들웨어 순서가 중요합니다. CSRF 방어 미들웨어인 csurf를 다른 미들웨어보다 먼저 등록하는 것이 중요합니다. 그렇지 않으면 CSRF 토큰이 유효하지 않은 상태로 요청이 전송될 수 있습니다.

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(csrfProtection);

위 예제에서는 express.json(), express.urlencoded(), cookieParser() 순서로 미들웨어를 등록한 후, 마지막으로 csrfProtection 미들웨어를 등록합니다.

요약

Express.js 애플리케이션에서 CSRF 공격을 방어하기 위해서는 CSRF 토큰을 사용하고, SameSite 쿠키 설정을 적용하며, 미들웨어 순서를 올바르게 지정해야 합니다. 이러한 방법을 통해 사용자의 보안을 강화하고 웹 애플리케이션의 취약성을 줄일 수 있습니다.

참고문헌: