../

任意のページごとの閲覧・編集制限 -- Ynak

目次

できること

任意のページに対する閲覧・編集・検索でアクセス制御を行う。

アクセス制御対象となるページは、以下のいずれかで決定できる。

  • ページ名にある正規表現にマッチした場合
  • ページ内容にある正規表現にマッチした場合

(具体例)

  • ××ページは全員が閲覧できるが、内容を編集できるのは○○だけ。
  • △△ページは□□だけが閲覧・編集できる。
  • ○△ページは○○と□□が閲覧できるが、編集は○○だけ。

PukiWiki-official の関連ページ

設定ファイルの仕様

pukiwiki.ini.phpに以下の項目を設定することで、 既存・新規作成ページに対するアクセス制御を行うことができる。

  • ユーザ定義
  • 認証方式種別
  • 閲覧認証フラグ
  • 閲覧認証対象パターン定義
  • 編集認証フラグ
  • 編集認証対象パターン定義
  • 検索認証フラグ

ユーザ定義

アクセス制御で使用するユーザとパスワードを設定する。

// ユーザ定義
$auth_users = array(
'foo' => 'foo_passwd',
'bar' => 'bar_passwd',
'hoge' => 'hoge_passwd',
);

1.4.6 以降のパスワード保存書式については、BugTrack/709 を参照

認証方式種別

××認証対象パターン定義で定義したパターンがどこにあったら、 マッチしたことにするのか、を設定する。

※今回からページ内容によるアクセス制御に対応した。

// 認証方式種別
// pagename : ページ名
// contents : ページ内容
$auth_method_type = "contents";

閲覧認証

閲覧認証フラグ

閲覧認証によるアクセス制御を行うかどうか設定する。 不要な場合はオフにすればパターンマッチングを行わないので、性能劣化を防止できる。

// 閲覧認証フラグ
// 0:不要
// 1:必要
$read_auth = 1;

閲覧認証対象パターン定義

閲覧認証をかけるページを決定するための正規表現パターンを設定する。 マッチしたページに閲覧認証をかける。 カンマ区切りで複数ユーザを書いても良い。

// 閲覧認証対象パターン定義
$read_auth_pages = array(
'/ひきこもるほげ/' => 'hoge',
'/(ネタバレ|ねたばれ)/' => 'foo,bar,hoge',
);

編集認証

編集認証フラグ

編集認証によるアクセス制御を行うかどうか設定する。 不要な場合はオフにすればパターンマッチングを行わないので、性能劣化を防止できる。

// 編集認証フラグ
// 0:不要
// 1:必要
$edit_auth = 1;

編集認証対象パターン定義

編集認証をかけるページを決定するための正規表現パターンを設定する。 マッチしたページに編集認証をかける。 カンマ区切りで複数ユーザを書いても良い。

// 編集認証対象パターン定義
$edit_auth_pages = array(
'/Barの公開日記/' => 'bar',
'/ひきこもるほげ/' => 'hoge',
'/(ネタバレ|ねたばれ)/' => 'foo',
);

検索認証フラグ

検索時にも閲覧認証と同等のアクセス制御が必要かどうか設定する。 どちらの場合も、ページ名は公開情報なので検索対象となる。

// 検索認証フラグ
// 0: 閲覧が許可されていないページ内容も検索対象とする
// 1: 検索時のログインユーザに許可されたページのみ検索対象とする
$search_auth = 0;

上記設定例の解説

上の例では

  • 「Barの公開日記」は、誰でも閲覧できて、barだけが編集できる。
  • 「ひきこもるほげ」ページは、hogeだけが閲覧・編集できる。
  • 「映画紹介~ネタバレ注意」ページは、foo, bar, hogeの三人だけが閲覧できて、かつ、編集はfooだけが可能。 のような設定となる。

かなり強引にUNIXっぽく表現すると、こうなる。

アクセス権   ユーザID   グループ   ページ名
-rw----r--   bar        なし       Barの公開日記
-rw-------   hoge       なし       HogeOnly
-rw-r-----   foo        hoges      映画紹介~ネタバレ注意

※グループhogesには、barとhogeが所属するとする。


改造

本体の改造

PukiWiki1.4rc2(20030529版)をベースにする場合は、以下を改造する。 *1

pukiwiki.ini.php

設定ファイルの仕様で紹介した項目を追加して、適切な設定を行う。 すでに存在している$edit_auth, $edit_auth_usersの設定は削除するか、 コメントアウトすること。

プラグインの改造

アクセス制御する仕組みは用意したが、 実際にページにアクセスするのはすべてプラグインである。

よって、プラグインで以下の関数による事前チェックを行うように改造する必要がある。

アクセス制御用の関数仕様

  • check_readable($page, $auth_flag=true, $exit_flag=true)
    • 閲覧することができるかチェックする。
    • 今のところread_authと全く同じ。内部でread_authのみを呼び出している。
  • check_editable($page, $auth_flag=true, $exit_flag=true)
    • 編集することができるかチェックする。
    • edit_auth+凍結などのチェックをする場合。
  • read_auth($page, $auth_flag=true, $exit_flag=true)
    • 閲覧権限があるかチェックする。
  • edit_auth($page, $auth_flag=true, $exit_flag=true)
    • 編集権限があるかチェックする。


引数説明
$pageページ名文字列
$auth_flagtrue: 現在のログイン状態で認証NGであれば、BASIC認証発動(デフォルト)
false:現在のログイン状態で判断するだけ
$exit_flagtrue: 認証NGの場合、check_xxxable関数側でNG画面に遷移する(デフォルト)
false:認証NGの場合でも、戻り値falseで戻ってくるだけ


戻り値true: 認証OK
false:認証NG
  • get_source, file関数を使用している全てのプラグインで、 以下の関数による事前チェックを行うように改造しなければ、 そこがセキュリティホールになるので注意!!
  • 使わないプラグインはpukiwiki/plugin/disableディレクトリを作って そこに入れておくなどして、無効化すると良い。
  • check_xxxxable系とxxx_auth系の使い分けは、特に問題がなければ、総合的な 観点で読めるか書けるかを判断しているcheck_xxxx系の方を利用する方がよいと思う。
  • 第2、第3引数のデフォルト値は既存プラグインとの互換性のために用意している。 今後プラグインを実装する場合は明示的に指定した方がよいと思う。

要改造プラグイン一覧

この改造に伴って一緒に改造する必要があるプラグインの一覧を以下に示す。 Ynakの環境で単にgrep -lE '(get_source|file)' pukiwiki/plugin/*.phpした結果+read.inc.phpなので漏れがあるかもしれない。

このうち少なくともedit, read, edit, backup, diffは絶対に改造する必要がある。

※改造したものからリンク先に改造方法を書く、ということでよろしければご協力お願いします。

推奨運用方式

Ynakのところで運用している方式と、その説明ページの内容をコピーしておく。

./推奨運用方式

注意事項

  • 閲覧認証をかけたページは、編集認証も必須。
    • でないと、「編集」リンクから内容が読めてしまったり、挙動が怪しくなったりする。*2
    • 編集可能ユーザは、閲覧可能ユーザのサブセットとなるように設定すること。
  • edit_auth_pagesなどのvalue部分と、BASIC認証のユーザ名の比較をpreg_matchで行っているので、あるユーザIDのサブセットとなるようなユーザIDがあるとややこしくなる。
    • 例えば、'hogefoobar'というユーザIDがあって、このユーザだけが編集できるようなページを以下のように設定する状況を考える。
      $edit_auth_pages = array(
       '/Secret/' => 'hogefoobar',
      );
    • ここでもし、'hoge'、'foo'、'bar'というユーザIDが存在していれば、そのいずれかのユーザIDでBASIC認証を突破すれば、このSecretページにアクセスできてしまう。
    • とりあえず、pukiwiki.ini.phpにユーザID設定をする人が気を付ければ良いので、気にしていませんが、良い回避法があれば修正してください。
  • 通常の設定ではwikiディレクトリ配下のファイルは直接URL指定でアクセス可能であるため、 ApacheのBasic認証などを利用して、直接アクセスを防止しておかないといけない。
    • たとえば、下記のような.htaccessを配置すると良い。
      AuthUserFile /usr/local/apache/htdocs/basic/.htpasswd
      AuthGroupFile /dev/null
      AuthName "PukiWikiData"
      AuthType Basic
      require valid-user
    • 詳しくはApacheなどのドキュメントを参照のこと。

関連

 

コメント

  • できるだけ1.4の設計思想(?)を優先して、きれいにまとめてみたつもりです。 -- Ynak 2003-05-20 (火) 23:28:16
  • pcommentもセキュリティホールになりますね。改造しないと。 -- Ynak 2003-05-22 (木) 00:09:00
  • あと、メイン機能系では添付ファイルのアクセス制限に未対応ですが、これをやるのはかなりの大工事になりそうですね。ページごとにサブディレクトリを作って、とかやればいいのかな? -- Ynak 2003-05-22 (木) 00:10:39
  • ページ名による制御対象のページ指定に対応したので、一新してみました。しかしアレですね、ページ名の階層が深くなると、#recentの出力が鬱陶しくなるという弊害があるんですね。皆様すみません。 -- Ynak 2003-06-06 (金) 01:43:32
  • すばらしいですね。是非本家に取り入れて欲しい機能です。 -- puchi? 2003-06-06 (金) 13:21:27
  • ありがとうございます。BugTrack/370で要望を出してみたところ、シグネチャ変更はまずいとのことなので(そりゃそうですね)、現在のCVS版と互換性を実現してみました。 -- Ynak 2003-06-07 (土) 00:15:48
  • 私の方での利用形態では一通り試して特に問題は見つかりませんでした。edit_authを独自に使用されているプラグインと連携してどうなるかですが、どのプラグインでedit_authを使用されているかわからなかったので確認できていません。 -- Ynak 2003-06-07 (土) 00:30:11
  • ソース差分をチェックしただけで検証をしていないのですが、sourceプラグインも参照権限のチェックが必要ではありませんか? -- にぶんのに 2003-07-06 (日) 22:21:30
  • まだ、使いはじめたばかりでわからないこといっぱいなんですが、passwordをmd5にするにはどうしたらいいんでしょう? -- merlin 2003-07-15 (火) 16:19:54
  • md5というプラグインが1.4で追加されているのでそれを使ってみて下さい。使い方はマニュアル/プラグインに書いてありますので。 -- にぶんのに 2003-07-15 (火) 23:54:08
  • ユーザ定義のところにmd5にしたパスワードを書きたいのですが、認証時にエンコードしてくれるか?ということなんですが ... -- merlin 2003-07-16 (水) 01:58:03
  • 以下のようにすればいいのではないかと。 -- ぱんだ 2003-07-16 (水) 10:16:27
    • pukiwiki.ini.php
       /////////////////////////////////////////////////
       // ユーザ定義
       $auth_users = array(
       -'foo' => 'foo_passwd',
       -'bar' => 'bar_passwd',
       -'hoge' => 'hoge_passwd',
       +// ユーザ名 => パスワード(md5 hash)
       +// pukiwiki.php?md5=pass のようにURLに入力し
       +// MD5ハッシュにしてから記入してください。
       +'foo' => 'f122914144e12fa7d7b7b14cc223f671',
       +'bar' => 'f53ae779077e987718cc285b14dfbe86',
       +'hoge' => '0c165e4475e0726a1f4a5dc55647d992',
       );
    • auth.php
       	// ユーザリストに含まれるいずれかのユーザと認証されればOK
       	if (!isset($_SERVER['PHP_AUTH_USER'])
       		or !in_array($_SERVER['PHP_AUTH_USER'],$user_list)
       		or !array_key_exists($_SERVER['PHP_AUTH_USER'],$auth_users)
      -		or $auth_users[$_SERVER['PHP_AUTH_USER']] != $_SERVER['PHP_AUTH_PW'])
      +		or $auth_users[$_SERVER['PHP_AUTH_USER']] != md5($_SERVER['PHP_AUTH_PW']))
      	{
  • この方が安全(pukiwiki.ini.phpを盗まれたとしても、ある程度の時間は稼げる?)でしょうね。 -- ぱんだ 2003-07-16 (水) 10:16:27
  • ありがとうございます。どうもパスワード直打ちが気持ちわるかったものですから -- merlin 2003-07-16 (水) 10:39:53
    • 'hoge' => md5("hoge_passwd"), ってのもいけそうなので こっちのがいいかな?
    • pukiwiki.ini.php
       /////////////////////////////////////////////////
       // ユーザ定義
       $auth_users = array(
       -'foo' => 'foo_passwd',
       -'bar' => 'bar_passwd',
       -'hoge' => 'hoge_passwd',
       +// ユーザ名 => パスワード(md5 hash)
       +// pukiwiki.php?md5=pass のようにURLに入力し
       +// MD5ハッシュにしてから記入してください。
       +// 面倒ならば以下のようにどうぞ
       +// ユーザ名 => md5(パスワード)
       +'foo' => 'f122914144e12fa7d7b7b14cc223f671',
       +'bar' => 'f53ae779077e987718cc285b14dfbe86',
       +'hoge' => md5("hoge_passwd"),
       );
  • はじめまして
    閲覧認証を設定したいのですが、ユーザー定義で定義したユーザー名・パスワードで接続しようとしてもできません。どうしてでしょう・・・
    「Windows 2000 Professional」に「pukiwiki_1.4.2」ではできるのは確認できてるのですが
    現在は「Windows Xp HomeEdition」に「pukiwiki_1.4.2」を使用させてもらっています。設定の問題でしょうか、環境的な問題でしょうか? -- ひがけん? 2004-01-10 (土) 00:02:22
  • このページを参考に、既に使っているDBのセッション認証を付加しました。閲覧制限されている場合、list.inc.phpやrecent.inc.phpも改変しました。でないと隠す意味が。。。 -- taketan? 2004-02-28 (土) 13:41:24
    • 閲覧制限されているページをlist.inc.phpやrecent.inc.phpで表示しないようにすると弊害があります。list.inc.phpやrecent.inc.phpで表示したくないページは$non_listで設定すべき。pukiwiki:続・質問箱/36参照。 -- reimy 2004-02-28 (土) 15:30:01
  • 上記の方法でうまくいきましたが、雛形から見ることが出来てしまいます・・・何か良い対処法はありませんでしょうか? -- どん? 2007-07-23 (月) 17:36:23
    • 関連リンク を少し足してみました。雛形に関するリンクもあります。 2007-07-24 (火) 19:22:40
      • 元の著者が誰かがわからなくなるような修正がありましたので、ちょっと戻しました -- henoheno 2007-07-26 (木) 10:47:14
  • lib/pukiwiki.php の次の部分もチェックしたほうがいいのでは?
     if (isset($retvars['body']) && $retvars['body'] != '') {
     	$body = & $retvars['body'];
     } else {
     	if ($base == '' || ! is_page($base)) {
     		$base  = & $defaultpage;
     		$title = htmlspecialchars(strip_bracket($base));
     		$page  = make_search($base);
     	}
    
     	$vars['cmd']  = 'read';
     	$vars['page'] = & $base;
    
    -	$body  = convert_html(get_source($base));
    +	if (check_readable($base, true, false)) {
    +		$body  = convert_html(get_source($base));
    +	} else {
    +		global $title_cannot;
    +		$body  = str_replace('$1', htmlspecialchars(strip_bracket($page)), $title_cannot);
    +	}
     }
    例えば、コメントプラグインでメッセージが空だった場合に、array('msg'=>'', 'body'=>'') と返してくるので、ノーチェックでconvert_html しています。他には、ページが存在しなかった場合は$defaultpage を読み込むようになっていますが、この場合も$defaultpage に制限がかかっているかをチェックしていません。 -- 2008-03-29 (土) 13:06:51
  • 現在
    '/^☆.*$/'	=> 'tokubetu',        (イ)
    のようにして、☆で始まるページは「tokubetu」ユーザにだけ閲覧させています。これに加え、後から「ippan」というユーザーも管理を始めました。
    '/[^(FrontPage)]/'=> 'ippan,tokubetu',  (ロ)
    という行も追加しました。つまり、フロントページは誰でも見られる。それ以外のページは、「ippan」「tokubetu」ユーザーが見られる。☆で始まるページは「tokubetu」ユーザーのみ。という運用を行いたいのですが、「ippan」ユーザーで☆で始まるページも閲覧出来てしまいます。(ロ)の行の記載では、たしかに☆で始まるページも含まれるのは理解しましたが、解決方法が分かりません。どのようにすれば良いのでしょうか。-- 2008-07-04 (金) 20:01:31
    • 自己解決しました
      '/^☆.*$/'	=> 'tokubetu',
      '/^(?!^(FrontPage|^☆.*$)$).*$/' => 'ippan,tokubetu',
      が正解でした。 -- 2008-07-08 (火) 15:45:20

*1 長いので別ページで。
*2 UNIXでも、rw-(閲覧認証&編集認証の同時設定)はOKだけど、 -w-(編集認証のみ)はいろいろと問題が発生するのと似てる。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-01-31 (日) 18:01:24
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u7. HTML convert time: 0.755 sec.

OSDN