본문 바로가기
Today I Learned 2024. 10. 8.

(24.10.08) 보안 공격 정리 : SQL Injection, CSRF, XSS

 

 

Spring Framework에 기반으로 백엔드를 작성했기 때문에,

그 안의 Spring Security를 활용해서 기본적으로 CSRF 등을 방지할 수 있는 기능이 활성화되어 이를 사용하기도 했고,

JWT 역시 헤더에 넣는 방향으로 탈취를 방지하도록 설계를 했기 때문에

직접적으로 보안 취약점을 다룰 수 있는 기회가 많이 있지는 않았다.

 

하지만, 실무에서 또, 언제나 항상 관련한 내용을 인지하고 있고, 어떻게 공격이 진행이 되는지,

그리고 어떻게 방어와 예방을 할 수 있는지를 찾아보고 나름대로 내용을 합쳐서 정리를 했다.

 


SQL Injection

  • Application 에서 외부에서 입력한 값을 직접적으로 SQL 쿼리에 포함시켜 DB에 접근하여 실행시는 과정에서의 취약점
  • DB를 임의로 조작, 중요 정보를 서버에서 탈취하거나 삭제, 수정이 가능
  • Application ↔ DB 간 서비스를 작동할 때, 동적으로 만들어지는 쿼리에서 발생

EXAMPLE

로그인 우회

SELECT * FROM users WHERE username = '사용자 입력' AND password = '사용자 입력';
  • 만약 위의 쿼리가 서버에서 동적으로 사용자의 입력값에 의해 바뀌어서 DB에 요청하는 상태로 가정
**// 우회 코드

//** WHERE 조건절을 참(1=1)으로 만들어서 로그인을 할 수 있게끔 하는 방식
****SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '';

// --을 사용해 일부분을 주석처리=무효화 하는 방식 
SELECT * FROM users WHERE username = 'admin' -- ' AND password = '...';
  • 이 외 일부를 무효화 또는 논리적인 우회를 통해서 DB에 접근

방지 방법

ORM 사용

  • Java 기준 JPA, Hibernate와 같은 ORM 도구를 사용하여 SQL 쿼리를 직접 작성하지 않고 객체단에서 다룰 수 있도록 설계

최소 권한 부여

  • DB 계정 자체에 최소한의 권한만 부여 : 쿼리를 통해 바꾸는 권한을 주지 않도록

입력값 필터링

  • 외부 입력값을 검증을 통해, SQL 예약어, 주석기호 등을 필터링, 또는 이스케이프 할 수 있는 로직을 추가

JDBC의 PreparedStatement 사용

  • PreparedStatement
    • SQL문을 Complie 단계에서 ? 를 사용하여 pre-Compile 하여 미리 준비 → Query문 자체를 바인딩 변수를 활용해서 실행하고 결과만을 받는 방식
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, username); // 사용자가 입력한 username 
pstmt.setString(2, password); // 사용자가 입력한 password
  • 위처럼 미리 query자체를 입력 받는 것이 아닌, ? 부분으로 동적인 변수로 활용할 수 있게끔 해서 일종의 파라미터 값만을 수정하는 방식으로 변경

CSRF (Cross-Site Request Forgery)

  • 사용자가 신뢰하는 웹사이트에서 인증된 상태에서 공격자가 이 인증된 정보를 가지고 서버에 원치 않는 요청을 실행하도록 유도하는 보안 취약점
  • 로그인을 정상적으로 완료한 후, 세션 유지 상태, 또는 생성된 쿠키를 탈취해서 공격
    1. 사용자가 공격자가 작성한 탈취용 링크로 접근 (브라우저)
    2. 악성 스크립트를 통해 서버로 자동으로 보내는 사용자의 쿠키/인증 정보악의적인 요청을 함께 요청
      • 이 과정에서 세션일 경우엔 이미 로그인 된 세션을 인지하고 시도
    3. 서버는 인증 정상진행, 리소스에 접근 권한 부여
    4. 리소스 정보 변경 및 탈취 진행

방지 방법

CSRF 토큰 사용

  • 가장 통용되는, 클라이언트 ↔ 서버 간 요청/응답에 대해 고유한 토큰을 생성, 포함시킨 후, 검증을 하는 방식
  • Spring Framework에서 제공해주는 Spring Security 보안 프레임워크에서는 기본적으로 CSRF 토큰을 자동처리 (CSRF 보호처리)

Header에 인증 정보 적용

  • 악의적인 스크립트로 인증/인가용 쿠키가 요청과 따로 존재하거나, 이미 세션방식만을 채택한 설계보다 요청시 동시에 Header에 JWT 내지는 인증 토큰을 포함시키는 방식
  • Stateless 한 상태를 유지하는 상태(Session 방식이 아닌 상태)에서 사용하기 유용한 방식

XSS (Cross-Site Scripting)

  • 웹 Application 에서 악성 스크립트를 Web Page 내에서 삽입을 하여 공격하는 방식
  • 정보 탈취, 악성 코드를 배포, 인증 정보 탈취 후 악용 등 스크립

공격유형

저장형 Stored XSS

  • 공격자가 악성 스크립트를 Web Application DB에 직접적으로 저장 → 클라이언트가 요청할 때 마다, 페이지에서 해당 스크립트가 실행
  • ex) 특정 게시판, 기능을 실행시킬때 악성코드를 실행시키게 가능

반사형 Reflected XSS

  • 사용자가 클릭하면 악성 스크립트가 실행되는 URL에 접속할 수 있게끔 유도하는 방식
  • ex) 악성 이메일, 채팅, 스팸등이 이 방법

방지 방법

입력값 검증 / 인코딩

  • 악성 스크립트가 포함되어 있는지 확인하는 로직을 추가
  • 사용자 입력을 출력할 때, 추가 스크립트가 실행되지 않도록 HTML Encoding 적용

CSP, Content Security Policy 콘텐츠 보안 정책 실행

  • Header에 페이지에서 실행이 되는 컨텐츠(리소스)의 출처를 제한하는 메커니즘
  • 스크립트를 제한시키는 방법