애플리케이션 보안

  • 주입(Injection)
  • 크로스 사이트 스크립트(Cross-site scripting)
  • 크로스 사이트 요청 위조 토큰 보호(Cross-site request forgery protection)
  • 오픈 리다이렉션(Open redirects)

주입(Injection)

  • SQL 주입은 애플리케이션에 영향을 끼치는 가장 일반적인 주입의 형태입니다.
const query = `SELECT * FROM user WHERE username = ${username} AND password = ${password}`;
  • 위의 경우 username이 OR 1=1 -- 일 경우 -- 문자 시퀀스는 라인의 나머지 부분을 주석으로 만들기 때문에 SELECT * FROM user WHERE username = OR 1=1가 되어 사용자 전체 리스트를 반환합니다.
  • SQL 주입을 방지하기 위한 방법은 준비된 문장(prepared statements)을 사용하는 것입니다.
  • 라이브러리에서 제공하는 메소드를 활용해서 이스케이프 문자를 사용합니다.

입력 유효성 검사

  • 서버에 손상된 데이터가 들어가는 것을 방지하는 가장 쉬운 방법은 입력 유효성 검사(Input validation)입니다.
  • 입력 유효성 감사는 다음과 같은 두 가지 유형이 있습니다.
    • 화이트 리스팅(White listing)
    • 블랙 리스팅(Black listing)
  • 블랙 리스팅은 위험한 기법입니다. 권장되는 방식은 사용자로부터 들어오는 데이터를 정규 표현식을 이용해 검증하는 화이트 리스팅 방식입니다.
  • 입력 유효성 검사는 SQL 주입에 만능 해결책은 아니지만, 크로스 사이트 스크립팅 같은 다른 보안 위협에 도움이 됩니다.

크로스 사이트 스크립팅(cross-site scripting, XSS)

  • Cross Site Scripting의 약자로 CSS라고 하는 것이 맞지만 Cascading Style Sheets의 약어로 사용되어 있어 XSS라고 합니다.
  • 주로 웹 사이트에서 클라이언트 브라우저의 데이터를 훔칠 수 있는 주입 코드를 넣는 것입니다.
  • XSS 게시판이나 웹 메일 등에 자바스크립트 같은 스크립트 코드를 삽입해 개발자가 고려하지 않은 기능이 작동하게 하는 치명적일 수 있는 공격 입니다.
  • 대부분의 웹 해킹 공격 기법과는 다르게 클라이언트 즉, 사용자를 대상으로 한 공격입니다.
  • 일부 인터넷 웹 사이트의 경우, 사용자는 임의의 입력이 있는 주석을 추가할 수 있습니다. 이 잉ㅁ의의 입력은 원격 서버에서 세션 쿠키(또는 다른 귀중한 정보)를 훔칠 수 있습니다. 또한 공격자가 원격 머신에서 사용자 세셔능ㄹ 복제할 수 있는 자바스크립트를 로드시키는 스크립트 태그도 포함시킬 수 있습니다.
  • XSS 공격에는 영구적인(persistent) 공격과 비영구적인(non-presistent) 공격이 있습니다.
    • 영구적인 유형의 XSS는 웹 사이트에서 사용자에게 표시될 때, 공겨긍로 분석되는 텍스트의 특정 문자열을 만드는 XSS 공격을 저장하는 것으로 이루어집니다. 이 코드는(포럼의 주석과 같이) 데이터베이스에 저장된 임의의 입력 텍스트를 통해 주입됩니다.
    • 비영구적인 유형의 XSS는, 잘못된 데이터 처리로 인해 애플리케이션의 비영구적인 부분으로 삽입되는 경우입니다.

대처방안

  • <&lt로 바꿔주는 것으로 막아 줄 수 있습니다.
  • 추가적으로 &, ",', `, =과 같은 문자도 바꿔주는 것이 좋습니다.
  • react에서도 hrml을 넣을 때 <div dangerouslySetInnerHTML={{ __html: data }} />를 사용하지만 이름을 길고 어렵게 작성하고 객체로 만들어 둔 것이 사용을 권장하지 않기 때문이라고 합니다.

sznitize-html

  • 허용하지 않는 html 입력을 맏습니다.
npm i sanitize-html
const sanitizeHtml = require('sanitize-html');

const html = "<script>location.href = 'https://naver.com'</script";
console.log(sanitizeHtml(html)); // ''

출력 인토딩(output encoding)

  • 문제를 우베 개발로 축소하는 경우, 다음과 같이 출력 인코딩이 필요한 세 영역을 알아둬야 합니다.
    • CSS
    • Javascript
    • HTML
  • 일반적으로 앱을 만들 때 어떤 프레임워크를 사용하는지에 상관없이, 프레임워크는 항상 출력을 인코딩하는 함수를 갖고 있습니다.

크로스 사이트 요청 위조(Cross-site request forgery, CSRF)

  • 크로스 사이트 요청 위조는 크로스 사이트 요청 스크립팅의 반대입니다.
    • 크로스 사이트 요청 스크립트에서의 문제는 서버에서 오는 데이터에 있습니다. 이에 반해 크로스 사이트 요청 위조에서의 문제는 클라이언트로부터 오는 데이터를 신뢰하는 서버에 있습니다.
  • 세션 쿠키를 훔친 후, 공격자는 사용자로부터 정보를 훔칠 수 있을 뿐 아니라 쿠키와 관련된 계정 정보를 수정할 수도 있습니다.
  • 크로스 사이트 요청 위조 공격을 방지하는 방법은 엔드 포인트를 크로스 사이트 요청 토큰을 통해 보호하는 것입니다.
    • input에 type이 hidden인 임의의 토큰을 포함시켜 유효한 요청인지 확인합니다.

오픈 리다이렉트

  • 사용자는 악의적인 페이지로 리다엙션될 수 있습니다.
  • 이 문제에 대한 해결책은 신뢰하지 못하는 서드파티 웹사이트로 사용자를 리다이렉션 시키지 않습니다.
  • 가장 좋은 방법은 리아티렉션을 위한 대상 호스트를 화이트 리스팅하는 것입니다.
  • 기본적으로 우리의 소프트웨어가 고객을 알지 못하는 웹사이트로 리다이렉션 않도록 해야 합니다.

효과적인 코드 리뷰

  • 애플리케이션 내의 보안 결함을 감소시키는 가장 효과적인 방법 중 하나는 체계적이고 잘 알려진 코드 리뷰 프로세스를 지속적으로 수행하는 것입니다.
  • 항상 같은 두 단계의 리뷰를 수행해야 합니다.
    • 큰 그림을 얻기 위해 코드를 빠르게 검토합니다. 코드가 어떻게 작동하는지, 사용되는 기술 중 익숙하지 않은 기술은 어떤 것이 있는지, 코드에 대한 지원이 어떻게 수행되는지 등을 파악합니다.
    • 검토를 위한 체크리스트 항목에 따라 코드를 리뷰합니다.
  • 일반적으로 코드 리뷰 동안 코드 보안 관심 사항에 관련된 점검 항목 리스트는 상당히 방대합니다. 이를 다음 구성 요소에 따라 범위를 좁힐 수 있습니다.
    • 모든 입력이 적용되는 경우 검사/인코딩 됐는가?
    • 로그를 포함한 모든 출력이 인코딩 됐는가?
    • 크로스 사이트 요청 위조 토큰으로 엔드포인트를 보호하고 있는가?
    • 모든 사용자의 자격 증명이 암호화 되거나 데이터베이스 내의 해시로 처리됐는가?