On Mar 21, 2015, at 10:17, Georges.L <cont...@geolim4.com> wrote:

> The main purpose of this RFC is *not* to improve the exception system of
> PHP but to improve the code logic/hierarchy.
> 
>>> Hi php internals,
>>> 
>>> After some long and deep research i finally decided to write my first RFC
>>> about a feature i'd be interested to be improved in the php core: *Nested
>>> enclosing returns*

Georges,

This would make simply looking at code and reasoning about what it does 
impossible.

At present, if I have the following code:

function foo() {
        if(doSomething()) {
                success();
        } else {
                failure();
        }
        
        return 42;
}

try {
        bar(foo());
} catch($ex) {
}

Then I can make the following true statements about this code:
        * foo always calls doSomething()
        * foo always calls either success() or failure(), based on the result 
of doSomething()
        * foo always returns 42
        * bar is always called (with foo’s return value, 42)
        * Alternatively to the above, any of the called functions may throw an 
exception, which will be caught by the catch block

If any of doSomething(), success(), failure(), or bar() can arbitrarily return 
to some higher calling scope, then the only thing I can say for sure is that 
doSomething() is called, after which my application could be in some 
dangerously inconsistent state because I have no idea what will be executed 
next.

This then provides significant security concerns. For example, if we have this:

function API_Function_With_Callback($callback) {
        try {
                $callback();
                
                //do more stuff
                
                return true;
        } catch($ex) {
                //do error stuff
                
                return false;
        }
}

function doEvil() {
        $sentinel = //some unique value
        
        $result = API_Function_With_Callback(function() use($sentinel) {
                $backtrace = debug_backtrace();
                $nestingLevel = //determine nesting level from backtrace
                if($nestingLevel == 2) return $sentinel, 2;
                else if($nestingLevel == 3) return $sentinel, 3;
                else if($nestingLevel == 4) return $sentinel, 4;
                // etc
        }
        
        // Exploit inconsistent state of Call_API_Function here
        if($result === $sentinel) { … }
}

Then we can short-circuit code from some other library which isn’t prepared to 
deal with this kind of hijacking. More seriously, this sort of hijacking 
*can’t* be defended against (at least not without a weakening of your original 
proposal). Any function that takes a callback is potentially vulnerable to this 
sort of attack.


Can you suggest an actual, practical, example, where this would be such a 
benefit as to override the inherent difficulty about reasoning about this code, 
and the potential security concerns? Are there any other languages that make 
something like this possible?

I suspect that any code that could be “improved” with this functionality is 
already in significant need of improvement by more conventional means.

-John


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to