Bug #66322 [Ver->Csd]: COMPersistHelper::SaveToFile can save to wrong location

From: Date: Thu, 06 Feb 2020 14:02:47 +0000
Subject: Bug #66322 [Ver->Csd]: COMPersistHelper::SaveToFile can save to wrong location
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-225389@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66322&edit=1 ID: 66322 Updated by: cmb@php.net Reported by: cyg0x7 at gmail dot com Summary: COMPersistHelper::SaveToFile can save to wrong location -Status: Verified +Status: Closed Type: Bug Package: COM related Operating System: windows PHP Version: 5.4.23 Assigned To: cmb Block user comment: N Private report: N New Comment: Automatic comment on behalf of cmbecker69@gmx.de Revision: http://git.php.net/?p=php-src.git;a=commit;h=5e2ea00b1539d6003548f7698ece1f737c14fb51 Log: Fix #66322: COMPersistHelper::SaveToFile can save to wrong location Previous Comments: ------------------------------------------------------------------------ [2020-02-06 13:51:14] cmb@php.net Well, safe_mode is removed as of PHP 5.4.0, so a bypass is not possible, and I don't see another way how this typo could be exploited, so I'm re-categorizing as bug. ------------------------------------------------------------------------ [2013-12-19 08:10:33] cyg0x7 at gmail dot com sr,it was COM related. ------------------------------------------------------------------------ [2013-12-19 07:30:08] cyg0x7 at gmail dot com Description: ------------ The problem exist in function COMPersistHelper::SaveToFile which check fullpath, but call php_com_string_to_olestring with filename from args and fullpath's length. Because fullpath's length may less than filename's length, with '/../' skill, it's safe-mode bypass. =====ext/com_persist.c================================ CPH_METHOD(SaveToFile) { HRESULT res; char *filename, *fullpath = NULL; int filename_len; zend_bool remember = TRUE; OLECHAR *olefilename = NULL; CPH_FETCH(); CPH_NO_OBJ(); res = get_persist_file(helper); if (helper->ipf) { if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p!|b", &filename, &filename_len, &remember)) { php_com_throw_exception(E_INVALIDARG, "Invalid arguments" TSRMLS_CC); return; } if (filename) { fullpath = expand_filepath(filename, NULL TSRMLS_CC); if (!fullpath) { RETURN_FALSE; } if (php_check_open_basedir(fullpath TSRMLS_CC)) { efree(fullpath); RETURN_FALSE; } olefilename = php_com_string_to_olestring(filename, strlen(fullpath), helper->codepage TSRMLS_CC); efree(fullpath); } res = IPersistFile_Save(helper->ipf, olefilename, remember); if (SUCCEEDED(res)) { if (!olefilename) { res = IPersistFile_GetCurFile(helper->ipf, &olefilename); if (S_OK == res) { IPersistFile_SaveCompleted(helper->ipf, olefilename); CoTaskMemFree(olefilename); olefilename = NULL; } } else if (remember) { IPersistFile_SaveCompleted(helper->ipf, olefilename); } } if (olefilename) { efree(olefilename); } if (FAILED(res)) { php_com_throw_exception(res, NULL TSRMLS_CC); } } else { php_com_throw_exception(res, NULL TSRMLS_CC); } } Test script: --------------- the file path like this(have not been verified): c:/windows/../../../boot.ini/../../../../../../webphp/AAAAAA.php ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=66322&edit=1

« previous php.bugs (#225389) next »