この本を執筆している時点で、http://www.php.cn/ には、関数に似た構文構造を含む合計 3917 個の関数がリストされています。ここでは関数と区別するつもりはありませんが、関数として扱います。
機能が多数あるため、その正しく安全な使い方を 1 つずつ説明することは不可能です。ここでは、最も注意が必要と思われる機能を選択しました。選定基準は使用頻度、使用時の危険度(安全性)、私自身の経験などです。
リストされている各機能について、推奨される使用方法を示します。安全を第一に考えて提案させていただきます。実際にご使用になる際は、必要に応じて調整してください。
ある機能が別の機能と同じリスクを持っている場合、重複して説明するのではなく、他の機能を参照して情報を提供します。
B.1. eval( )
eval( ) 関数は、PHP ステートメント モードで文字列を解析して実行するために使用されます。例:
<?php $name = 'Chris'; $string = 'echo "Hello, $name";'; eval($string); ?>
上記の例では、$string は PHP ステートメントとして実行されるため、次と同等です:
<?php $name = 'Chris'; echo "Hello, $name"; ?>
eval( ) は非常に便利ですが、汚染されたデータを使用すると非常に危険になる可能性があります。たとえば、次の例では、$name が汚染されている場合、攻撃者は任意の PHP コードを実行できます。 PHP で解釈される文字列が汚染されたデータを使用しているかどうか不明な場合は、可能であれば eval() の使用を避けることをお勧めします。この機能は、セキュリティレビューやピアレビュー中に強調されるべきです。
B.2. exec()
第 6 章で述べたように、シェル コマンドの実行は非常に危険な操作です。シェル コマンドの作成時に汚染されたデータを使用すると、コマンド インジェクションの脆弱性が発生する可能性があります。
シェル コマンド関数の使用は避けるようにしてください。ただし、シェル コマンド関数を使用する必要がある場合は、シェル コマンドを作成するときに必ずフィルター処理されエスケープされたデータのみを使用してください。
<?php $name = $_GET['name']; eval($name); ?>
B.3. ファイル( )
ファイル( ) 関数は、ファイルを読み取るための私のお気に入りの方法の 1 つです。ファイルの各行を、返された配列の要素として読み取ります。特に便利なのは、ファイル ハンドルを指定する必要がないことです。ファイル名を指定すると、すべてが自動的に行われます。
上記のファイルの場合2 行で、次のような出力が生成されます。 ) 関数は特に危険ではありませんが、allow_url_fopen オプションをオンにして使用すると、リモート Web サイトなどのさまざまな種類のリソースのコンテンツを読み取ることができます。
出力は次のとおりです (要約):
<?php $clean = array(); $shell = array(); /* Filter Input ($command, $argument) */ $shell['command'] = escapeshellcmd($clean['command']); $shell['argument'] = escapeshellarg($clean['argument']); $last = exec("{$shell['command']} {$shell['argument']}", $output, $return); ?>
file() 関数によって呼び出されるファイル名が汚染されたデータから構成されている場合、その内容も汚染されていると見なされます。これは、汚染されたデータを使用してファイル名を作成すると、悪意のあるデータを含むリモート Web サイトを開いてしまう可能性があるためです。データを変数に保存すると、危険性が大幅に高まります:
<?php $contents = file('/tmp/file.txt'); print_r($contents); ?>
$tainted数组中的每个元素与$_POST['filename']有相同的危险性——它是输入并必须要进行过滤。
在这里,其行为有可能是意想不到的——$_POST['filename']的误用可以改变file()函数的行为,因此它可以指向一个远程资源而不是本地文件。
B.4. file_get_contents( )
参见 "file( )."
B.5. fopen( )
参见 "file( )."
B.6. include
如第5章所述,include在组织化与模块化的软件设计中被普遍使用,是非常有必要的。但是,不正确的使用include会造成一个重大的代码注入安全漏洞。
在include语句中只使用已过滤数据是非常有必要的。在安全审查和同行评审中,应重点检查该函数。
B.7. passthru( )
见"exec( )."
B.8. phpinfo( )
phpinfo( )会输出有关PHP信息的页面——运行的版本号,配置信息等等。由于phpinfo( )的输出提供了非常多的信息,我建议限制对任何使用该函数的资源的访问。
如果你使用的第八章中的技巧来保护数据库验证信息,则需要确认访问者不能看到由phpinfo( )形成的输出信息,这是由于它会暴露超级全局数组$_SERVER的内容。
B.9. popen( )
参见"exec( )."
B.10. preg_replace( )
preg_replace( )用于对符合正则表达式的字符串进行替换。在某些情况下,使用被污染数据构造正则表达式部分会非常危险,因为它的e修饰符会导致在替换时把用于替换的参数作为PHP代码来对待。例如(本例为译者所加):
<?php $str = "abcdef"; $se = "len"; $reg = "/abc/e"; echo preg_replace($reg,"strlen(\$se)",$str); ?>
会输出如下字串:
3def
当使用了e修饰符,不管是否有意为之,它会带来与eval()相同的风险。在安全审查和同行评审中,应重点检查该函数。
B.11. proc_open( )
参见 "exec( )."
B.12. readfile( )
参见 "file( )."
B.13. require
参见 "include."
B.14. shell_exec( )
参见 "exec( )."
B.15. system( )
参见 "exec( )."
以上就是PHP安全-函数的内容,更多相关内容请关注PHP中文网(www.php.cn)!