gpt4 book ai didi

php - 如何避免 PHP 中的反射注入(inject)攻击?

转载 作者:行者123 更新时间:2023-12-04 03:18:12 24 4
gpt4 key购买 nike

我正在编写一个类,它允许您将 HTTP 请求与使用 JSON 数据的类实例桥接起来,而无需在您正在桥接的类中进行任何实现。基本上这是它的工作原理:

// This is just an ordinary class.
$service = new WeatherService();

$jhi = new JsonHttpInterface($service);
$jhi->exec();

JsonHttpInterface 类将检查请求的 PATH_INFO 并调用该方法,应用任何查询字符串参数作为参数。

http://example.com/the_above.php/getWeather?state="CA" 将转换为
$service->getWeather("CA")(假设第一个参数的名称是$state)。

这是找到和调用方法的方式:

$method = new ReflectionMethod(get_class($this->instance), $action);
/*
... code that matches query string values to arguments of above method...
*/
$response = $method->invokeArgs($this->instance, $args);

现在我想知道的是:这样一个系统的弱点是什么。我对错误检查非常宽松,在尝试调用不存在或私有(private)/ protected 方法时依赖 PHP 抛出错误。

  • 是否可以欺骗系统?
  • 是否可以传入一个无效的方法名来执行除抛出错误之外的其他操作?
  • 是否可以引用基类或任何其他类中的方法?

JsonHttpInterface 的完整源代码可在此处获得:http://blixt.org/js/two-cents.php

最佳答案

您可以在不使用 ReflectionXYZ 类的情况下实现同样的效果

call_user_func( array($this->instance, $action) , $args);

只要您控制 $this->instance 是什么,两者都以相同的方式保存。
$action 是一个字符串,用于搜索对象/类的方法哈希表中的条目,并且没有可以转义对象上下文(切换到另一个对象)的魔术符号。并且不涉及解析,例如在 sql 和 sql 注入(inject)中。
ReflectionMethod 和 call_user_func_array() 都遵循方法的保护级别。例如

class Foo {
public function publicfn() {
echo 'abc';
}

protected function protectedfn() {
echo 'xyz';
}
}

$obj = new Foo;
call_user_func_array(array($obj, 'publicfn'), array());
call_user_func_array(array($obj, 'protectedfn'), array());
$ro = new ReflectionMethod($obj, 'protectedfn');
$ro->invokeArgs($obj, array());

打印

abc
Warning: call_user_func_array() expects parameter 1 to be a valid callback, cannot access protected method Foo::protectedfn() in blabla on line 14

Fatal error: Uncaught exception 'ReflectionException' with message 'Trying to invoke protected method Foo::protectedfn() from scope ReflectionMethod' in blabla:16
Stack trace:
#0 blabla(16): ReflectionMethod->invokeArgs(Object(Foo), Array)
#1 {main}
thrown in blabla on line 16

如果情况总是如此,您可能想查找一下。有例如条目 - MFH 修复了错误 #37816(ReflectionProperty 在访问 protected 属性时不会抛出异常)。至少对于 php 5.3 分支是这样。
您始终可以访问 $this->instance.
的任何基类的公共(public)方法您可以从类上下文中访问 protected 方法,即如果 $this 和 $this->instance 是相同的/派生类型 $this->instance 的 protected 方法是可访问的。例如

class Foo {
protected $instance;
public function __construct(Foo $instance=null) {
$this->instance = $instance;
}
public function publicfn() {
if ( !is_null($this->instance)) {
call_user_func_array( array($this->instance, 'protectedfn'), array());
}
}

protected function protectedfn() {
echo 'Foo::protectedfn() invoked';
}
}

class Bar extends Foo {
protected function protectedfn() {
echo 'Bar::protectedfn() invoked';
}
}

$foo = new Foo(new Bar);
$foo->publicfn();

打印 Bar::protectedfn() 被调用。但这应该不难避免。

关于php - 如何避免 PHP 中的反射注入(inject)攻击?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2066305/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com