크로스 사이트 스크립팅 (XSS)
Cross-Site Scripting
설명
크로스 사이트 스크립팅(XSS)은 웹 페이지를 생성할 때 사용자 입력을 적절히 이스케이프(escape)하지 않고 그대로 HTML, JavaScript, HTML attribute 등에 넣을 때 발생하는 취약점입니다. 이 규칙은 Go에서 template.HTMLAttr()에 포맷팅된 문자열을 그대로 넘기는 경우를 탐지합니다. template.HTMLAttr()는 내용을 자동으로 이스케이프하지 않기 때문에, 여기에 사용자 입력이 포함되면 공격자가 <img src=x onerror=alert(1)> 같은 스크립트를 속여 넣어 브라우저에서 실행시킬 수 있습니다.
잠재적 영향
스크립트 실행을 통한 공격 (악성 스크립트 실행): 공격자가 피해자 브라우저에서 임의의 JavaScript 코드를 실행할 수 있습니다.
세션/계정 탈취 (세션 하이재킹): 쿠키, 토큰 등을 훔쳐 사용자 계정으로 로그인하거나 권한을 탈취할 수 있습니다.
피싱 및 UI 위·변조 (화면 조작 공격): 페이지 내용을 조작해 가짜 로그인 폼, 결제 화면 등을 띄워 사용자 정보를 훔칠 수 있습니다.
데이터 변조 및 악성 요청 전송 (사용자 권한 남용): 로그인한 사용자의 권한으로 의도치 않은 요청(계정 변경, 결제, 게시글 작성 등)을 서버에 보내게 만들 수 있습니다.
해결 방법
template.HTML/template.HTMLAttr최소 사용: 정말 필요한 경우를 제외하고 사용하지 말고, 기본html/template의 자동 이스케이프 기능에 맡깁니다.사용자 입력 이스케이프: HTML 본문, 속성, JavaScript 등 맥락(context)에 맞게 이스케이프합니다. 가능하면 표준 라이브러리(
html/template)를 사용합니다.직접 문자열 결합 금지: HTML/속성을 문자열 더하기(+)로 만들지 말고, 템플릿에 데이터 바인딩하는 방식으로 렌더링합니다.
검증 및 정규화: HTML attribute에 들어갈 값은 화이트리스트 기반으로 허용(예:
[a-zA-Z0-9_-]만 허용)하고 길이 제한을 둡니다.template.HTMLAttr사용 시 사전 필터링: 정말 써야 한다면, 사용자 입력이 포함되지 않거나, 포함되어도 엄격히 검증·필터링된 값만 넣습니다.
취약한 코드 및 안전한 코드 예시
취약한 코드
안전한 코드
설명:
취약한 코드:
unsafeHandler에서는 사용자 입력color를 직접 문자열 결합으로style="color:..."형태의 HTML attribute로 만들고, 이를template.HTMLAttr로 감싼 뒤 템플릿에 주입합니다.template.HTMLAttr는 내용을 이스케이프하지 않기 때문에, 사용자가red" onclick="alert(1)같은 값을 넣으면 최종 HTML에<p style="color:red" onclick="alert(1)">가 생성되어 브라우저에서 악성 JavaScript가 실행될 수 있습니다. 즉, 사용자 제어 데이터가 검증 없이 HTML attribute context에 들어가 XSS가 발생합니다.안전한 코드:
safeHandler에서는 HTML 전체를 문자열로 직접 조합하지 않고,html/template에 미리 정의한 템플릿을 사용합니다. 사용자 입력color는 정규식으로 검증해 알파벳/숫자/_/-만 허용하고 길이도 제한합니다. 검증에 실패하면 안전한 기본값(black)으로 대체합니다. 이후Color를 평범한 문자열로 템플릿에 바인딩하면,html/template가 context(여기서는 CSS 값)를 고려해 자동으로 이스케이프해 줍니다. 이렇게 해도 깨끗한 값만 들어가도록 화이트리스트 검증을 했기 때문에,template.HTMLAttr를 쓰지 않고도 안전하게 HTML attribute를 구성할 수 있습니다.
참조
Last updated