草庐IT

php - 预处理 PHP $_GET 变量

coder 2023-10-22 原文

我继承了一个庞大且漏洞百出的 PHP 代码库。它需要彻底审查和清理,但同时我需要权宜之计。从长远来看,它需要适当的用户输入 sanitizer ,例如根据 What's the best method for sanitizing user input with PHP? .然而,这在短期内是不切实际的。它是一个由数千个文件组成的代码库,包含数十万行代码,我需要某种方法来尽快阻止大部分错误。

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

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

我很清楚:

  • 这不是一个正确的修复,只是一个拼凑。
  • 我可以使用某种查找和替换功能将它放在每个文件的顶部。
  • 几乎肯定还有其他未经处理的 SQL 输入问题。
  • 代码应该使用准备好的语句。

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

编辑:下面是我通过自动添加拼凑在一起的一些代码,以防对其他人有用。您需要替换数据库用户名、密码,可能还需要替换字符集。除了 $_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>';
}

最佳答案

您可以为每个请求添加一个文件 auto-prepend-file在你的 php.ini

auto_prepend_file = /path/of/your/file.php

然后在这里进行您想要的所有 sanitizer 。

Specifies the name of a file that is automatically parsed before the main file. The file is included as if it was called with the require function, so include_path is used.

关于php - 预处理 PHP $_GET 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34179445/

有关php - 预处理 PHP $_GET 变量的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  3. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  4. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  5. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  6. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  7. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. ruby-on-rails - 应用程序的名称是否可以作为变量使用? - 2

    当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve

  10. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

随机推荐