보안 설정 오류
고친 사람 github-actions[bot]
보안 설정 오류는 코드가 아니라 설정 때문에 시스템이 뚫리는 일입니다. 설치할 때 정해져 있던 관리자 비밀번호를 바꾸지 않은 채 운영하는 것이 대표적입니다. 코드에는 흠이 없어도 공격자가 들어올 길이 열립니다. 코드 리뷰와 테스트는 코드를 보기 때문에 이 길을 잘 못 봅니다.
쉽고 빠른 이해
보안 설정 오류는 설정 값 하나가 공격자에게 문을 열어 주는 일입니다. 운영 서버에 디버그 모드가 켜져 있어 오류가 날 때마다 서버 내부 사정이 화면에 뜨는 경우가 그렇습니다.
따로 이름을 붙여 부르는 까닭은 코드만 봐서는 안 보이기 때문입니다. 설정은 코드 밖에 있어서 코드 리뷰도 테스트도 대개 지나칩니다. 이름이 있어야 점검할 항목이 됩니다.
어떻게 생기나:
- 프로그램을 깔면 쓰기 편한 쪽으로 정해진 설정이 딸려 옵니다
- 개발할 때 편하려고 켠 기능이 운영 서버까지 따라갑니다
- 아무도 그 값을 안전한 쪽으로 바꾸지 않은 채 서버가 인터넷에 열립니다
무엇이 나빠지나:
공격자는 코드의 약점을 찾을 필요 없이 설정이 열어 둔 길로 들어옵니다. 설정은 서버마다 흩어져 있어서 한 군데를 고쳐도 다른 곳에 같은 값이 남기 쉽습니다.
상세
이 절은 네 덩이로 나아갑니다. 무엇인가, 왜 생기나, 무엇과 다른가, 어떻게 막나입니다. 첫 덩이에서는 흔히 보이는 모양을 표로 모읍니다. 그다음 오류 두 개가 이어져 서버가 뚫리는 이야기를 하나 따라갑니다.
코드 밖에서 생기는 취약점
현관 도어락을 새로 달고 공장에서 정해 둔 비밀번호를 바꾸지 않았다고 해 봅시다. 도어락 자체에는 아무 흠이 없습니다. 그 비밀번호가 설명서에 적혀 있다는 것만 알면 누구든 문을 엽니다.
프로그램의 동작은 코드로만 정해지지 않습니다. 같은 코드도 설정 파일이나 환경 변수에 적힌 값에 따라 다르게 돕니다. 어느 포트를 열지, 오류를 얼마나 자세히 보일지, 누구에게 무엇을 허락할지가 설정 값으로 정해집니다.
공격자가 파고들 수 있는 약한 대목을 취약점이라 합니다. 그 약한 대목이 코드가 아니라 설정 값에서 생긴 것이 보안 설정 오류입니다. 코드를 한 줄도 안 바꿔도 설정 하나로 생깁니다. 없앨 때도 설정 하나를 바꾸면 됩니다.
보안 설정 오류는 웹 애플리케이션이 자주 뚫리는 방식 열 가지를 모은 목록 OWASP Top 10 에 한 항목으로 올라 있습니다. 그만큼 흔하게 터진다는 뜻입니다. 이 목록을 펴내는 단체가 OWASP(Open Worldwide Application Security Project)입니다.
흔히 보이는 모양
보안 설정 오류는 한 가지 실수가 아니라 여러 실수를 묶어 부르는 이름입니다. 자주 보이는 모양과 그 값이 공격자에게 무엇을 내주는지를 표로 봅니다.
| 모양 | 무엇을 내주나 |
|---|---|
| 기본 계정을 지우거나 바꾸지 않음 | 설명서에 적힌 아이디와 비밀번호로 관리자 로그인이 됩니다 |
| 운영 서버에 디버그 모드를 켜 둠 | 개발자용 진단 화면과 내부 정보가 누구에게나 보입니다 |
| 오류 응답에 스택 트레이스를 담음 | 오류가 난 함수의 호출 경로가 드러나 쓰는 라이브러리와 파일 경로가 보입니다 |
| 웹 서버의 디렉터리 목록을 켜 둠 | 폴더 주소로 들어가면 그 안의 파일 이름이 전부 나열됩니다 |
| 쓰지 않는 기능과 포트를 열어 둠 | 관리 화면이나 예제 페이지처럼 아무도 지키지 않는 입구가 생깁니다 |
| 클라우드 저장소를 공개로 둠 | 주소만 알면 누구든 안에 든 파일을 내려받습니다 |
| 보안 헤더를 빠뜨림 | 보안 헤더는 브라우저에게 이 페이지를 어떻게 다룰지 알리는 응답 헤더입니다. 이게 빠지면 남의 사이트가 내 페이지를 제 화면 안에 끼워 넣어도 브라우저가 막지 않습니다 |
표의 모양들은 세 갈래로 나뉩니다. 기본 계정, 열린 포트, 공개 저장소는 들어올 길을 엽니다. 디버그 모드, 스택 트레이스, 디렉터리 목록은 내부 사정을 알려 줍니다. 보안 헤더를 빠뜨리면 브라우저가 해 줄 수 있던 보호가 꺼집니다.
오류 두 개가 이어지는 경로
내부 사정을 알려 주는 오류는 그 자체로는 뚫리지 않아도 다음 공격을 쉽게 만듭니다. 길을 여는 오류와 이어지면 어떻게 되는지 서버 하나로 따라갑니다.
이 서버에는 설정 오류가 둘 있습니다. 하나는 디버그 모드가 켜져 있다는 것입니다. 다른 하나는 관리 화면의 계정이 설치 때 값 그대로라는 것입니다.
공격자는 먼저 일부러 틀린 값을 보내 서버가 오류를 내게 합니다. 디버그 모드가 켜져 있으니 서버는 스택 트레이스를 담은 오류 화면을 돌려줍니다. 그 화면에서 서버가 어떤 프레임워크를 쓰는지 드러납니다.
프레임워크를 알면 그 프레임워크가 관리 화면을 어느 주소에 여는지도 알 수 있습니다. 공격자는 그 주소로 가서 설명서에 적힌 기본 계정으로 로그인합니다. 이제 공격자는 관리자입니다.
sequenceDiagram
participant 공격자
participant 서버
Note over 서버: 디버그 모드 켜짐 · 기본 계정 그대로
공격자->>서버: 일부러 틀린 값을 보낸다
서버-->>공격자: 스택 트레이스가 담긴 오류 화면
Note over 공격자: 어떤 프레임워크인지 알아낸다
공격자->>서버: 관리 화면 주소로 간다
공격자->>서버: 기본 계정으로 로그인한다
서버-->>공격자: 관리자 권한
이 경로에서 코드의 버그는 하나도 쓰이지 않았습니다. 두 설정 가운데 어느 하나만 안전한 값이었어도 경로가 끊깁니다. 오류 화면이 간단했다면 공격자는 프레임워크를 몰랐을 겁니다. 계정을 바꿨다면 로그인이 안 됐을 겁니다.
생기는 조건
보안 설정 오류는 세 조건이 겹칠 때 생깁니다. 첫째, 보안에 영향을 주는 설정이 있습니다. 둘째, 그 값이 안전하지 않은 쪽에 놓여 있습니다. 셋째, 그 설정이 걸린 기능에 공격자가 닿을 수 있습니다.
세 번째 조건 때문에 같은 값도 어디 있느냐에 따라 오류가 되기도 하고 안 되기도 합니다. 디버그 모드가 켜진 서버가 개발자 노트북 안에서만 돌면 문제가 되지 않습니다. 같은 서버가 인터넷에 열리는 순간 보안 설정 오류가 됩니다.
외부에서 닿을 수 있는 입구 전체를 공격 표면이라 부릅니다. 쓰지 않는 기능을 켜 두는 설정 오류는 이 공격 표면을 넓힙니다. 지키는 사람이 없는 입구가 늘어나는 셈입니다.
기본값이 위험한 까닭
설정을 아무도 건드리지 않았을 때 쓰이는 값을 기본값이라 합니다. 프로그램을 만든 쪽은 기본값을 처음 쓰는 사람이 바로 돌려 볼 수 있게 고릅니다. 그래서 기본값은 편한 쪽으로 기울기 쉽습니다.
편한 값과 안전한 값은 자주 반대 방향입니다. 관리자 계정이 미리 만들어져 있으면 설치가 빨리 끝납니다. 오류가 자세히 보이면 개발자가 원인을 빨리 찾습니다. 같은 성질이 운영 서버에서는 공격자에게 도움이 됩니다.
개발할 때 켠 설정이 운영으로 넘어가는 경우도 많습니다. 개발 서버의 설정 파일을 복사해 운영 서버를 만들면 개발용 값이 함께 따라갑니다. 아래는 그렇게 만들어진 운영 서버의 설정 파일을 지어낸 예입니다.
debug: true # 개발 때 켠 값
admin_password: admin # 설치 때 값
error_detail: full # 오류를 자세히 보임
세 줄 모두 개발 서버에서는 문제가 없던 값입니다. 운영 서버가 인터넷에 열리는 순간 셋 다 공격자가 쓸 수 있는 길이 됩니다. 문법 오류가 없고 서버도 잘 돕니다. 그래서 아무 경보도 울리지 않습니다.
자꾸 생기는 까닭
요청 하나가 서버에 닿기까지 여러 계층을 지납니다. 계층마다 설정이 따로 있습니다. 그래서 어느 한 계층만 안전한 값이 아니어도 오류가 됩니다.
flowchart TD
C["클라우드 네트워크 · 어느 포트를 밖에 여나"] --> O["운영체제 · 어떤 서비스가 켜져 있나"]
O --> W["웹 서버 · 디렉터리 목록을 보여 주나"]
W --> F["프레임워크 · 오류를 얼마나 자세히 보이나"]
F --> A["애플리케이션 · 관리자 계정이 설치 때 값인가"]
위에서 아래로 요청이 지나는 순서입니다. 클라우드의 네트워크 설정, 운영체제, 웹 서버, 프레임워크, 애플리케이션이 저마다 설정을 가집니다. 이 다섯을 한 사람이 모두 챙기는 팀은 드뭅니다.
서버가 여러 대면 일이 더 커집니다. 한 서버에 접속해 급히 바꾼 값은 그 서버에만 남습니다. 다른 서버에도, 팀이 적어 두고 관리하는 설정 파일에도 반영되지 않습니다.
이렇게 서버의 실제 설정이 설정 파일에 적어 둔 값과 조금씩 벌어지는 일을 구성 드리프트라 합니다. 같아야 할 서버들끼리도 설정이 서로 달라집니다. 점검 때 잠깐 열어 둔 포트가 닫히지 않고 남으면 드리프트가 곧 보안 설정 오류가 됩니다.
이웃한 취약점과 가르는 선
보안 설정 오류는 무엇을 고쳐야 없어지느냐로 이웃과 갈립니다. 아래 표는 자주 헷갈리는 셋을 나란히 놓습니다.
| 이름 | 약한 곳 | 고치는 곳 |
|---|---|---|
| 보안 설정 오류 | 설정 값 | 설정 파일, 관리 화면 |
| SQL 인젝션 | 입력을 SQL(Structured Query Language, 데이터베이스 질의 언어) 명령에 섞는 코드 | 코드 |
| 취약한 의존성 | 알려진 흠이 있는 옛 판 라이브러리 | 라이브러리 판 |
| 안전하지 않은 설계 | 처음부터 빠진 보호 장치 | 설계 |
설정 값만 바꿔서 없어지면 보안 설정 오류입니다. 코드를 고쳐야 하면 코드의 버그입니다. 라이브러리를 올려야 하면 의존성 문제입니다. 보호 장치를 새로 설계해 넣어야 하면 설계의 문제입니다.
막는 방법
막는 방법은 이름과 하는 일만 적습니다. 자세한 것은 각 항목이 다룹니다.
| 방법 | 하는 일 |
|---|---|
| 보안 강화 | 설치 직후 기본 계정을 지우고 쓰지 않는 기능과 포트를 끕니다 |
| 최소 권한 | 계정과 프로그램에 꼭 필요한 권한만 줍니다 |
| 환경별 설정 분리 | 개발용 설정과 운영용 설정을 따로 두어 개발용 값이 넘어가지 않게 합니다 |
| 코드형 인프라 | 설정을 파일로 적어 검토를 거친 뒤에만 서버에 적용합니다 |
| 설정 점검 | 운영 중인 서버의 설정을 안전한 값 목록과 견주어 다른 곳을 알립니다 |
앞의 셋은 오류가 처음 들어오지 않게 합니다. 뒤의 둘은 설정을 한곳에 모아 정기적으로 확인합니다. 이미 들어온 오류가 오래 남지 않게 합니다.
관련 항목
보안 설정 오류가 속하는 상위 분류
OWASP Top 10 · OWASP · 취약점 · 보안 엔지니어링 · 웹 보안 · 애플리케이션 보안
보안 설정 오류의 흔한 모양
기본 계정 · 기본값 · 디버그 모드 · 스택 트레이스 · 디렉터리 목록 · 보안 헤더 · 공개 버킷 · CORS · 정보 노출
보안 설정 오류가 생기는 설정 대상
설정 파일 · 환경 변수 · 클라우드 · 운영체제 · 웹 서버 · 프레임워크 · 방화벽 · 객체 스토리지
보안 설정 오류를 막거나 찾는 방법
보안 강화 · 최소 권한 · 공격 표면 · 코드형 인프라 · 설정 점검 · CIS 벤치마크 · 심층 방어 · 취약점 스캐너
보안 설정 오류와 원인이 갈리는 취약점
SQL 인젝션 · 교차 사이트 스크립팅 · 취약한 의존성 · 안전하지 않은 설계 · 권한 상승
보안 설정 오류를 낳는 운영 문제
다른 이름: security misconfiguration · 보안 구성 오류 · 잘못된 보안 설정