Go言語によるWebサーバー作成入門 ーXSSー

1 min読了の目安(約1500字TECH技術記事

(作成2020.10.22)

XSS クロスサイトスクリプティング

脆弱性を利用した攻撃の一つで、悪意のあるスクリプトを投稿する攻撃です。掲示板を設置する場合に、スクリプトを投稿できるようにしておけばいろいろ機能性に富んだものになりますが、一方で、攻撃の対象にもなってしまいます。ここでは、どのようなことが起こるかが体験できるコードを書いておきたいと思います。

text/templateの場合

main.go
package main

import (
	"log"
	"os"
	"text/template"
)

type Page struct {
	Title   string
	Heading string
	Input   string
}

var tpl *template.Template

func init() {
	tpl = template.Must(template.ParseFiles("tpl.gohtml"))
}

func main() {

	nf, err := os.Create("index.html")
	if err != nil {
		log.Fatalln(err)
	}
	defer nf.Close()

	home := Page{
		Title:   "Nothing Escaped",
		Heading: "text/templateだとスクリプトが実行されてしまう。",
		Input:   `<script>alert("おきのどくですが\nぼうけんのしょ1は\nきえてしまいました。");</script>`,
	}

	err = tpl.ExecuteTemplate(nf, "tpl.gohtml", home)
	if err != nil {
		log.Fatalln(err)
	}
}
tpl.gohtml
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ .Title }}</title>
</head>
    <body>
        <h1>{{ .Heading}}</h1>
        {{ .Input }}
    </body>
</html>
$ go run main.go

作成されたindex.htmlを開くと、、、

ぎゃーーーーーーっ!!

html/templateの場合

こうあるのを、

main.go抜粋
import (
	"log"
	"os"
	"text/template"
)

こう変えます。

main.go抜粋
import (
	"html/template"
	"log"
	"os"
)

そして実行してindex.htmlを開くと

エスケープされてスクリプトの実行を回避しました。
import文のところは自動的に作成されることもあり、うっかりtext/templateが適用された状態になってしまいがちですが、htmlを作成する際には気をつけましょう。