詳細検索

WAF에 의존하지 마세요! 애플리케이션 보안 조치 완전 가이드

아바타
글쓴이 望月

WAF에 의존하지 마세요! 애플리케이션 보안 조치 완전 가이드
日本語에서 번역 • 원문 보기
望月
望月

제가 가장 좋아하는 축구팀인 요코하마 F 마리노스는 현재 최하위에 있고, 저는 매일 경기 결과에 기대하는 컬러크루 시큐리티의 모치즈키입니다.

많은 회사들이 웹 애플리케이션을 보호하기 위해 WAF(웹 애플리케이션 방화벽)를 도입했습니다.
하지만 WAF는 단지 '외부 방어층'일 뿐 보안을 위한 만병통치약은 아닙니다.
이상적인 보안 조치는 애플리케이션 자체를 견고하게 설계하고 구현하는 데 있습니다.

이 글에서는 WAF에 의존하지 않고 애플리케이션 측면에서 구현할 수 있는 효과적인 보안 조치들을 설명하겠습니다. 이러한 조치를 적절히 구현함으로써 "처음부터 안전한 애플리케이션"을 구축할 수 있습니다.

애플리케이션 수준의 보안이 중요한 이유

WAF는 외부 공격을 탐지하고 차단하는 효과적인 방법이지만, 애플리케이션 자체의 보안 조치도 다음과 같은 이유로 필수적입니다:

  1. 다층 방어
    "심층 방어" 개념은 보안에 중요합니다.
    WAF가 침해되더라도 애플리케이션 자체가 견고하면 피해를 최소화할 수 있습니다.
  2. 우회 WAF
    정교한 공격자들은 끊임없이 WAF 탐지를 회피할 방법을 찾고 있습니다.
    애플리케이션 자체가 취약하다면, WAF를 통과할 경우 손상 위험이 증가합니다.
  3. 내부 위협에 대응하기
    WAF는 주로 외부 공격을 위해 설계되었지만, 내부 사용자의 무단 접근에 대응하지 못할 수도 있습니다.
  4. 성과 영향
    WAF 배포는 요청 처리 지연을 초래할 수 있습니다.
    애플리케이션 자체가 매우 안전하다면, WAF 검사 규칙을 최적화할 수 있습니다.

구체적인 애플리케이션 수준의 보안 조치를 살펴보겠습니다.

SQL 주입 대응책

SQL 인젝션은 가장 흔하고 위험한 공격 중 하나입니다.
다음 조치들이 거의 완전히 예방할 수 있습니다:

1. 매개변수화된 쿼리 사용

문자열 연결 방식으로 SQL 쿼리를 조립하는 대신, 자리 표시자를 사용하는 매개변수화된 쿼리를 사용하세요.
이로 인해 입력값이 SQL 코드로 해석되는 것을 방지합니다.

2. ORM 프레임워크 활용

원시 SQL 작성 대신, Hibernate, Eloquent, Django ORM 같은 ORM 프레임워크를 사용하면 SQL 인주입 위험을 크게 줄일 수 있습니다.

3. DB 최소 특권 원칙을 적용한 회계

애플리케이션이 DB에 연결될 때, 계정에 필요한 최소한의 권한만 부여합니다.
예를 들어, 사용자 정보만 표시하는 함수의 경우, SELECT 권한만 가진 계정을 사용하세요.

크로스사이트 스크립팅(XSS) 측정

XSS 공격은 사용자의 브라우저가 악성 스크립트를 실행하게 만드는 공격입니다.
다음과 같은 조치들이 효과적입니다:

1. 적절한 출력 인코딩

사용자 입력을 표시할 때는 반드시 제대로 인코딩하세요.
HTML 맥락에서는 특수 문자(<, >, ", ' 등)를 엔터티로 변환합니다.

2. 콘텐츠 보안 정책(CSP) 구현

CSP 헤더를 설정하면 허용된 소스에서만 스크립트 실행을 허용하고 인라인 스크립트와 eval( 사용)의 사용을 제한할 수 있습니다.

3. HTTP 헤더를 제대로 구성하세요

X-XSS-Protection, X-Content-Type-Options와 같은 보안 헤더를 설정하여 브라우저의 내장 보호를 강화할 수 있습니다.

교차 사이트 요청 위조(CSRF) 조치

CSRF는 사용자가 의도치 않은 요청을 하도록 강요하는 공격입니다.

1. CSRF 토큰 사용

중요 작업(특히 POST 요청)의 경우, 무작위로 생성된 CSRF 토큰을 포함하고 서버 측에서 검증합니다.

2. 동일 사이트 쿠키 설정

쿠키에 "SameSite=Strict" 또는 "SameSite=Lax" 속성을 설정하여 사이트 간 요청에서 쿠키가 전송되는 것을 방지하세요.

3. 리퍼러 헤더 검증

Referer 헤더를 검증하여 중요한 연산의 출처가 사이트 내에 있는지 확인하되(보조 조치로서) 확인하세요.

세션 관리의 적절한 구현

세션 관리 취약점은 계정 탈취를 포함한 심각한 피해를 초래할 수 있습니다.

1. 보안 세션 ID 생성

충분히 길고(최소 128비트) 복잡하고 예측 불가능한 형식으로 세션 ID를 생성하세요.

2. 세션 종료 설정

세션에 적절한 만료일을 설정하고, 오랫동안 유휴 상태인 세션은 자동으로 비활성화하세요.

3. 로그인 상태 변경 시 세션 재생성

로그인, 로그아웃, 권한 변경 같은 중요한 작업 시 세션 ID를 다시 생성하세요.
이로 인해 세션 고정 공격이 발생하지 않습니다.

입력값 검증 및 출력 인코딩

모든 사용자 입력을 신뢰하지 말고, 이를 제대로 검증하고 인코딩하는 것이 기본입니다.

1. 서버 측 입력 검증

모든 사용자 입력은 항상 서버 측과 클라이언트 측에서 검증됩니다. 길이, 형식, 범위와 같은 제약 조건을 기준으로 검증하세요.

2. HTML 컨텍스트 의존 인코딩

출력할 문맥에 맞는 적절한 인코딩(HTML, JAVASCRIPT, CSS, URL 등)을 작성해야 합니다.
하나의 인코딩 방법이 모든 맥락을 커버할 수는 없습니다.

3. 콘텐츠 타입의 헤더 설정

정확한 Content-Type 헤더를 설정하고 X-Content-Type-Options 헤더를 추가하여 MIME 타입 스니핑을 방지합니다.

보안 인증 메커니즘 구현

인증은 공격자들의 주요 표적이므로 특히 신중해야 합니다.

1. 비밀번호의 안전한 해싱

비밀번호는 평문이나 단순 해시가 아니라, bcrypt나 Argon2와 같은 특수 알고리즘을 사용해 해싱되고 솔팅됩니다.

2. 다중 인증(MFA) 구현

비밀번호 이외의 인증 요소(토큰, 생체 인식 등)를 중요 시스템에 추가하면 보안을 크게 향상시킬 수 있습니다.

3. 계정 잠금 정책

임시 계정 잠금과 CAPTCHA 표시 등 지속적인 인증 실패 방지 조치를 도입하여 무차별 대입 공격을 방지하세요.

적절한 오류 처리

잘못된 오류 처리는 애플리케이션에 대한 내부 정보를 위험에 빠뜨릴 수 있습니다.

1. 사용자 오류와 개발자 오류 분리

사용자에게 일반적인 오류 메시지를 표시하고 상세한 오류 정보를 기록합니다.
운영 환경에서 디버그 정보를 표시하는 것을 피하세요.

2. 예외 유형에 따른 적절한 대응

입력 오류, 인증 오류, 내부 오류 등 다양한 유형의 오류에 대해 적절한 HTTP 상태 코드와 메시지를 반환합니다.

보안 설정 및 배포

애플리케이션 구성 및 배포도 보안에 큰 영향을 미칩니다.

1. 민감한 정보의 안전한 관리

API 키, 비밀번호, 연결 문자열과 같은 민감한 정보는 소스 코드에 내장되어 있지 않고, 대신 환경 변수나 전용 기밀성 관리 서비스를 사용합니다.

2. 종속 도서관에 대한 정기 업데이트

모든 의존 라이브러리를 정기적으로 업데이트하고 보안 패치를 적용하세요. 취약점 스캔 도구를 사용해 알려진 취약점을 확인하세요.

3. 제작을 위한 적절한 설정

개발 모드 비활성화, 디버깅 기능 비활성화, 안전한 HTTP 헤더 구성 등 운영 전용 보안 설정.

요약: 애플리케이션 보안을 지속적으로 개선하다

애플리케이션 자체를 견고하게 만들면 WAF에 의존하지 않고도 높은 수준의 보안을 유지할 수 있습니다.
보안 조치는 한 번에 시행되는 것이 아니라 지속적으로 개선됩니다:

  1. 보안 테스트: 정적 분석 도구와 침투 테스트를 정기적으로 실시합니다
  2. 개발자 교육: 보안 코딩에 대한 지속적인 교육
  3. 최신 정보 파악: 보안 정보 수집 및 업데이트
  4. 코드 검토: 보안 관점에서 코드 검토를 습관으로 만드세요

하지만 최근 몇 년간 공격자 방법들이 점점 더 정교해졌고, 어떤 경우에는 위의 조치만으로는 충분하지 않아 업계에서 다층 방어가 주류가 되었습니다.
WAF를 도입함으로써 더 강력한 보안 조치를 구현할 수 있으니, WAF의 도입 및 운영에 대해 듣고 싶으신 회사라면 Colorkrew에 연락해 주시기 바랍니다.

Related Articles