Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11219] ファイルの概要

このコミットは、Go言語の標準ライブラリ encoding/json パッケージにおいて、JSON文字列エンコーディングの挙動に関するドキュメントの追加を行っています。具体的には、アングルブラケット(<>)が \u003c\u003e にエスケープされる理由を明記することで、一部のブラウザがJSON出力をHTMLとして誤解釈するのを防ぐためのセキュリティ上の考慮事項を説明しています。

コミット

commit 6e285ebade0aa819186cb6b6657b9de5169749ff
Author: David Symonds <dsymonds@golang.org>
Date:   Wed Jan 18 12:56:24 2012 +1100

    encoding/json: document angle bracket escaping.

    Fixes #2643.

    R=rsc, d_smithson
    CC=golang-dev
    https://golang.org/cl/5543068

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/6e285ebade0aa819186cb6b6657b9de5169749ff

元コミット内容

このコミットの元々の目的は、encoding/json パッケージの encode.go ファイルに、JSON文字列エンコーディングにおけるアングルブラケットのエスケープ処理に関する説明を追加することです。これは、Issue #2643 を修正するためのものであり、ブラウザがJSONレスポンスをHTMLとして誤解釈する可能性を防ぐためのセキュリティ対策としてのエスケープ処理の存在を明確にしています。

変更の背景

この変更の背景には、Webアプリケーションにおけるセキュリティ上の脆弱性、特にクロスサイトスクリプティング(XSS)攻撃への対策があります。

JSONデータがWebブラウザに送信される際、Content-Typeヘッダが application/json であっても、一部の古いブラウザや特定の状況下では、レスポンスの内容をHTMLとして解釈しようとすることがありました。もしJSONデータ内に <script> タグのようなHTML要素が含まれており、それがエスケープされていない場合、ブラウザがこれをHTMLとしてレンダリングし、悪意のあるスクリプトが実行されてしまう可能性があります。

Goの encoding/json パッケージは、このような潜在的なXSS脆弱性を防ぐために、デフォルトでアングルブラケット(<>)をUnicodeエスケープシーケンス(\u003c\u003e)に変換して出力する挙動を持っていました。しかし、この挙動がドキュメントに明記されていなかったため、開発者がその理由や必要性を理解しにくい状況でした。

このコミットは、この重要なセキュリティ対策としてのエスケープ処理の存在とその理由を公式ドキュメントに追記することで、開発者に対して透明性を提供し、なぜこのようなエスケープが行われるのかを明確にすることを目的としています。これにより、開発者が不必要にエスケープを無効化したり、セキュリティ上のリスクを認識せずにJSONを扱うことを防ぎます。

前提知識の解説

JSON (JavaScript Object Notation)

JSONは、人間が読んで理解しやすく、機械が生成・解析しやすいデータ交換フォーマットです。JavaScriptのオブジェクトリテラルをベースにしていますが、言語に依存しないデータ形式として広く利用されています。Web APIのデータ送受信などで頻繁に使用されます。

クロスサイトスクリプティング (XSS: Cross-Site Scripting)

XSSは、Webアプリケーションの脆弱性の一つで、攻撃者が悪意のあるスクリプト(通常はJavaScript)をWebページに注入し、そのスクリプトがユーザーのブラウザで実行されることで発生します。これにより、セッションハイジャック、個人情報の窃取、Webサイトの改ざんなど、様々な被害が生じる可能性があります。

XSS攻撃の一種として、JSONレスポンスがHTMLとして誤解釈されるケースがあります。例えば、サーバーがJSONデータを返す際に、そのデータ内に <script>alert('XSS')</script> のような文字列が含まれており、ブラウザがこれをHTMLとして解釈してしまうと、alert('XSS') が実行されてしまいます。

Unicodeエスケープシーケンス

Unicodeエスケープシーケンスは、特定の文字を \uXXXX の形式で表現する方法です。XXXX はその文字のUnicodeコードポイントを16進数で表したものです。例えば、< はUnicodeコードポイントがU+003Cなので \u003c と表現され、> はU+003Eなので \u003e と表現されます。

JSONでは、文字列内に特定の文字(例: "\、制御文字)が含まれる場合、これらをエスケープする必要があります。アングルブラケットのエスケープは、JSONの仕様上必須ではありませんが、セキュリティ上の理由から多くのJSONエンコーダで実装されています。

Content-Typeヘッダ

HTTPレスポンスヘッダの一つで、レスポンスボディのメディアタイプ(MIMEタイプ)を示します。例えば、JSONデータであれば application/json、HTMLであれば text/html となります。ブラウザはこのヘッダを参考に、レスポンスボディをどのように解釈・レンダリングするかを決定します。しかし、前述の通り、一部のブラウザではContent-Typeヘッダだけでなく、レスポンスボディの内容も見て解釈を試みることがあります。

技術的詳細

Go言語の encoding/json パッケージは、Goのデータ構造をJSON形式にエンコード(Marshal)する機能を提供します。このパッケージの内部では、JSON文字列を生成する際に、特定の文字に対してエスケープ処理が施されます。

このコミットで言及されているアングルブラケットのエスケープは、encoding/json パッケージの HTMLEscape 関数(またはそれに類する内部ロジック)によって行われます。この関数は、JSONエンコーダがHTMLコンテキストで安全に出力されるように、特定の文字(<>& など)をUnicodeエスケープシーケンスに変換します。

具体的には、encoding/json のエンコーダは、文字列をJSON形式で出力する際に、以下の変換を行います。

  • <\u003c
  • >\u003e
  • &\u0026

これらのエスケープは、JSONの仕様自体が要求するものではありませんが、WebブラウザがJSONレスポンスをHTMLとして誤解釈し、XSS攻撃に利用されるリスクを軽減するための「防御的プログラミング」の一環として行われます。これにより、たとえJSONデータが誤ってHTMLとしてレンダリングされても、悪意のあるスクリプトが実行される可能性が低くなります。

このコミットは、この既存の挙動を変更するものではなく、その挙動がなぜ存在するのかという理由をドキュメントとして追加するものです。これにより、パッケージの利用者がこのエスケープ処理の意図を理解し、セキュリティ上のメリットを認識できるようになります。

コアとなるコードの変更箇所

変更は src/pkg/encoding/json/encode.go ファイルのコメント部分に限定されています。

--- a/src/pkg/encoding/json/encode.go
+++ b/src/pkg/encoding/json/encode.go
@@ -39,6 +39,8 @@ import (
 //
 // String values encode as JSON strings, with each invalid UTF-8 sequence
 // replaced by the encoding of the Unicode replacement character U+FFFD.
+// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
+// to keep some browsers from misinterpreting JSON output as HTML.
 //
 // Array and slice values encode as JSON arrays, except that
 // []byte encodes as a base64-encoded string.

追加された行は以下の2行です。

// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
// to keep some browsers from misinterpreting JSON output as HTML.

コアとなるコードの解説

このコミットは、Goの encoding/json パッケージにおける文字列エンコーディングのドキュメントに、アングルブラケットのエスケープに関する説明を追加しています。

追加されたコメントは、encode.go ファイル内の Marshal 関数(または関連するエンコーディングロジック)の動作を説明する既存のコメントブロックの一部として挿入されています。このコメントブロックは、JSON文字列値がどのようにエンコードされるかを記述しており、元々は無効なUTF-8シーケンスがUnicode置換文字(U+FFFD)に置き換えられることについて説明していました。

今回追加された2行は、その説明に続けて、アングルブラケット(<>)がそれぞれ \u003c\u003e にエスケープされること、そしてその目的が「一部のブラウザがJSON出力をHTMLとして誤解釈するのを防ぐため」であることを明確に述べています。

これは、コードの動作自体を変更するものではなく、既存のセキュリティ対策としてのエスケープ処理がなぜ行われているのかという背景と理由を、コードのドキュメントとして明示するものです。これにより、このパッケージを利用する開発者が、JSONエンコーディングの挙動をより深く理解し、潜在的なセキュリティリスクを認識できるようになります。

関連リンク

参考にした情報源リンク