Same-Origin Policy とは何なのか。

ちょっと凝ったWebアプリケーションを作成していたり、あるいはWebのセキュリティに関わっている人ならば「Same-Origin Policy」(SOP)という言葉を一度は聞いたことがあると思います。日本語では「同一生成元ポリシー」あるいは「同一生成源ポリシー」などと訳されることもありますが、個人的には「オリジン」は固有の概念を表す語なので下手に訳さず「同一オリジンポリシー」と書いておくのが好きです。
さて、この「オリジン」とは何なのかという話ですが、これは「RFC 6454 - The Web Origin Concept」で定められており、端的に言うと「スキーム、ホスト、ポート」の組み合わせをオリジンと定め、それらが同じものは同一のオリジンとして同じ保護範囲のリソースとして取り扱うということです。
例えば、http://example.jp/foohttp://example.jp:80/barはそれぞれ同一のスキーム(http)、ホスト(example.jp)、ポート(80)を持つため、同一のオリジンであると判断されます。一方、https://example.jp/foohttp://example.jp/fooはどちらも同じホストを持ちますが、スキームがそれぞれhttpsとhttpであるため、異なるオリジンのリソースであると判断されます。data:スキームはそれぞれ独立したオリジンを持つものとして取り扱われ、またfile:スキームに関しては実装依存ということになっています。2つのオリジンが同一でない場合、すなわち異なるオリジンを「クロスオリジン」と言います。
RFC6454では、現在のドキュメントのオリジンを正規化して表現する方法も定められており、例えばhttp://example.jp:80/foo/bar/というリソースであればオリジンは正規化するとhttp://example.jpとなります。最近のWebKit系のブラウザでは、表示しているドキュメントのオリジンを示す location.origin というプロパティが実装されています。
オリジンに依存して動作が制約されるものとしては、以下のようなものがあります。

XMLHttpRequest
同一オリジンでは無条件にレスポンスを読むことができますが、クロスオリジンでは許可された場合にしかレスポンスにアクセスすることはできません。
Canvas
Canvasに表示された画像は、同一オリジンであれば画像データにJavaScriptからアクセスすることができますが、クロスオリジンの場合には許可された場合にしかアクセスできません。
Web Storage
データの保存される単位はオリジンに基づきます。クロスオリジンでのデータの読み書きはできません。
X-Frame-Options
SAMEORIGINのような指定をした場合には、オリジンを超えてフレーム内にコンテンツを含めることはできません。

これら以外にもWeb上の様々な挙動について、対象が同一オリジンの場合には制約なしにリソースの読み書きが可能となるのに対し、クロスオリジンの場合には原則としてリソースの読み書きが禁止になることを「同一オリジンポリシー」と言います。
一方、オリジン以外をベースに動作の制約に定めているものとしては以下のようなものがあります。

Cookie
Cookieはpathやdomain指定が可能であり、またデフォルトではhttpとhttpsで共有されます。
HTTP認証
HTTP認証はpath名を元に認証情報を送信するなど、オリジンに基づかない動作となります。
document.domain
JavaScriptでdocument.domainを書き換えることによりホストを超えてinnerHTMLなどの読み書きが可能になります。

XMLHttpRequestCanvasなどのオリジンにより制約を受ける機構において、クロスオリジンでのリソースでアクセスする方法については、Cross-Origin Resource Sharing(CORS)がルールとして定められています。CORSに基づいてリクエスト、レスポンスを発行することにより、XMLHttpRequestCanvasにおいてクロスオリジンでリソースにアクセスすることが可能になります。CORSについては、「HTTP access control | MDN」が日本語でよくまとまっていますので参照するとよいと思います。

まったくの余談になりますが、「クロスサイトスクリプティング」という攻撃手法の名前について「何が『クロスサイト』なのか分からない」という声をよく聞きますが、ここでいう「サイト」は純粋な意味でのサイトではなくオリジンを示しているのであり、クロスサイトスクリプティングはオリジンを超えてスクリプトを注入する攻撃だと考えると、わりとしっくり来るような気がします。