メイン
   XOOPS2一般
     GET時にMySQLを更新できないのはなぜ?
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
o_ob
投稿日時: 2005/1/31 20:34
新米
登録日: 2004/1/5
居住地: 西フランス
投稿: 13
GET時にMySQLを更新できないのはなぜ?

XOOPS開発者の皆さん、お世話になっております。
モジュール内のあるURLをみたかどうかを記録するコードを書いているのですが、ログDBに記録するときのquery()でエラーが起きて困っています。mySqlAdminやかねやんのMYSQLでは普通に追加できるSQLなので変だなあ、とXOOPSのソースを洗っていたら以下のようなエラーであることがわかりました。
<PRE>
(/class/database/mysqldatabase.phpより)
class XoopsMySQLDatabaseProxy extends XoopsMySQLDatabase
{
(snip)

	function &query($sql, $limit=0, $start=0)
	{
	    $sql = ltrim($sql);
		if (strtolower(substr($sql, 0, 6)) == 'select') {
		//if (preg_match("/^SELECT.*/i", $sql)) {
			return $this->queryF($sql, $limit, $start);
		}
		<B>$this->logger->addQuery($sql, 'Database update not allowed during processing of a GET request', 0);</B>
		return false;
	}

}
</PRE>
これってつまりHTTPでGETリクエストの最中はDBを更新できない、ということですよね?なぜなんでしょう?
またこの手の更新をしたい場合はどういった書き方をするのが良いのでしょうか?
「このモジュールのこの辺を見よ!」とかでもかまいません、情報いただければ幸いです。

匿名
投稿日時: 2005/1/31 20:51
Re: GET時にMySQLを更新できないのはなぜ?
引用:
モジュール内のあるURLをみたかどうかを記録するコードを書いているのですが、ログDBに記録するときのquery()でエラーが起きて困っています。

これってつまりHTTPでGETリクエストの最中はDBを更新できない、ということですよね?なぜなんでしょう?

GET リクエストはアドレス部の ? 以降に共通なため、
これを用いてアタックを行う事による悪質行為が行われる可能性があります。
現在の XOOPS ではそれを防ぐために query() では GET リクエストを実行できないようになっています。

危険性がないのであれば queryF() を用いても良いのですが、
この辺の問題があれば、対策を検討する必要があります。

o_ob
投稿日時: 2005/1/31 22:38
新米
登録日: 2004/1/5
居住地: 西フランス
投稿: 13
Re: GET時にMySQLを更新できないのはなぜ?
引用:
route286さんは書きました:
これを用いてアタックを行う事による悪質行為が行われる可能性があります。
現在の XOOPS ではそれを防ぐために query() では GET リクエストを実行できないようになっています。

なるほど…やはりアタック対策でしたか。
でもPOSTなら問題がないんでしょうか??

引用:
危険性がないのであれば queryF() を用いても良いのですが、

なるほど、queryFの「F」はForceということでしょうかね。
会員限定の同窓会名簿の閲覧ログなのでこの方式で対応してもいいかもしれないですね。
queryFで追加して、悪質な行為があるなら通知する、といったプログラムにしようと思います。

どうもありがとうございました。

blues
投稿日時: 2005/1/31 23:16
一人前
登録日: 2002/11/5
居住地:
投稿: 143
Re: GET時にMySQLを更新できないのはなぜ?

o_obさんこんばんは

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

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

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


----------------

Blues Supporter
サッカーサイト専門サーチエンジンの運営
BluesBB 掲示板モジュールの配布

スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
To Top