Q.게시판에 HTML 서식을 허용해야 한다면 어떻게 안전하게 구현하겠습니까?
전부 막을 수 없으니 허용 목록 방식의 검증된 라이브러리로 걸러냅니다. 직접 만들지 않습니다.
| 방법 | 판정 |
|---|
| 위험한 태그를 지우는 차단 목록 | 불가. 우회 방법이 계속 나온다 |
| 허용 태그와 속성만 남기는 검증 라이브러리 | 권장 |
| 마크다운만 허용하고 HTML 은 이스케이프 | 더 안전. 표현력은 줄어든다 |
허용 목록을 쓸 때 놓치기 쉬운 부분입니다.
| 확인할 것 | 내용 |
|---|
| 태그만 보면 안 된다 | onclick 같은 이벤트 속성도 제거해야 한다 |
| 링크의 스킴 | javascript: 와 data: 는 거부한다 |
| 스타일 속성 | CSS 로도 공격이 가능하다 |
| 저장할 때와 출력할 때 | 저장 시 정제하고 출력 시 자리에 맞게 처리한다 |
여기에 CSP 를 함께 걸어 인라인 스크립트 실행을 막으면 한 겹이 더 생깁니다.
흔한 실수: 정규식으로 script 태그만 지우는 것. 대소문자 섞기, 속성 안 실행, SVG 안 스크립트 등으로 뚫립니다.
Q.입력값 검증만으로 XSS를 막기 어려운 이유는 무엇인가요?
위험한지 아닌지는 값이 어디에 쓰이는지에 달려 있기 때문입니다. 입력 시점에는 그것을 모릅니다.
같은 값 javascript:alert(1) 이 어디에 놓이는지에 따라 달라집니다.
| 놓이는 자리 | 결과 |
|---|
| HTML 본문 | 그냥 글자다. 위험하지 않다 |
| 링크의 href | 클릭 시 실행된다. 위험하다 |
그래서 원칙은 원본을 저장하고 출력 시점에 그 자리에 맞게 처리하는 것입니다.
| 값이 놓이는 자리 | 처리 |
|---|
| HTML 본문 | 꺾쇠와 앰퍼샌드 인코딩 |
| HTML 속성 | 인용부호로 감싸고 인코딩 |
| URL 자리 | 허용 스킴만 통과 |
| 스크립트 안 | HTML 에 심지 않고 데이터로 넘긴다 |
입력 검증도 여전히 필요합니다. 길이와 형식을 제한해 공격 표면을 줄이는 역할입니다. 다만 그것만으로는 부족합니다.
흔한 실수: 입력 시점에 이스케이프해 저장하는 것. 그 값이 JSON 이나 로그로 나갈 때 이중 인코딩되어 화면이 깨집니다.
Q.CSP를 도입했는데도 XSS가 발생할 수 있는 경우는?
CSP 는 실행 경로를 제한하는 장치이고, 정책에 구멍이 있으면 통과됩니다.
| 구멍 | 왜 뚫리나 |
|---|
unsafe-inline 허용 | 인라인 스크립트가 실행된다. CSP 의 핵심 효과가 사라진다 |
unsafe-eval 허용 | 문자열을 코드로 실행할 수 있다 |
| 넓은 허용 출처 | 허용한 CDN 에 공격자가 올릴 수 있는 경로가 있으면 통과 |
| JSONP 엔드포인트 | 허용 출처가 임의 콜백을 반환해 준다 |
| 스크립트가 아닌 경로 | 데이터 유출은 이미지나 폼 전송으로도 가능하다 |
그리고 CSP 는 DOM 조작으로 생기는 XSS 를 다 막지 못합니다. 이미 로드된 우리 스크립트가 사용자 입력을 innerHTML 로 넣으면 정책 안에서 벌어집니다.
흔한 실수: CSP 를 도입했으니 이스케이프를 안 해도 된다고 보는 것. CSP 는 마지막 방어선이고, 출력 이스케이프가 1차 방어입니다. 순서를 바꿀 수 없습니다.
Q.저장형 XSS와 반사형 XSS의 대응 우선순위를 어떻게 정하겠습니까?
저장형을 먼저 막습니다. 피해 범위와 지속성이 다릅니다.
| 항목 | 저장형 | 반사형 |
|---|
| 어디에 있나 | DB 에 남는다 | 요청 파라미터에만 있다 |
| 피해 범위 | 그 페이지를 보는 모든 사용자 | 조작된 링크를 누른 사용자 |
| 공격 조건 | 한 번 심으면 계속 | 사용자를 유인해야 한다 |
| 정리 비용 | 이미 저장된 데이터를 찾아 지워야 한다 | 코드만 고치면 끝 |
저장형은 이미 심어진 것을 찾아 지우는 작업이 따라옵니다. 그래서 발견 즉시 유입을 막고, 기존 데이터를 훑어 정리하고, 그 사이 노출된 세션을 무효화할지 판단합니다.
대응 순서
1. 저장 경로를 막는다 (유입 차단)
2. 저장된 데이터를 조사하고 정리한다
3. 출력 이스케이프를 전 경로에 적용한다
4. 반사형 경로를 정리한다
흔한 실수: 코드만 고치고 끝내는 것. 저장형은 데이터에 남아 있어 코드 수정만으로 사라지지 않습니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
보안 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.