Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

XOOPS legacy 2.1xで、ユーザーモジュールの新規登録が出来なかった件

XOOPSで動いているユーザー管理モジュールの、ユーザー登録が出来ないという不具合があった。

当初はユーザー登録画面→確認画面の所で、シリアライズして渡している入力情報が受け取れていないとリダイレクトされるので、それなのかな~と思って見たけどそこは通ってるにもかかわらず、insert出来ない現象があった。

う~んと思ってぐぐってみたら、この辺にヒントとなる記述が。

query()を通過する条件は
★SELECT文は無条件で通過。それ以外は以下の条件
★POSTデータであること、かつ、HTTP_REFERERが収得できること
となります。

リンク集モジュール等で、登録サイトへのアクセス数をカウントするような場合ですと、queryF()の使用例を見ることができます。具体的にはmylinksモジュールのvisit.php内で使われています。こういう使い方ならば、悪意ある攻撃を受けてもカウントが異常に上がるくらいですから許せる範囲なのでしょう。重要な処理の場面でqueryF()は使ってはいけません。

この制約から逃れるためにはワンタイムチケットを導入することをお勧めします。GIJOEさんが公開されているチケットクラスには、GETに渡すための半券も用意されていますので参考になるかと思います。「チケット」で過去ログを探してみてください。

XOOPS Cube日本サイト - 旧フォーラム

なんだよこの制約はあああああと思ったけど、どうもCSRF対策のやっつけ版みたいだな・・・

ユーザー登録モジュール登録メソッド(kernel/user.php#558あたり)で発行されているSQLをログに吐いて、phpmyadmin経由で叩いたらINSERT出来たので、ますますこの制約に引っかかっているんだな、と。

で、その制約チェックを行っているのが、modules/legacy/kernel/Legacy_Controller.class.phpにある、以下のDB接続メソッド。

<?php
	/**
	 * Create the instance of DataBase class, and set it to member property.
	 * @access protected
	 */
	function _setupDB()
	{
		if(!defined('XOOPS_XMLRPC'))
			define('XOOPS_DB_CHKREF', 1);
		else
			define('XOOPS_DB_CHKREF', 0);

		require_once XOOPS_ROOT_PATH.'/class/database/databasefactory.php';

		if ($this->mRoot->getSiteConfig('Legacy', 'AllowDBProxy') == true) {
			if ($_SERVER['REQUEST_METHOD'] != 'POST' || !xoops_refcheck(XOOPS_DB_CHKREF)) {
				define('XOOPS_DB_PROXY', 1);
			}
		}
		elseif ($_SERVER['REQUEST_METHOD'] != 'POST') {
			define('XOOPS_DB_PROXY', 1);
		}

		$this->mDB =& XoopsDatabaseFactory::getDatabaseConnection();

		$GLOBALS['xoopsDB']=&$this->mDB;
	}

だるいからxoops_refcheckを辞めるなり、XOOPS_DB_PROXYのdefineをコメントアウトするなりすれば、とりあえず登録はできるようになります。

しかし・・・不思議な仕組みだ。セレクトオンリーのDBコネクションを返せばいいって、SQLインジェクション食らって情報抜かれたら意味ないだろって思うけどw