소프트웨어 개발보안 가이드 (제 3장, 분석ㆍ설계단계 SW 보안강화 활동) (3)

SOO·2021년 2월 17일
0

설계보안항목 정의 및 설계시 고려사항

1. 입력데이터 검증 및 표현 항목

1) DBMS 조회 및 결과 검증

취약점 개요

데이터베이스(DB)와 연동된 웹 응용프로그램에서 입력된 데이터에 대한 유효성 검증을 하지 않을 경우, 공격자가 입력 폼 및 URL 입력란에 SQL문을 삽입하여 DB로부터 정보를 열람하거나 조작할 수 있다.

설계 시 고려사항

1) 애플리케이션에서 DB 연결을 수행할 때 최소권한의 계정 사용

  • 침해사고가 발생하더라도 다른 부분에 대해 엑세스 권한을 가지지 않도록 DB연결을 위해 사용되는 계정은 해당 애플리케이션이 사용하는 데이터에 대한 CRUD 권한만 설정

2) 외부 입력값이 삽입되는 SQL 쿼리문 동적 생성하여 실행 금지

  • ORM 프레임워크를 사용하여 안전한 정적 쿼리 구조로 SQL문 수행이 가능하도록 개발환경 설정
    (*ORM(Object Relational Model): 객체 관계 매핑, 가상 객체 데이터베이스 구축 ex.Django)
  • 시큐어 코딩 규칙을 통해 정적 쿼리문(외부 입력값에 의해 쿼리문의 구조가 변경되지 않는)을 사용

3) 외부 입력값을 이용해 SQL 쿼리문을 동적 생성해야 할 경우, 입력값에 대한 검증을 반드시 수행

  • 필터를 이용한 입력값 검증
    외부입력값에서 SQL 삽입이 가능한 문자열을 필터링하여 안전한 값으로 치환하는 Filter 컴포넌트를 생성하여 DB에서 관리하는 데이터를 처리하는 모든 애플리케이션에 일괄 적용
  • 인터셉트를 이용한 입력값 검증
    MVC 프레임워크를 사용하는 경우 Interceptor 컴포넌트를 사용하여 입력값에 대한 검증 작업을 수행한 뒤, 요청을 차단하거나 허용하는 정책을 애플리케이션에 일괄 적용
  • 라이브러리 또는 Validator 컴포넌트를 이용한 입력값 검증
    입력값을 검증하는 Validator 컴포넌트를 공통코드로 생성하고 모든 개발자가 SQL문에 삽입되는 입력값에 대해 검증작업을 해당 컴포넌트에서 수행
  • 활용 가능 라이브러리
    • Java: Hibernate, MyBatis, Apache Software License v2.0, JPA
    • ASP.NET(확장 가능): AnsiSQLi 라이브러리
    • PHP: MeekroDB 라이브러리, HTML Purfier 라이브러리

2) XML 조회 및 결과 검증

취약점 개요

XML 문서를 조회할 경우 입력값 조작을 통해 XQuery나 XPath와 같은 쿼리문의 구조를 임의로 변경하여 허가되지 않은 데이터를 조회하거나 인증절차를 우회할 수 있다.

설계 시 고려사항

1) XML 쿼리에 사용되는 파라미터는 반드시 XML 쿼리를 조작할 수 없도록 필터링 해서 사용하거나, 미리 작성된 쿼리문에 입력값을 자료형에 따라 바인딩하여 사용

  • 공통 검증 컴포넌트를 이용한 입력값 필터링
    외부 입력값에서 XML 삽입 공격이 가능한 문자열들을 필터링하는 Validator 컴포넌트를 개발하여 입력값에 대한 검증 작업이 일괄 적용되도록 설계
  • 필터 컴포넌트를 이용한 입력값 필터링
    Filter 컴포넌트에서 XML 삽입이 실행될 수 있는 입력값(", [, ], /, =, @)을 필터링하도록 작성하여 전체 요청 또는 XML 필터링이 요구되는 요청에 대해 프레임워크에서 일괄 적용하도록 설계
  • 개별 코드에서 입력값 필터링하도록 시큐어코딩 규칙 정의
    각각의 컴포넌트에서 입력값에 대해 XMl 삽입을 발생시킬 수 있는 문자열(", [, ], /, =, @)을 제거 또는 안전하게 치환하여 사용할 수 있도록 시큐어코딩 규칙 정의
  • 안전한 API를 사용하도록 시큐어코딩 규칙 정의
    외부 입력값이 쿼리문의 구조를 바꿀 수 없는 API(예. Java API - XQuery)를 사용하도록 시큐어코딩 규칙 정의

3) 디렉터리 서비스 조회 및 결과 검증

취약점 개요

외부 입력값이 LDAP 조회를 수행하기 위한 필터 생성에 사용되는 경우 필터규칙을 변경할 수 있는 입력값에 대한 검증 작업을 수행하지 않게 되면 공격자가 의도하는 LDAP 조회가 수행될 수 있는 취약점
(*LDAP: Lightweight Directory Access Protocol(경량 디렉터리 엑세스 프로토콜))

설계 시 고려사항

1) LDAP 인증서버를 통해 인증을 구현하는 경우 LDAP 삽입 취약점을 가지지 않도록 필터링

  • LDAP 인증이 포함되는 기능 설계 시 외부 입력값이 LDAP 조회를 위한 검색 필터 생성에 삽입되어 사용되는 경우 필터 규칙으로 인식 가능한 특수문자(=, +, <, >, #, ;, \ 등)들을 제거하고 사용할 수 있도록 시큐어 코딩 규칙 정의

2) 활용 가능한 프레임워크 또는 라이브러리

  • Java, PHP, ASP: LDAP Syntax Filter

4) 시스템 자원 접근 및 명령어 수행 입력값 검증

취약점 개요

  • 경로조작 및 자원삽입
    - 공격자가 입력값 조작을 통해 시스템이 보호하는 자원에 임의로 접근하여 자원의 수정, 삭제, 시스템 정보누출, 시스템 자원 간 충돌로 인한 서비스 장애 등을 유발
    - 경로 조작 및 자원 삽입을 통해 허용되지 않은 권한을 획득하여 설정에 관계된 파일을 변경하거나 실행
  • 입력값을 조작하여 허가되지 않은 명령 실행 (운영체제 명령어 삽입)
    적절한 검증 절차를 거치지 않은 사용자 입력값에 의해 의도하지 않은 시스템 명령어가 실행되어 부적절하게 사용자 권한이 변경되거나 시스템 동작 및 운영에 악영향을 미칠 수 있음

설계 시 고려사항

1) 외부 입력값을 이용해 시스템 자원(IP, PORT번호, 프로세스, 메모리, 파일 등)을 식별하는 경우 허가되지 않은 자원 사용 금지

  • 기능 설계 시 사용해야 하는 리소스 목록을 정의하여 지정된 범위 안에서 리소스를 선택하여 사용하도록 해야 함
  • 리소스 목록은 프로퍼티 파일이나 XML 파일로 정의하여 리소스 정보를 변경하는 경우 프로그램 수정을 최소화 할 수 있도록 관리
  • 경로조작을 일으킬 수 있는 문자(.. / \)를 제거하고 사용하여 지정된 경로 내의 파일만 접근 가능하도록 시큐어코딩 규칙 정의

2) 서버 프로그램 안에서 쉘을 생성하여 명령어를 실행해야 하는 경우 외부 입력값에 의해 악의적인 명령어가 실행되지 않도록 함

  • 서버 프로그램 안에서 쉘을 생성해서 명령어가 실행되는 구조를 가지지 않도록 설계하는 것이 최우선 조건
  • 경우에 따라 꼭 필요한 경우 외부 입력값이 직접적으로 명령어의 일부로 사용되지 않도록 해야 함
    • 이 경우 사용되어야 하는 값들을 목록화하여 목록 내에 있는 값들로만 명령어가 조립되어 실행될 수 있도록 해야 하며, 경우에 따라 변경이 필요한 경우 이로 인해 프로그램이 수정되지 않도록 프로퍼티 파일이나 XML 파일을 사용하여 허용 목록을 작성
    • 외부 입력값은 목록화된 정보를 검색하는 인덱스값을 사용하여 목록화된 정보의 노출을 최소화

5) 웹 서비스 요청 및 결과 검증

취약점 개요

  • 외부 입력값을 검증 없이 응답 페이지 생성에 사용하는 경우 (Reflective XSS)
    웹 페이지에 악의적인 스크립트를 포함시켜 웹페이지를 열람하는 접속자의 권한으로 부적절한 스크립트가 수행되어 정보유출 등의 공격 유발
  • DB에 저장된 값을 검증 없이 응답 페이지 생성에 사용하는 경우 (Stored XSS)
    공격자가 미리 취약한 서버에 악의적인 스크립트가 포함된 정보를 저장해 일반 사용자들이 해당 정보를 조회하는 경우 접속자의 권한으로 부적절한 스크립트가 수행되어 정보 유출 등의 공격을 유발

설계 시 고려사항

1) 사용자로부터 입력받은 값을 동적으로 생성되는 응답페이지에 사용하는 경우 크로스사이트 스크립트(XSS) 필터링을 수행한 뒤 사용

  • 입력값에 대해 필터링 또는 인코딩 정책을 적용하는 공통코드를 작성하여 웹컨테이너, 또는 MVC 프레임워크에 적용

    • 필터를 이용한 입력값 검증
      웹 컴포넌트인 Filter를 사용하여 사용자의 입력값에 대해 XSS 필터나 HTML 인코딩을 적용하여 안전한 값으로 치환한 뒤 사용할 수 있도록 모든 애플리케이션에 일괄 적용

    • 인터셉트를 이용한 입력값 검증
      -VC 프레임워크를 사용하는 경우 Interceptor 컴포넌트를 사용하여 X사용자의 입력값에 SS 공격 패턴의 문자열이 포함되었는지 검사하여 요청을 차단하거나 허용하는 정책을 모든 애플리케이션에 일괄 적용

    • 라이브러리 또는 Validator 컴포넌트를 이용한 입력값 검증
      공통코드로 입력값을 검증하는 Validator 컴포넌트를 작성하여 XSS 공격 패턴의 사용자 입력값을 필터링하도록 설계

2) DB 조회 결과를 동적으로 생성되는 응답페이지에 사용하는 경우 HTML 인코딩 또는 크로스사이트스크립트(XSS) 필터링을 수행한 뒤 사용

  • 각각의 컴포넌트에서 출력값에 대해 XSS 필터 또는 HTML 인코딩을 적용하여 안전한 값만 응답에 사용

    • View 컴포넌트에서 출력값에 대해 HTML 인코딩 적용

    • DB 조회 결과값에 대한 XSS 필터 적용
      DB 에서 읽어오는 데이터도 외부입력값의 범위에 포함시켜 응답페이지에 출력하기 전에 반드시 검증작업을 수행

  • XSS 방어를 위한 라이브러리 및 클래스

    • ASP.NET: MS Anti-XSS, MS AntiXSSEncoder, HTML Sanitizer 라이브러리
    • Java: LUCY XSS Filter, OWASP ESAPI XSS Filter
    • PHP: HTML Purifier 라이브러리

6) 웹 기반 중요기능 수행 요청 유효성 검증

취약점 개요

공격자는 세션 탈취, XSS 등을 통해 자신이 의도한 행위(수정, 삭제, 등록 등)를 사이트가 신뢰하는 인증된 사용자의 권한을 통해 실행되게 할 수 있다. (크로스 사이트 요청 위조)
(*CSRF: 사이트 간 요청 위조)

설계 시 고려사항

1) 시스템으로 전송되는 모든 요청에 대해 정상적인 사용자의 유효한 요청인지 아닌지 여부를 판별

  • CSRF 토큰 사용

    • 세션별로 CSRF 토큰을 생성하여 세션에 저장하고 사용자가 작업 페이지를 요청할 때마다 hidden 값으로 클라이언트에게 토큰을 전달하여 요청의 유효성을 검사하도록 설계
    • Spring이나 Struts와 같은 MVC 프레임워크의 경우 사용자의 요청을 중간에 가로채서 값의 유효성을 검사할 수 있는 Interceptor 컴포넌트를 이용, 파라메터로 전달된 CSRF 토큰값이 세션에 저장된 토큰값과 동일한지를 체크하여 요청이 처리되도록 설계
    • 활용 가능 프레임워크 또는 라이브러리
      • Java: Spring Security, Apache Struts, OWASP CSRFGuard
      • Python: Django
      • PHP: CSRF Protector
  • 사용자와 상호 처리 기능 작용
    CSRF 토큰 방식도 XSS 취약점이 있는 사이트를 통해 공격하면 무력화 될 수 있으므로 CAPTCHA와 같은 사용자와 상호 처리 가능한 기법을 적용하여 위조된 요청이 차단될 수 있도록 설계

  • 재인증 요구
    중요기능의 경우 재인증을 통해 안전하게 실제 요청 여부를 확인하도록 설계

7) HTTP 프로토콜 유효성 검증

취약점 개요

  • HTTP 응답 분할
    공격자가 HTTP 요청에 삽입한 인자값이 HTTP 응답헤더에 포함되어 사용자에게 다시 전달될 때 개행문자(줄 바꿈 문자)를 이용, 첫 번째 응답을 종료시키고 두 번째 응답에 악의적인 코드가 주입되어 XSS 공격 등이 가능해짐
  • 신뢰되지 않은 URL로 자동 접속연결
    사용자의 입력값을 외부사이트의 주소로 사용하여 자동으로 연결하는 서버 프로그램에서, 공격자가 사용자를 피싱(Phishing)사이트 등 위험한 URL로 접속하도록 유도

설계 시 고려사항

1) 외부 입력값을 쿠키 및 HTTP 헤더정보로 사용하는 경우 필터링

  • \r\n문자는 HTTP 응답에서 헤더와 바디를 구분하는 구분자로 사용되기 때문에 HTTp 응답 헤더에 삽입되는 외부입력값은 반드시 \r\n 문자를 제거하여 사용

2) 외부입력값이 페이지 이동(리다이렉트 또는 포워드)을 위한 URL로 사용되어야 하는 경우, 해당 값은 시스템에서 허용된 URL 목록의 선택자로 사용되도록 함

  • 페이지 이동을 허용하는 URL 목록을 소스코드에 하드코딩 하거나, 설정파일(XML, properties)에 저장하여 허용된 URL로만 이동할 수 있도록 설계

8) 허용된 범위 내 메모리 접근

취약점 개요

  • 버퍼오버플로우
    스택(Stack)이나 힙(Heap)에 할당되는 메모리에 문자열 등이 저장될 때 최초 정의된 메모리의 크기를 초과하여 문자열을 저장하는 경우 발생
  • 포맷스트링 삽입
    공격자가 외부입력값에 포맷 문자열을 삽입하여 취약한 프로세스를 공격하거나 메모리 내용을 읽고 쓸 경우, 취약한 프로세스의 권한을 취득하여 임의의 코드 실행 가능

설계 시 고려사항

1) C나 C++과 같이 메모리를 프로그래머가 관리하는 플랫폼 사용 시 메모리 버퍼의 경계값을 넘어서지 않도록 경계설정 또는 검사를 반드시 수행

2)개발 시 메모리 버퍼오버플로우를 발생시킬 수 있는 취약한 API를 사용하지 않도록 통제

9) 보안기능 동작에 사용되는 입력값 검증

취약점 개요

  • 보안기능 결정에 사용되는 부적절한 입력값
    서버가 사용자가 전달하는 쿠키, 환경변수, 히든필드를 충분히 검증하지 않을 경우 공격자가 이에 포함된 사용자 권한, 사용자 역할을 나타내는 변수를 조작한 뒤 서버로 요청하여 상승된 권한으로 작업을 수행
  • 정수형 오버플로우
    정수형 변수의 오버플로우는 정수값이 증가하며 값의 최대치를 넘어서며 실제 저장되는 값이 의도치 않게 아주 작은 수가 되거나 음수가 되며 발생. 특히 반복문 제어, 메모리 할당, 메모리 복사 등을 위한 조건으로 사용하는 외부입력값이 오버플로우 되는 경우 보안상 문제 유발 가능
  • Null Pointer 역참조
    일반적으로 '그 객체가 널(Null)이 될 수 없다'는 가정을 위반했을 때 발생. 공격자가 의도적으로 널 포인터 역참조를 발생시키는 경우, 그 결과 발생하는 예외 상황을 이용하여 추후의 공격을 계획하는 데 사용 될 수 있음

설계 시 고려사항

1) 서버에서 정보 관리

  • 상태정보나 인증, 인가, 권한에 관련된 중요 정보는 서버측의 세션이나 DB에 저장하여 사용

2) 외부 입력값이 보안기능을 수행하는 함수의 인자로 사용될 경우 검증작업 수행 뒤 제한적 사용

  • 외부의 입력값에 의존할 필요가 없는 구조로 설계
  • 검증작업을 수행한 뒤 제한적으로 사용
  • 사용 전 Null 여부 체크 뒤 사용

3) 중요상태정보나 인증, 권한결정에 사용되는 정보는 쿠키로 전송되지 않아야 하며, 불가피한 경우 암호화를 해야 함

10) 업로드ㆍ다운로드 파일 검증

취약점 개요

  • 위험한 형식 파일 업로드
    서버 측에서 실행될 수 있는 스크립트 파일(asp, jsp, php 파일 등)을 업로드 가능하고 이 파일을 공격자가 웹을 통해 직접 실행이 가능한 경우 시스템 내부명령어를 실행하거나 외부와 연결하여 시스템을 제어할 수 있게 됨
  • 경로조작 문자를 이용한 파일 다운로드 취약점
    외부 입력값에 대해 경로조작에 사용될 수 있는 문자를 필터링하지 않으면, 예상 밖의 접근제한 영역에 대한 경로 문자열 구성이 가능해져 시스템 정보누출, 서비스 장애 등을 유발
  • 무결성 검사 없는 코드 다운로드
    원격으로부터 소스 코드 또는 실행 파일을 무결성 검사 없이 다운로드 받고, 이를 실행할 경우 호스트 서버의 변조, DNS 스푸핑(Spoofing)또는 전성 시의 코드 변조 등의 방법을 이용하여 공격자가 악의적인 코드를 실행할 수 있게 됨
    (*DNS 스푸핑: 변질된 도메인 네임시스템 데이터가 DNS 리졸버(DNS resolver)의 캐시에 유입되어 네임 서버가 유효하지 않은 결과(예: IP주소)를 반환, 이를 통해 공격 우회 가능)
    (*DNS(Domain name System) Resolver: 호스트의 도메인 이름을 호스트의 네트워크 주소로 바꾸거나, 그 반대의 변환을 수행할 수 있도록 하기 위해 개발됨)

설계 시 고려사항

1) 업로드 되어 저장되는 파일의 타입, 크기, 개수, 실행권한을 제한

  • 업로드 파일의 크기 제한
  • 파일의 타입 제한
  • 업로드되어 저장되는 파일은 실행권한 제거
    파일이 read 퍼미션을 가지고 있기만 해도 서버에서 해당 파일을 읽어 실행이 가능. 서버 설정을 통해 업로드 경로의 파일이 실행되지 않도록 설정

2) 업로드 되어 저장되는 파일은 외부에서 식별되지 않아야 함

  • 업로드 파일의 저장 경로는 외부에서 직접 접근이 불가능하도록 설계
    URL 조작을 통해 접근이 불가능하면 업로드 파일에 대한 통제가 가능
  • 업로드 파일명 랜덤 생성
    공격자가 파일을 찾을 수 없도록 파일명을 랜덤 생성. 이 경우 업로드 파일명과 실제로 저장된 파일명이 매핑될 수 있도록 DB테이블 설계 시 업로드 파일명과 저장된 파일명이 함께 저장되도록 설계

3) 파일 다운로드 요청 시 요청 파일명에 대한 검증작업 수행

  • 파일 다운로드를 위해 요청되는 파일명에 경로를 조작하는 문자가 포함되어 있는지 점검
    파일명에 경로 조작이 가능한 문자(../ ..\)를 제거하도록 필터링
  • 허가된 사용자의 허가된 안전한 파일에 대한 다운로드 요청인지 확인
    • 요청 시 허용된 사용자와 허용된 파일인지를 확인하는 기능이 구현되도록 파일 다운로드 컴포넌트를 설계
    • 파일을 다운로드하는 사용자의 안전을 위해 파일에 대한 악성코드 또는 바이러스 검사를 수행한 뒤 파일이 다운로드 되도록 기능 설계
  • 사용자 요청에 의해 서버에 존재하는 파일이 참조되는 경우 화이트리스트 정책으로 접근 통제
    허용 파일에 대한 목록을 작성하고 목록의 범위 내에서만 제한적으로 접근 또는 다운로드하도록 설계

4) 다운로드 받은 소스코드나 실행파일에 대해 무결성 검사 실행

  • 해당 파일과 해당 파일의 체크섬값(해쉬값)을 같이 다운로드 받아 파일에 대한 무결성 검사를 수행
    (*체크섬: 네트워크를 통해서 전송된 데이터의 값이 변경되었는지(무결성)를 검사하는 값. 이를 활용해 네트워크를 통해 수신된 데이터에 오류가 없는지 여부를 확인)
  • 활용 가능한 프레임워크
    • JAVA: Spring
    • PHP: CodeIgniter
    • ASP.NET: .NET Framework

[출처] 행정자치부 SW 개발보안 가이드 https://www.mois.go.kr/frt/bbs/type001/commonSelectBoardArticle.do?bbsId=BBSMSTR_000000000015&nttId=57473

0개의 댓글