Manual:編集トークン
編集トークン (edit token、別名 csrf トークン) は、ページを変更する操作を実行する際にクライアントと MediaWiki サーバーの間で交わされるランダムな文字列です。 外部サイトに訪問している間に騙されてウィキ上の変更をリクエストしていないか (つまり、クロスサイト リクエスト フォージェリ) を確認することよりも、利用者がウィキ上で本当に変更しようとしているかを確認するために使用されます。
なぜ必要なのか
編集トークンは変更を実行するときに追加のセキュリティ基準として使用されます。 利用者識別が Cookie のみで確認される場合、外部サイトは訪問者にウィキの変更を実行させる以下のようなリンクを利用できます。
https://en.wikipedia.org/w/index.php?title=Image:Abcd.jpg&action=delete&oldimage=324242234
そのようなリンクを許可すると管理者が知らずに画像の削除をリクエストすることにつながりかねません。 管理者がまだログインしている場合、サーバーは Cookie を確認してリクエストを許可します。
このため、変更を実行する操作は HTTP パラメーター、編集トークンとして渡されるデータの追加ピースが要求されます。 編集トークンは利用者ーが一つの変更を要求することができるものからウェブページに埋め込まれます; これは編集フォーム (「変更を公開」を押すことでページを変更できる場所) を含みますが、画像説明ページ (管理者が画像の古いバージョンの削除をリクエストできる場所)、投稿者の履歴 (管理者がロールバックできる場所) なども含みます。
利用者が実際に行われる変更をリクエストする際 (ボタンを押す、またはリンクをたどる)、編集トークンはサーバーに送信されます。 外部サイトは利用者の編集トークンへのアクセス権限がないため、このことによって利用者が外部サイトではなくサイトから直接の変更をサーバーにリクエストしたことを証明します。
How it works
編集トークンは PHP セッションに保存されるランダムな文字列です。PHP セッションは連想配列でサーバーに保存され Cookie によってセッションを越えて維持されます (例えば英語版ウィキペディアでは enwiki_session
)。
編集トークンはとりわけ PHP セッションの wsEditToken
要素に含まれます。
編集トークンは利用者が変更をリクエストできる場所からウェブページに埋め込みされます。
ページが生成される際、編集トークンは PHP セッションの wsEditToken
要素が存在する場合、その要素から取得されます; さもなければランダムな文字列が生成されその要素に保存されます。
ウェブページに実際に埋め込まれるものは wsEditToken
要素自身ではありません。
むしろ、この要素は salt に連結されます。salt は特定の操作とページに依存する文字列です; 結果の文字列は MD5 のハッシュです; これはウェブページに埋め込まれるものです。
利用者が実際に操作をリクエストする際、この文字列は HTTP パラメーター経由でサーバーに送信されます。
サーバーはこのパラメーターの対応を確認できます: PHP セッションからそれを生成するために使用される手続きを繰り返し結果がパラメーターと等しいかを検査します。
有効性
サーバーから返る編集トークンは複数回にわたり異なる編集処理に用いることができます。 トークンには特定の有効期間があります。 期限切れのトークンで API を呼び出すと、トークン無効エラーを返します。 この事例では、サーバーから有効な新しい編集トークンを入手してから、もう一度、処理を実行してください。
ソースコード
編集トークンは主にUser.phpソースファイルで取り扱われます。とりわけ次のようなメソッドがあります。
- getEditToken(salt)
- returns the MD5 hash of the concatenation of the
wpEditToken
element of the PHP session with the salt. If such an element does not exist in the PHP session, a random one is generated. リポジトリ内の getEditToken 関数を参照してください。 - matchEditToken(token, salt)
- 最初の引数 token が、後者の引数 salt に対する有効な編集トークンであるか検査します。これは生成の処理を繰り返して最初の引数と結果を比較することで行われます。具体的には、この関数は
editToken(salt)
を呼び出し最初の引数と結果を比較します。
Salt
既定の salt は空の文字列です; 多くの操作はこの既定値を使用します。結果として、サーバーからページに最初の操作を行うために受け取る編集トークン文字列を試用すると、その他のページで別の処理を実行できます。 しかしながら、編集トークンの保存先は PHP セッションであるため、これを利用する条件とは、サーバーがセッションを保持していること、クライアントが対応するセッション トークン Cookie (例えば、enwiki_session Cookie) を保存している場合に限定されます。
salt を用いて生成した編集トークン用ハッシュは、同一の salt をサーバーとクライアントの両方で利用した場合のみ、その他の処理を行うことができます。 そこでその特定の salt の埋め込み先が、最初の処理を行ったページに限定された場合、前述の編集トークン ハッシュを利用しても別のページで処理を行うことは不可能です。
- 既定の空のsaltを使わない処理:
- rollback
- saltとは編集を差し戻す予定のユーザー名に連結された (名前空間の接頭辞を含む) 記事名です;
- delete the old version of an image : the salt is the
oldimage
parameter (when deleting all version this parameter is the empty string, which is also the default salt); - Special:UserRights
- salt は変更される利用者のプロパティの利用者名です;
- Special:Watchlist/clear
- salt は 'clearwatchlist' の文字列です
編集トークン接尾辞
Edit tokens end with +\
to prevent broken proxies from editing: proxies that cannot correctly handle the backslash or plus sign typically also mess up the wiki markup code.
クライアント側のハッシュを取得
1.18 以降は Ajax を介して編集トークンを取得する必要がなくなりました。mw.user.tokens.get( 'csrfToken' )
として提供されます。
ただしご利用のモジュールの ResourceLoader 依存として、mediawiki.user を定義しておく必要がある点にご注意ください。
mw.api.postWithToken()
ヘルパー方式の採用が推奨され、Web ページの読み込み後にトークンが期限切れになった場合に自動的に再試行を行います。