dimanche 8 janvier 2017

Is it possible to truly limit access of this private property?

I'm using three tricks in my attempt:

  • Reflections can't be used with dynamic class properties
  • __get() or __set() must be called when accessing dynamic class properties
  • debug_backtrace() can be utilized to emulate something similar to private

For the class Foo with the private non-static property $bar, I want to disallow any scopes outside $this to modify its value. Therefore I'm doing it like this:

/** @property object $bar */
class Foo{
    public function __get($k){
        if($k === "bar") return $this->bar;
    }
    public function __set($k, $v){
        if($k === "bar"){
            $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
            if($trace[0]["object"] !== $this or $trace[0]["file"] !== __FILE__) throw new RuntimeException("Illegal access");
            $this->bar = $v;
        }
    }
}

This should be (not tested) invulnerable to three kinds of access:

  • Direct access
    • debug_backtrace() checks if the calling context is from $this. Direct access outside $this will be disallowed.
  • ReflectionProperty
    • PHP Fatal Error: Uncaught ReflectionException: Property bar does not exist
    • Reflections don't work with dynamic properties. It doesn't even detect the existence of it through ReflectionClass::hasProperty() :-)
  • Closure::bind
    • Not tested, but I believe debug_backtrace() should return the "file" something different from FILE, but rather the file that defined the Closure. I only have correct usage of Foo, so I don't care as long as the correct code is loaded.

Assuming that there is no permission to write any files and no extension to redefine class methods, but arbitrary PHP code can be loaded, are there any methods to change this Foo->bar property?





Aucun commentaire:

Enregistrer un commentaire