XSS , CSRF

박찬영·2024년 2월 18일
0

XSS

XSS(Cross-Site-Scripting)는 웹사이트에서 의도치 않은 스크립트를 넣어서 실행시키는 기법을 말합니다.

보통 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어집니다.
그리고 스크립트가 포함된 글을 열어보게 되면 브라우저에서 원치 않는 스크립트가 실행되는 방식이죠.

이걸 통해 유저의 쿠키 정보를 탈취하거나, 유저 비밀번호를 변경하는 api를 호출하는 행위를 할 수 있습니다.

  1. Perpetrator(침입자)는 사이트의 취약점을 찾습니다.
  2. 취약점을 찾아서 세션 쿠키를 탈취하는 스크립트를 사이트에 삽입합니다.
  3. 사용자가 그 웹사이트에 접근할 때마다 스크립트가 작동합니다
  4. 스크립트를 통해 침입자에게 사용자의 세션 쿠키가 전달됩니다.

위는 가장 기초적인 방식이고, XSS의 종류는 크게 세 가지로 나눌 수 있습니다.

  1. Stored XSS
    XSS 공격 스크립트를 웹 사이트의 방명록이나 게시판에 삽입하고,
    다른 사용자들이 그 글을 확인할 때 스크립트 코드가 사용자에게 전달되고
    세션 쿠키가 침입자에게 전달되는 방식입니다.

스크립트를 웹 서버에 저장하기 때문에 Stored라는 이름이 붙게 되었습니다.

  1. Reflected XSS
    공격 스크립트가 삽입된 URL을 사용자가 클릭하도록 유도하는 방식입니다.
    클릭 요청이 발생하면 바로 스크립트가 반사되어 돌아온다고 해서 Reflected라는 이름이 붙었습니다.
    보통 피싱공격에 많이 사용되는 부분입니다.

  1. DOM-based XSS
    사용자의 브라우저에서 DOM 환경을 수정하면 스크립트가 실행되는 방식입니다.
    페이지 자체는 변경되지 않지만 DOM에서 발생한 수정으로 인해
    페이지에 포함된 클라이언트쪽 코드가 다르게 실행됩니다.

조금 더 쉽게 말하면 스크립트는 HTML페이지가 구문분석이 될 때마다 실행됩니다.
그렇기 떄문에 다른 XSS 방식과는 다르게 서버와는 전혀 관계가 없습니다.

XSS의 방지 대책

쿠키에 중요한 정보를 담지 않고 서버에 중요 정보를 저장하는 방식을 사용할 수 있습니다.
그리고 httponly 속성을 다는 방식을 사용할 수 있습니다.
(document.cookie를 이용해서 쿠키에 직접 접근하는 것을 막는 옵션입니다!)
마지막으로 웹 애플리케이션에서 Content Security Policy (CSP)를 설정하여
외부 스크립트의 실행을 제한하고 안전한 리소스만 허용합니다.

<meta http-equiv="Content-Security-Policy" content="default-src 'self';">

하지만 React를 사용하면 기본적으로 XSS(Cross-Site Scripting) 공격에 대한 방어가 강화됩니다.
React는 JSX를 사용하고, JSX는 사용자 입력을 자동으로 이스케이핑하여 안전하게 렌더링하기 때문입니다. 즉, React 컴포넌트를 통해 사용자 입력을 출력할 때 React는 스크립트가 실행되지 않도록 처리합니다.

import React from 'react';
const userInput = "<script>alert('XSS attack');</script>";

function App() {
  return (
    <div>
      {userInput}
    </div>
  );
}

export default App;

이렇게 해커가 스크립트를 넣어줘도 자연스럽게 이스케이핑 되기 때문에 해결할 수 있습니다.

이스케이핑
사용자 입력 중에서 HTML 태그와 스크립트가 아닌 일반 텍스트로 처리되도록 하는 과정을 의미합니다.
여러 분야에서 이스케이핑이 사용되지만 주로 웹 보안과 관련이 있습니다.
웹 애플리케이션에서는 사용자 입력을 이스케이핑하여 웹 페이지에 안전하게 표시하고,
원치 않는 스크립트 실행을 방지하는 데 사용됩니다.

  1. CSRF
    CSRF 공격(Cross-Site-Request-Forgery)은 웹 어플리케이션 취약점 중 하나로
    사용자가 자신의 의지와는 무관하게 침입자가 의도한 행위를 서버에 요청하게 만드는 공격입니다.

XSS가 사용자가 특정 사이트를 신뢰하기 때문에 발생하는 문제라면,
CSRF는 특정 사이트가 사용자를 신뢰하기 때문에 발생하는 문제입니다.

즉 XSS는 클라이언트의 브라우저에서 발생하는 문제라면 CSRF는 서버에서 발생하는 문제입니다.
침입자가 XSS를 사용하면 사용자의 쿠키를 탈취할 수 있고,
CSRF를 사용하면 서버로부터 권한을 탈취할 수 있습니다.

  1. Perpetrator(침입자)는 서버로 넘어가는 자금 전송에 대한 요청을 조작하려고 합니다.
  2. 침입자는 하이퍼링크에 자금 전송 요청에 대한 스크립트를 삽입하고
    사이트에 로그인할 사람들에게 전송합니다.
  3. 사용자는 링크를 누르고, 의도치않게 서버로 요청을 보내게 됩니다.
  4. 서버는 로그인 되어있는 사용자의 요청이기 떄문에 정상으로 인식하고 침입자에게 돈을 전송합니다.

다른 예시를 보면 사용자는 mybank에 로그인하고 침입자의 url에 접근하면 CSRF코드가 실행되고,
브라우저는 mybank에게 사용자가 원하지 않는 요청을 보내게 됩니다.
mybank는 이 요청을 사용자가 보낸 요청이라 생각하고 정상적으로 처리되고, 침입자에게 돈이 전달되는 것이죠.

CSRF 를 막는 방법

Cross-Site Request Forgery (CSRF)를 방지하는 가장 흔한 방법은
요청에 CSRF 토큰을 포함시키는 것입니다.
이 토큰은 사용자의 세션과 연결되어 있으며,
악의적인 웹 사이트에서 해당 토큰을 갖고 있는 경우에도 CSRF 공격을 실행하지 못하도록 합니다.

// Express.js를 사용하는 예시
const express = require('express');
const session = require('express-session');
const csrf = require('csurf'); // CSRF 미들웨어

const app = express();

app.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized: true }));
const csrfProtection = csrf();
app.use(csrfProtection);

// 라우트 핸들러에서 CSRF 토큰을 클라이언트로 전송
app.get('/my-form', (req, res) => {
  res.render('my-form', { csrfToken: req.csrfToken() });
});
// ...
profile
오류는 도전, 코드는 예술

0개의 댓글

관련 채용 정보