XSS, CSRF, SQL Injection이란

워니·2025년 1월 12일
0

컴퓨터네트워크

목록 보기
10/15

XSS(Cross Site Scripting)

크로스 사이트 스크립팅 이란 웹사이트에서 사용자 입력을 제대로 검증하지 않을 때 발생하는 취약점을 악용하는 공격이다

  • 공격자가 악성 스크립트를 삽입해 사용자의 브라우저에서 실행되도록 한다
  • 일반적으로 JavaScript를 사용하여 공격이 이루어지며, 이를 통해 민감한 데이터를 훔치거나, 사용자를 악성 사이트로 리디렉션하는 등의 행동을 할 수 있다

XSS 공격 유형

1. Stored XSS

  • 악성 스크립트가 서버에 영구적으로 저장됨
  • 게시판, 댓글, 프로필 등 사용자가 입력한 내용이 다른 사용장게 표시될 때 공격이 발생

  • - 공격자가 댓글로 <script>alert('Hacked!')</script>를 작성.
    - 서버가 이 입력값을 필터링 없이 저장.
    - 다른 사용자가 해당 페이지를 열 때 스크립트가 실행.

2. Reflected XSS

  • 악성 스크립트가 즉시 반영됨
  • 보통 URL 쿼리 파라미터나 폼 데이터에서 전달된 입력값이 검증 없이 페이지에 출력될 때 발생
  • 예:
    - 공격자가 http://example.com?q=<script>alert('Hacked!')</script> 링크를 피해자에게 보냄.
    - 피해자가 링크를 클릭하면 스크립트가 실행.

3. DOM-based XSS

  • 클라이언트 사이드(JavaScript)에서 발생하는 XSS입니다.
  • 서버가 아닌 브라우저에서 DOM 조작을 통해 악성 스크립트가 실행됩니다.
  • 예:
    - JavaScript 코드가 URL의 파라미터 값을 DOM에 삽입할 때 발생.
    - <script>document.body.innerHTML = location.search</script>

XSS 방어 방법

1. 입력 데이터 검증 및 필터링

  • 사용자 입력값을 검증(Validation)하고, 허용된 값만 통과시키도록 제한한다
  • HTML 태그나 JavaScript 코드를 차단하기 위해 특수 문자 인코딩을 적용한다
    예: <&lt;, >&gt;, "&quot;, '&#x27;

2. 출력 시 컨텍스트에 따라 이스케이프

  • HTML 컨텍스트: HTML 엔티티 인코딩 적용
  • JavaScript 컨텍스트: 값에 이스케이프 처리 (예: JSON.stringify())
  • CSS 컨텍스트: CSS 이스케이프 처리
  • URL 컨텍스트: encodeURIComponent() 사용

3. HTTP 응답 헤더 설정

  • 브라우저에서 XSS 공격을 방지하기 위해 HTTP 헤더를 설정
    - Content-Security-Policy (CSP): 스크립트 소스 제한
    Content-Security-Policy: default-src 'self'; script-src 'self'
    - X-XSS-Protection: 브라우저의 기본 XSS 방지 기능 활성화
    X-XSS-Protection: 1; mode=block

4. 사용자 입력에 대해 WAF(Web Application Firewall) 적용

  • WAF를 사용하면 XSS 공격 패턴을 사전에 탐지하고 차단할 수 있다

5. 라이브러리 및 프레임워크의 보안 기능 활용

  • 안전한 출력 처리를 제공하는 템플릿 엔진이나 라이브러리를 사용
    - Java: Jsoup
    - Python: bleach
    - JavaScript: DOMPurify

6. 신뢰할 수 없는 스크립트 포함 금지

  • 외부 스크립트나 사용자 제공 콘텐츠를 직접 실행하지 않도록 해야 한다
  • 예: <script>eval(userInput)</script> 사용 금지

CSRF(Cross-Site Request Forgecy)

공격자가 사용자의 인증된 상태를 악용해 원하지 않은 작업을 수행하도록 유도하는 공격

  • 사용자가 로그인한 상태라는 점을 악용
  • 공격자가 의도한 요청이 사용자의 브라우저를 통해 서버로 전달
  • 예를 들어, 사용자가 은행에 로그인한 상태에서 공격자의 링크를 클릭하면, 공격자의 계좌로 송금 요청이 이루어질 수 있음

CSRF 공격 시나리오

  1. 사용자가 은행 사이트(example.com)에 로그인하여 세션이 유지된 상태
  2. 공격자가 악성 스크립트를 포함된 페이지를 제작하고 사용자를 유도
    <img src="http://example.com/transfer?amount=1000&to=attacker_account" />
  3. 사용자가 공격자의 페이지를 방문하면, 브라우저는 은행 사이트에 인증된 상태로 요청을 보냄
  4. 서버는 요청이 정상적인 사용자 요청으로 간주하고 처리
  5. 결과적으로, 공격자가 의도한 작업(예: 송금)이 수행됨

CSRF 방어 방법

1. CSRF 토큰 사용

  • 서버는 사용자가 요청할 때마다 CSRF토큰을 발급하여 폼이나 URL에 포함
  • 토큰은 서버에서만 검증 가능하며, 클라이언트는 이를 예측할 수 없음
  • 서버는 요청 시 제공된 CSRF토큰이 유효한지 확인
<form action="/transfer" method="POST">
  <input type="hidden" name="csrfToken" value="randomGeneratedToken123">
  <input type="text" name="amount">
  <button type="submit">Send</button>
</form>

2. SameSite 속성 설정된 쿠키 사용

  • SameSite속성을 strict또는 Lax로 설정하여 브라우저가 타 사이트에서 쿠키를 전송하지 못하도록 함
Set-Cookie: sessionId=abc123; SameSite=Strict; HttpOnly; Secure;

3. Referer Header 검증

  • 서버는 요청의 Referer 헤더를 확인해 요청이 적합한 출처에서 발생했는지 확인.
  • 단, 일부 브라우저나 프록시가 Referer를 제거할 수 있으므로 보조적인 방법으로 사용.

4. POST 요청만 허용

  • 민감한 작업(예: 데이터 변경, 결제 등)은 반드시 POST 요청으로 처리.
  • GET 요청을 통해 데이터 변경을 허용하지 않도록 설정.

5. 쿠키의 HttpOnly 및 Secure 속성

  • HttpOnly: JavaScript로 쿠키를 읽을 수 없도록 설정.
  • Secure: HTTPS 연결에서만 쿠키 전송.
Set-Cookie: sessionId=abc123; HttpOnly; Secure;

6. CORS 정책 설정

  • 서버는 CORS(Cross-Origin Resource Sharing) 정책을 설정하여 허용된 출처에서만 요청을 처리.
  • 예: 특정 도메인만 허용.
Access-Control-Allow-Origin: https://trusted-site.com

7. 사용자 입력 확인

  • 요청 파라미터를 엄격히 검증하여 의도하지 않은 값이 처리되지 않도록 함.
  • 예: 금액 범위, 계좌 번호 형식 등을 검증.

CSRF 방어 전략의 조합

  • 모든 민감한 요청에 CSRF 토큰을 포함.
  • 쿠키에 HttpOnly, Secure, SameSite 속성을 설정.
  • CORS 정책 및 Referer 검증을 병행.
  • GET 요청을 통해 데이터 변경 금지.

SQL Injection

SQL Injection은 공격자가 애플리케이션의 입력 필드나 URL 쿼리 파라미터에 악의적인 SQL 코드를 삽입해 데이터베이스를 조작하거나 민감한 정보를 탈취하는 공격 기법이다

  • SQL 쿼리가 외부 입력에 의해 조작되어 실행됨
  • 공격자는 인증 우회, 데이터 조작, 테이블 삭제 등 다양한 악성 행위를 수행할 수 있음

SQL Injection 공격 시나리오

1. 취약한 코드 예시

String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
  • 사용자가 입력한 값이 바로 SQL 쿼리에 삽입됨

2. 공격자가 입력하는 값

  • username 필드에 'admin' OR '1'='1'을 입력
  • 쿼리는 다음과 같이 변환됨
SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '';

3. 결과

  • 공격자는 관리자 계정으로 로그인하거나, 다른 데이터베이스 정보를 조회/조작 가능

SQL Injection 방어 방법

1. Prepared Statement사용

  • Prepared Statement는 SQL쿼리와 데이터를 분리해 삽입 공격을 방지
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();

2. ORM(Object-Relational Mapping) 사용

  • JPA, Hibernate 등 ORM 프레임워크를 사용하면 SQL쿼리를 직접 작성하지 않아도 되므로 안정성이 향상

3. 입력값 검증 및 제한

  • 사용자 입력값의 길이, 형식, 허용 문자 등을 엄격히 검증
  • 예: 이메일 형식, 숫자 범위, 특수문자 제한 등
  • 서버에서 입력 검증
if (!username.matches("[a-zA-Z0-9_]+")) {
    throw new IllegalArgumentException("Invalid username");
}

4. 데이터베이스 권한 최소화

  • 데이터베이스 계정은 최소 권한 원칙에 따라 설정
  • 예: SELECT만 필요한 경우 INSERT, UPDATE, DELETE 권한 제거

5. Stored Procedure 사용

  • 미리 정의된 SQL쿼리만을 사용하도록 제한
  • 예: MySql에서 Stored Procedure 작성
CREATE PROCEDURE GetUser(IN username VARCHAR(50), IN password VARCHAR(50))
BEGIN
    SELECT * FROM users WHERE username = username AND password = password;
END;

6. SQL 쿼리 로그 모니터링

  • 비정상적인 쿼리 실행 시 경고하거나 차단.
  • SQL Injection 시도 패턴 탐지:
    - ' OR '1'='1
    - -- (주석 처리)
    - ; DROP TABLE

7. 웹 방화벽(WAF) 사용

  • SQL Injection 패턴을 탐지하고 요청을 차단.
  • WAF 솔루션: ModSecurity, AWS WAF 등.

8. 에러 메시지 숨김

  • 공격자가 SQL 쿼리 구조를 유추하지 못하도록 자세한 에러 메시지를 사용자에게 노출하지 않음.
try {
    // SQL Query 실행
} catch (SQLException e) {
    logger.error("Database error occurred", e); // 내부 로그만 남김
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An unexpected error occurred.");
}

SQL Injection 방어 전략 요약

방법설명
Prepared Statement쿼리와 데이터를 분리해 SQL 구문을 안전하게 실행.
입력값 검증입력값의 허용 범위를 명확히 정의하고 검증.
ORM 사용JPA와 같은 ORM을 통해 쿼리 작성 최소화.
DB 권한 최소화DB 계정의 권한을 최소화하여 피해를 줄임.
Stored Procedure사전 정의된 쿼리만 실행하도록 제한.
에러 메시지 숨김SQL 에러 메시지를 사용자에게 노출하지 않음.
WAF 사용SQL Injection 패턴 탐지 및 차단.
profile
매일, 조금씩 나아가는중

0개의 댓글