GAE for PHP環境でライブラリへの直接アクセスを禁止する

例えば以下のような構成を考えます。


[path]
/index.php : 公開WEBページ
/lib/sub.php : ライブラリ

[index.php]

<?php
require_once('lib/sub.php');
…

この際、URLとして"*.appspot.com/lib/sub.php"を直接指定されると/lib/sub.phpが実行されてしまいます。
/lib/の下のPHPスクリプトは直接実行されたくないでしょうから何とかして防止したいところです。

一般的にはhttpd.htaccessファイルやPHPget_included_files()関数を使って防止することになるのでしょうが、GAE for PHP環境ではapp.yamlの設定(+α)で防止することができます。

[app.yaml]

handlers:
- url: /lib/.*
  script: /404.php

- url: /(.+)\.php$
  script: \1.php

[404.php]

<?php
header('HTTP/1.1 404 Not Found');
?>
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>404 Not Found</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Not Found</h1>
<h2>The requested URL <code><?=$_SERVER["REQUEST_URI"]?></code> was not found on this server.</h2>
<h2></h2>
</body></html>

GAEのapp.yamlは、アップロード対象ファイルの特定とバージョニングに加えてルーティングを指定するファイルですが、そのルーティング機能で「/lib/の下をアクセスされたら代わりに/404.phpを実行する」と指定します(/直下のPHPスクリプトはそのまま実行)。
app.yamlによるルーティングはrequire()には適応されませんから、この指定をしたことによる既存のPHPスクリプトへの変更は一切不要です。

そして/404.phpの中身は上記のようなPHPスクリプトとすることで、GAEが本来出力する404ページのそれをエミュレートします。
$_SERVER["REQUEST_URI"]はルーティングで曲げられる前のパスが入っていますから、あたかも直接指定されたURLが404であるように見えます。
これで攻撃者には/libの存在そのものが隠ぺいされますから、安心してライブラリを置くことができるというわけです。