php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #81717 PHP "Magic" methods DOS
Submitted: 2022-05-13 09:14 UTC Modified: 2022-05-13 11:15 UTC
From: cyberguru2209 at gmail dot com Assigned: cmb (profile)
Status: Duplicate Package: Scripting Engine problem
PHP Version: 7.4.29 OS: Any
Private report: No CVE-ID: None
 [2022-05-13 09:14 UTC] cyberguru2209 at gmail dot com
Description:
------------
Hello.
Can it be a security issue that calling methods from ArrayAccess interface can cause infinite loop and segfault?
This problem appears when using references to objects. In some real-world web applications it can be done remotely using unserialize function. 
In the attached example $this->data property is reference to Obj object itself.
So calling offsetGet method from Obj class object causes infinite recursion.
All ArrayAccess interface methods are affected, as well as __toString magic method.

I reported this bug as security issue, because on the page https://wiki.php.net/security there is an item "severely impact accessibility or performance of the system". Local or possible remote user can do denial of service attack.
This problem presents in all PHP versions starting from 5.0.* to 8.0.*.

To patch this bug, we might suggest to use approach similar to ZEND_ACC_USE_GUARDS (it is used for "magic" methods __get/__set/__isset/__unset) to prevent infinite recursion in ArrayAccess methods.

Test script:
---------------
I created test scripts for every affected magic method:

- offsetGet
https://gist.github.com/dsadyrin/47a7b835cdfd6d44ba570c7b20fcb5e5
- offsetSet
https://gist.github.com/dsadyrin/e695c0ba3fd1dfad41dce7602d54b82b
- offsetUnset
https://gist.github.com/dsadyrin/2da94278edc7988b47e1a8e0ce9758a2
- offsetExists
https://gist.github.com/dsadyrin/1de2b80395ce737ad9a48315087db041
- __toString
https://gist.github.com/dsadyrin/e2e2cc2077ee4c5b130ef7db233dfc11


Expected result:
----------------
Expected result:   no segfault

Actual result:
--------------
Actual result:  Segmentation fault (core dumped)

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
execute_ex (ex=0x7ffff4596b20) at /home/user/php-7.3.27/Zend/zend_vm_execute.h:51412
51412		const zend_op *orig_opline = opline;
(gdb) bt
#0  execute_ex (ex=0x7ffff4596b20) at /home/user/php-7.3.27/Zend/zend_vm_execute.h:51412
#1  0x0000555555b397e1 in zend_call_function (fci=fci@entry=0x7fffff7ff190, fci_cache=fci_cache@entry=0x7fffff7ff170)
    at /home/user/php-7.3.27/Zend/zend_execute_API.c:756
#2  0x0000555555b63bdc in zend_call_method (object=object@entry=0x7fffff7ff270, obj_ce=<optimized out>, obj_ce@entry=0x7ffff440e018, fn_proxy=fn_proxy@entry=0x0, 
    function_name=function_name@entry=0x555556334428 "offsetget", function_name_len=function_name_len@entry=9, retval_ptr=retval_ptr@entry=0x7ffff4596b10, 
    param_count=1, arg1=0x7fffff7ff260, arg2=0x0) at /home/user/php-7.3.27/Zend/zend_interfaces.c:103
#3  0x0000555555b792b4 in zend_std_read_dimension (object=<optimized out>, offset=<optimized out>, type=0, rv=0x7ffff4596b10)
    at /home/user/php-7.3.27/Zend/zend_object_handlers.c:857
#4  0x0000555555b824e4 in zend_fetch_dimension_address_read (slow=1, support_strings=1, type=0, dim_type=8, dim=0x7ffff44902d0, container=0x7ffff4596b00, 
    result=0x7ffff4596b10) at /home/user/php-7.3.27/Zend/zend_execute.c:2024
#5  zend_fetch_dimension_address_read_R_slow (container=0x7ffff4596b00, dim=<optimized out>) at /home/user/php-7.3.27/Zend/zend_execute.c:2057
#6  0x0000555555b9deb8 in ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER () at /home/user/php-7.3.27/Zend/zend_vm_execute.h:13479
#7  0x0000555555bc9703 in execute_ex (ex=0x7ffff4596b20) at /home/user/php-7.3.27/Zend/zend_vm_execute.h:56965
#8  0x0000555555b397e1 in zend_call_function (fci=fci@entry=0x7fffff7ff4c0, fci_cache=0x7ffff4490240, fci_cache@entry=0x7fffff7ff4a0)
    at /home/user/php-7.3.27/Zend/zend_execute_API.c:756
#9  0x0000555555b63bdc in zend_call_method (object=object@entry=0x7fffff7ff5a0, obj_ce=<optimized out>, obj_ce@entry=0x7ffff440e018, fn_proxy=fn_proxy@entry=0x0, 
    function_name=function_name@entry=0x555556334428 "offsetget", function_name_len=function_name_len@entry=9, retval_ptr=retval_ptr@entry=0x7ffff4596a90, 
    param_count=1, arg1=0x7fffff7ff590, arg2=0x0) at /home/user/php-7.3.27/Zend/zend_interfaces.c:103
#10 0x0000555555b792b4 in zend_std_read_dimension (object=<optimized out>, offset=<optimized out>, type=0, rv=0x7ffff4596a90)
    at /home/user/php-7.3.27/Zend/zend_object_handlers.c:857
#11 0x0000555555b824e4 in zend_fetch_dimension_address_read (slow=1, support_strings=1, type=0, dim_type=8, dim=0x7ffff44902d0, container=0x7ffff4596a80, 
    result=0x7ffff4596a90) at /home/user/php-7.3.27/Zend/zend_execute.c:2024
#12 zend_fetch_dimension_address_read_R_slow (container=0x7ffff4596a80, dim=<optimized out>) at /home/user/php-7.3.27/Zend/zend_execute.c:2057
#13 0x0000555555b9deb8 in ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER () at /home/user/php-7.3.27/Zend/zend_vm_execute.h:13479
#14 0x0000555555bc9703 in execute_ex (ex=0x7ffff4596b20) at /home/user/php-7.3.27/Zend/zend_vm_execute.h:56965
#15 0x0000555555b397e1 in zend_call_function (fci=fci@entry=0x7fffff7ff7f0, fci_cache=0x7ffff4490240, fci_cache@entry=0x7fffff7ff7d0)
    at /home/user/php-7.3.27/Zend/zend_execute_API.c:756
#16 0x0000555555b63bdc in zend_call_method (object=object@entry=0x7fffff7ff8d0, obj_ce=<optimized out>, obj_ce@entry=0x7ffff440e018, fn_proxy=fn_proxy@entry=0x0, 
    function_name=function_name@entry=0x555556334428 "offsetget", function_name_len=function_name_len@entry=9, retval_ptr=retval_ptr@entry=0x7ffff4596a10, 
    param_count=1, arg1=0x7fffff7ff8c0, arg2=0x0) at /home/user/php-7.3.27/Zend/zend_interfaces.c:103
#17 0x0000555555b792b4 in zend_std_read_dimension (object=<optimized out>, offset=<optimized out>, type=0, rv=0x7ffff4596a10)
    at /home/user/php-7.3.27/Zend/zend_object_handlers.c:857
#18 0x0000555555b824e4 in zend_fetch_dimension_address_read (slow=1, support_strings=1, type=0, dim_type=8, dim=0x7ffff44902d0, container=0x7ffff4596a00, 
    result=0x7ffff4596a10) at /home/user/php-7.3.27/Zend/zend_execute.c:2024
#19 zend_fetch_dimension_address_read_R_slow (container=0x7ffff4596a00, dim=<optimized out>) at /home/user/php-7.3.27/Zend/zend_execute.c:2057
#20 0x0000555555b9deb8 in ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER () at /home/user/php-7.3.27/Zend/zend_vm_execute.h:13479
#21 0x0000555555bc9703 in execute_ex (ex=0x7ffff4596b20) at /home/user/php-7.3.27/Zend/zend_vm_execute.h:56965
#22 0x0000555555b397e1 in zend_call_function (fci=fci@entry=0x7fffff7ffb20, fci_cache=0x7ffff4490240, fci_cache@entry=0x7fffff7ffb00)
    at /home/user/php-7.3.27/Zend/zend_execute_API.c:756
#23 0x0000555555b63bdc in zend_call_method (object=object@entry=0x7fffff7ffc00, obj_ce=<optimized out>, obj_ce@entry=0x7ffff440e018, fn_proxy=fn_proxy@entry=0x0, 
    function_name=function_name@entry=0x555556334428 "offsetget", function_name_len=function_name_len@entry=9, retval_ptr=retval_ptr@entry=0x7ffff4596990, 
    param_count=1, arg1=0x7fffff7ffbf0, arg2=0x0) at /home/user/php-7.3.27/Zend/zend_interfaces.c:103
--Type <RET> for more, q to quit, c to continue without paging--



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2022-05-13 11:15 UTC] cmb@php.net
-Status: Open +Status: Duplicate -Assigned To: +Assigned To: cmb
 [2022-05-13 11:15 UTC] cmb@php.net
This is a known issue, and already being tracked as bug #64196.

We do not consider this to be a security issue, but rather a
programming error (for now).  Unserialization of untrusted data is
never a security issue regarding php-src.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC