서론
Go 언어는 encoding/json 패키지로 외부 종속성 없이 JSON 인코딩을 쉽게 처리할 수 있다. 대부분의 경우 Marshal 메소드로 특별한 문제를 느끼지 못하고 사용하지만 JSON 인코딩을 수행할 때 <, >, & 같은 HTML 관련 문자는 기본적으로 각각 \u003c, \u003e, \u0026으로 변환되어 출력된다. 이는 Marshal 메소드 문서를 보면 JSON이 HTML <script> 태그 내부에 안전하게 삽입될 수 있도록 이스케이프하고 Encoder를 사용해서 비활성화할 수 있다고 나와있다. 이 글에서는 json.Marshal에서 HTML 이스케이프를 제어하는 방법에 대해서 정리해본다.
JSON 근데 이제 HTML 이스케이프를 곁드린
package main
import (
"encoding/json"
"fmt"
)
func main() {
data, _ := json.Marshal(map[string]string{
"<music>": "<Rock & Roll 🎸>",
})
fmt.Println(string(data))
}
출력 결과
{"\u003cmusic\u003e":"\u003cRock \u0026 Roll 🎸\u003e"}
키와 값 모두 이스케이프가 적용됐다. 사람이 보기에는 조금 난해하다.
Encoder를 사용해서 HTML 이스케이프 비활성화
package main
import (
"bytes"
"encoding/json"
"fmt"
)
func main() {
buf := &bytes.Buffer{}
encoder := json.NewEncoder(buf)
encoder.SetEscapeHTML(false)
_ = encoder.Encode(map[string]string{
"<music>": "<Rock & Roll 🎸>",
})
fmt.Println(buf.String())
}
출력 결과
{"<music>":"<Rock & Roll 🎸>"}
Encoder를 사용하면 확실히 출력 결과는 깔끔하게 보이지만 코드는 지저분해진 것 같은 느낌이 든다. 그러나 HTML 이스케이프는 XSS 공격을 방지하는 데 중요한 역할을 한다. 따라서 이스케이프되지 않은 데이터를 HTML로 삽입할 경우 악성 스크립트가 실행될 위험이 있다는 것을 고려하고 사용해야 한다.
'Language > Go' 카테고리의 다른 글
[golang] sync.WaitGroup으로 고루틴 작업 기다리기 (0) | 2024.11.09 |
---|---|
[golang] html/template 패키지로 동적 페이지 처리하기 (3) | 2024.11.07 |
[golang] reflect 패키지를 사용한 외부 패키지의 private 필드 접근하기 (0) | 2024.10.30 |
[golang] cgo에서 Go와 C 언어 간의 버퍼 전달 (2) | 2024.10.29 |
[golang] 동일한 문자열 메모리 공유 (1) | 2024.10.28 |