[go] 템플릿 보안 측면

Go 언어에서 템플릿은 웹 애플리케이션에서 동적 콘텐츠를 생성하는데 자주 사용됩니다. 이러한 템플릿에서 보안 측면을 고려해야 합니다. 이 블로그에서는 Go 언어에서 템플릿을 안전하게 사용하는 방법에 대해 알아보겠습니다.

1. 사용자 입력 처리

템플릿은 종종 사용자 입력을 받아 렌더링된 콘텐츠에 포함될 수 있습니다. 이 경우 입력을 템플릿에 전달하기 전에 사용자 입력을 정규화하고 이스케이프해야 합니다. 이렇게 함으로써 크로스 사이트 스크립팅(XSS) 공격을 방지할 수 있습니다.

예를 들어, html/template 패키지의 html 함수를 사용하여 사용자 입력을 이스케이프할 수 있습니다.

import (
	"html/template"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	userInput := r.FormValue("input")
	tmpl, err := template.New("tmpl").Parse("{{.}}")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	tmpl.Execute(w, template.HTML(userInput))
}

2. 블랙리스트 대신 화이트리스트 사용

템플릿에서 사용할 수 있는 함수와 기능을 제한함으로써 템플릿 보안을 강화할 수 있습니다. 이를 위해 화이트리스트 방식으로 허용할 함수와 기능을 명시적으로 지정해야 합니다. 가능한 한 블랙리스트 방식을 피하여 모든 함수와 기능을 허용한 후 명시적으로 금지하는 것보다 화이트리스트 방식을 선호해야 합니다.

import (
	"html/template"
	"os"
)

func main() {
	tmpl := template.New("example")
	tmpl = tmpl.Funcs(template.FuncMap{
		"safeFunc": func(s string) template.HTML {
			return template.HTML(s)
		},
	})
	tmpl, err := tmpl.ParseFiles("template.tmpl")
	if err != nil {
		panic(err)
	}
	tmpl.Execute(os.Stdout, data)
}

3. 템플릿 캐싱

템플릿을 캐싱함으로써 웹 애플리케이션의 성능을 향상시킬 수 있습니다. 그러나 템플릿 캐싱은 보안 취약점을 유발할 수 있으므로 조심해야 합니다. 템플릿을 로드할 때 악의적인 스크립트가 삽입되지 않도록 확인해야 합니다.

import "html/template"

var cachedTemplates = template.Must(template.ParseGlob("templates/*.tmpl"))

func main() {
	// ...
}

이러한 방법들을 통해 Go 언어에서 템플릿 보안을 강화할 수 있습니다.

더 많은 정보는 Go 언어 템플릿 보안 문서를 참고하세요.


이 블로그에서는 Go 언어에서 템플릿을 안전하게 사용하는 방법에 대해 살펴보았습니다. 사용자 입력 처리, 화이트리스트 방식, 그리고 템플릿 캐싱을 통해 보안 측면을 고려하면서 템플릿을 사용할 수 있습니다.