预处理PHP $ _GET变量

时间:2015-12-09 12:59:17

标签: php mysql

我继承了一个庞大且极其错误的PHP代码库。它需要彻底的审查和清理,但在此期间我需要一个权宜之计。从长远来看,它需要适当的用户输入消毒,例如,根据{{​​3}}。但是,这在短期内并不实用。它是包含数十万行代码的数千个文件的代码库,我需要一些方法尽快阻止大多数错误。

许多脚本使用$_GET['id']作为数据库查找的未清除参数。有没有办法让PHP自动对这些行中的$_GET数组进行预处理:

if( isset( $_GET['id'] ) )
    $_GET['id'] = (int) $_GET['id'];

我很清楚:

  • 这不是一个正确的解决方案,只是一个kludge。
  • 我可以使用某种查找和替换将它放在每个文件的顶部。
  • 几乎可以肯定有其他未经过处理的SQL输入问题。
  • 代码应该使用预备语句。

然而,它会阻止99%的问题,并获得一些急需的喘息空间。如果可能的话,我更愿意在PHP配置等中全局地完成它。非常感谢任何建议。

编辑:下面是一些代码,我将它们拼凑在一起,通过自动前置,以防其他人使用。您还需要替换数据库用户名,密码以及可能的charset。除了$_GET$_POST之外,您可能还需要清理$_REQUEST$_SESSION$_COOKIE超全球。包含调试代码用于测试目的。请注意,这是作为权宜之计,作为正确输入消毒的替代品!再次感谢所有提供建议的人。

<?php
$debug = false;
if( $debug ) ini_set( 'display_errors', 1 );

if( !function_exists( '_sanitise' ) )
{
    function _sanitise( $input )
    {
        return htmlspecialchars( $input, ENT_QUOTES, 'UTF-8' );
    }
}

if( !function_exists( '_sanitise_sql' ) )
{
    function _sanitise_sql( $input )
    {
        $mysqli = new mysqli( 'localhost', 'username', 'password', 'database' );
        /*if( mysqli_connect_error() )
        {
            echo 'Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error();
        }*/
        $mysqli->set_charset( 'utf8mb4' );
        if( is_array( $input ) )
        {
            $result = array();
            foreach( $input as $key => $value )
            {
                $result[$key] = _sanitise_sql( $value );
            }
            return $result;
        }
        else return $mysqli->real_escape_string( $input );
    }
}

if( !isset( $_GET['_sanitised'] ) )
{
    foreach( $_GET as $key => &$value )
    {
        if( mb_strtolower( $key ) === 'id' ) $value = (int) $value;
        elseif( substr( mb_strtolower( $key ), -3 ) === '_id' ) $value = (int) $value;
        else $value = _sanitise_sql( $value );
    }
    $_GET['_sanitised'] = true;
}

if( !isset( $_POST['_sanitised'] ) )
{
    foreach( $_POST as $key => &$value )
    {
        if( mb_strtolower( $key ) === 'id' ) $value = (int) $value;
        elseif( substr( mb_strtolower( $key ), -3 ) === '_id' ) $value = (int) $value;
        else $value = _sanitise_sql( $value );
    }
    $_POST['_sanitised'] = true;
}

if( $debug )
{
    echo '<pre>$_GET:' . PHP_EOL;
    echo _sanitise( print_r( $_GET, true ) );
    echo PHP_EOL . '$_POST:' . PHP_EOL;
    echo _sanitise( print_r( $_POST, true ) );
    echo '</pre>';
}

1 个答案:

答案 0 :(得分:2)

您可以在php.ini

中使用auto-prepend-file为每个请求添加一个文件
auto_prepend_file = /path/of/your/file.php

在这里做你想要的每一次消毒。

  

指定在之前自动解析的文件的名称   主文件。包含该文件就像使用require调用它一样   函数,所以使用了include_path。