サポート » 使い方全般 » エラー原因の見つけ方

  • 自力で調べても解決できなさそうなので相談お願いします。
    現在運用中のもので、社用情報管理をしているサイトでの話です。
    ・特定多数がログインしてカスタムポストの登録やログイン者専用ページの閲覧を行う
    ・不特定多数がログインなしで一部データの閲覧ができる
    ・特定のURLを知っているものはログインなしでカスタムポストの下書き作成ができる
    という特徴があります。

    PHP Notice:  Trying to get property 'ID' of non-object in ***/class-wp-query.php on line 4044
    PHP Notice:  Trying to get property 'post_title' of non-object in ***/class-wp-query.php on line 4046
    PHP Notice:  Trying to get property 'post_name' of non-object in ***/class-wp-query.php on line 4048

    気づいたら少し前から上記のPHP注意のセットが数秒おきに1~6回ほど繰り返しログに残り、数時間おいてまた繰り返しログに残るという現象が起きています。

    テンプレートやプラウグインの影響かと思い、エックスサーバー内の機能を利用して別ドメインにまるっとコピーを作って見ましたが、コピー側では全くエラーが出ません。
    コピーの方は検索非公開設定にしてあるのと、確認のためにログインしているのが自分だけというのが差です。

    エラーが出ている時間はユーザーのログイン履歴からみられるログイン時間とは関連なさそうです。
    1日のうちにエラーが吐かれる個数は固定ではないです。

    いま実際に本番で動いているものを止めることはできないのですが、エラーの出ている原因を調べるにはどうすればいいでしょうか?

7件の返信を表示中 - 1 - 7件目 (全7件中)
  • dwc-1さん、こんにちは。

    1.数秒おきに1~6回ほど繰り返しログに残り、数時間おいてまた繰り返し
    2.コピー側では全くエラーが出ません
    3.ユーザーのログイン履歴からみられるログイン時間とは関連なさそう
    4.1日のうちにエラーが吐かれる個数は固定ではない
    この条件から考えられることは、外部からの不定期なアクセスです。
    まあ、機械的に脆弱性を探しているアクセスだとは思いますが、該当のログが発生している同時刻の Web サーバーへのアクセスログを確認し、繰り返している不審なアクセスがないか調査されてみてはいかがでしょうか。

    該当箇所はis_pageの判定関数のようですが、おそらく$this->get_queried_object()で正しい返り値が得られなく、$page_obj->ID等で Notice を吐いているのではないかと。通常のページへのアクセスではなく、普通にはアクセスしない URL へのアタックか、何らかの呼び出しを含めた get アクセスとかでないかと推測しますが、ログを見てみないとですね。

    ご参考になれば。

    トピック投稿者 d.w.c

    (@dwc-1)

    shokun0803さん、ありがとうございます。とても助かります。

    サーバーのログを確認したところ、サイトリニューアルよりずいぶん昔の、現在は存在しないブログ記事のRSSフィードに対してのアクセスだったようです。
    [19/Jan/2022:10:39:56 +0900] "GET /event/%E5%BF%98%E5%B9%B4%E4%BC%9A%EF%BC%81/feed/ HTTP/1.1" 200 458 "-" "Mozilla/5.0 (compatible; MJ12bot/v1.4.8; http://mj12bot.com/)"

    これは現存しないURLに対してアクセスが来ているけど、404エラーで返していないということになるんでしょうか?
    デバッグログがこのアラートで埋まってしまって不便なので何とかしたいのですが、RSSフィードのことよくわからなくてどう対策すればいいのかちょっと糸口が見つけられないです…
    何かアドバイスいただけますと幸いです。

    • この返信は2年、 3ヶ月前にd.w.cが編集しました。

    dwc-1さん、こんにちは。

    ログでは 200 OK を返しているので、何かを表示しているようですね。
    実際にアクセスしてみれば早いのではないでしょうか。

    プラグイン等でリダイレクトしてしまうのが早いかとは思います。
    リダイレクトしてログがでなくなれば問題ないとの判断でもよろしいのでは?

    ご参考になれば。

    トピック投稿者 d.w.c

    (@dwc-1)

    ありがとうございます。
    ルートディレクトリの.htacessで

    <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    RedirectMatch 301 ^/event/(.*)/feed/(.*)$ /
    </IfModule>

    とリダイレクト処理をしたところ、eventディレクトリ下のrssではエラーを吐かなくなりました。

    ただその後もエラーが出るので調べたところ、違うディレクトリ構造のURLでのアクセスも出てきてしまい、さらに調べると
    https://ドメイン/sonzaisinaiyo/feed/
    のようにそもそも存在しないページだとしてもURLの最後に/feed/さえ入っていればアクセスできてしまい、エラーを吐くようでした。

    自分の能力では.htacessでの汎用性のある対応が思いつかなかったので下記のようにfunctions.phpでリダイレクトをかけてみました。

    function is_redirect_to_top(){
    	$request_uri = home_url('/') . $_SERVER['REQUEST_URI'];
    	if( empty( $request_uri )) return;
    	if( strpos( $request_uri, "feed" ) === false ) return;
    
    	$request_uri_nofeed = preg_replace( "/\/feed/", '', $request_uri );
    	$response = @file_get_contents( $request_uri_nofeed );
    
    	if ($response !== false) {
    		//存在するページ
    		return;
    	} else {
    		//存在しないページ
    		wp_safe_redirect( home_url('/') );
    		exit();
    	}
    }
    add_action( 'template_redirect', 'is_redirect_to_top');

    ただ、これだとリダイレクト自体はできたんですが、エラー文章はまた出てきてしまいました。
    どうやら'template_redirect'で判別する前の段階でエラーが出てしまっているようで…

    .htacessでURLから/feed/を取り除いた場合のページが存在するかどうかを判別する方法か、
    そもそもTrying to get propertyエラーを無視する方法などありますでしょうか・・・

    @dwc-1 さん こんにちは。

    .htaccessに書く場合

    RedirectMatch 301 ^/event/(.*)/feed/(.*)$ /

    →この記述だと、「マッチしたアクセスをトップページに301リダイレクトさせる」となりますが、それで大丈夫でしょうか。
    ページが存在しない事を知らせ、かつフィードURLにマッチさせるのであれば、以下でどうでしょうか。

    RedirectMatch 404 (.*)/feed/(.*)$

    ただし、これはサーバ側の設定になるので、詳細はレンタルサーバ会社にお問い合わせください。

    WordPressでコントロールする場合

    is_feed で判定すれば良いと思います。

    function feed_404( $query ) {
        if ( $query->is_feed ) {
            wp_die( '', '', array( 'response' => 404 ) );
        }
    }
    add_action( 'parse_query', 'feed_404' );
    トピック投稿者 d.w.c

    (@dwc-1)

    Tetsuaki Hamano さん、ありがとうございます。
    現在は存在していない過去サイトの、まったく重要ではないブログのURLだったのでトップに飛ばしていましたが、たしかに404の方がよさそうですね。

    現在も生きているページのRSSは公開したままでも大丈夫なので、書いていただいたwordpressでコントロールする方法を参考に書いてみました。
    wp_die()を使ってみたら表示されるのがちょっとよくわからない画面になってしまったので、そこも代替え案にしています。

    function feed_404( $query ) {
    	if ( $query->is_feed ) {
    		$target_post_id = @$query->queried_object->ID;
    		if ( empty( $target_post_id )) {
    			$query->set_404();
    			status_header(404);
    		}
    	}
    }
    add_action( 'parse_query', 'feed_404' );

    これで怒涛のエラーメッセージの嵐から解放されました。
    ありがとうございました。

    トピック投稿者 d.w.c

    (@dwc-1)

    $target_post_idを取得する部分のコード間違ってたみたいだったので修正版一応記載します。
    というか、固定ページと投稿ページとカスタム投稿で取得できる$queryの中身が違うようで、存在するページなのかの判別の付け方がわからなく、もう諦めて教えていただいたコードの通りすべてのfeedは弾くことにしました。

    function feed_404( $query ) {
    	if ( $query->is_feed ) {
    		$query->set_404();
    		status_header(404);
    	}
    }
    add_action( 'parse_query', 'feed_404' );

    出来れば新しく作られた投稿やカスタム投稿ではfeedが使いたかったですが、とりあえずエラー出さなくなっただけで良しとします。

7件の返信を表示中 - 1 - 7件目 (全7件中)
  • トピック「エラー原因の見つけ方」には新たに返信することはできません。