Go言語のWebアプリにおけるセキュリティベストプラクティス集
生徒
「先生、GoでWebアプリを作っているんですが、セキュリティが心配です。どう守ればいいですか?」
先生
「Webアプリには色々な攻撃のリスクがあります。Goで安全に開発するための基本ルールや設定を守ることが大切です。」
生徒
「具体的にはどんなことを意識すればいいんですか?」
先生
「では、重要なセキュリティのポイントを一つずつ見ていきましょう!」
1. 入力値の検証とサニタイズ
ユーザーから送られてくるデータは信用してはいけません。例えばフォームやURLパラメータに悪意あるスクリプトを入れられると、XSS(クロスサイトスクリプティング)攻撃の原因になります。Goではhtml/templateを使うと、自動でHTMLをエスケープしてくれるので安全です。
import "html/template"
tmpl := template.Must(template.New("index").Parse("<p>{{.}}</p>"))
tmpl.Execute(w, userInput) // userInputを自動でエスケープ
2. SQLインジェクション対策
データベースにユーザー入力を直接入れると、SQLインジェクション攻撃のリスクがあります。Goではdatabase/sqlパッケージのPrepareやQueryでパラメータ化することで防げます。
stmt, _ := db.Prepare("SELECT * FROM users WHERE id = ?")
row := stmt.QueryRow(userInput)
3. CORS設定と安全なAPI設計
異なるドメインからのリクエスト制御はCORSで行います。必要なオリジンのみ許可することで、不正アクセスを防げます。github.com/rs/corsなどのライブラリを活用すると簡単です。
c := cors.New(cors.Options{
AllowedOrigins: []string{"https://example.com"},
AllowedMethods: []string{"GET","POST"},
})
handler := c.Handler(mux)
4. HTTPSの利用
通信を暗号化するHTTPSは必須です。Goではhttp.ListenAndServeTLSで簡単にHTTPSサーバを立ち上げられます。通信内容を暗号化することで、中間者攻撃などを防げます。
http.ListenAndServeTLS(":443", "cert.pem", "key.pem", handler)
5. セッション管理とCookieの安全設定
ユーザー認証にはセッションやCookieを使いますが、安全に扱う必要があります。HttpOnlyやSecureフラグを使うことで、JavaScriptからのアクセスや非HTTPS通信を防ぎます。
http.SetCookie(w, &http.Cookie{
Name: "session_id",
Value: sessionID,
HttpOnly: true,
Secure: true,
})
6. エラーメッセージの扱い
エラーメッセージには内部情報を含めないようにします。例えばデータベースの構造やサーバ設定をユーザーに表示すると攻撃に利用される可能性があります。エラーはログに記録し、ユーザーには一般的なメッセージを返すようにしましょう。
7. パッケージの最新化と依存管理
GoのWebアプリで使うライブラリは常に最新に保つことが重要です。脆弱性が修正されたバージョンを利用し、go.modで依存関係を管理することでセキュリティリスクを減らせます。
8. HTTPヘッダによる追加の防御
ClickjackingやXSS対策として、X-Frame-OptionsやContent-Security-Policyヘッダを設定することが有効です。Goではw.Header().Setで簡単に設定できます。
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("Content-Security-Policy", "default-src 'self'")
9. ログと監視
セキュリティ対策だけでなく、不正アクセスや異常動作を早期に検知するために、アクセスログやエラーログの記録を行います。Goでは標準パッケージlogを活用すると簡単に実装できます。
10. 定期的なセキュリティレビュー
コードの定期的なレビューや脆弱性スキャンを行うことも重要です。自分だけでなくチームで確認することで、ミスや抜けを減らし、安全なWebアプリを保つことができます。