|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2013-12-19 08:10 UTC] cyg0x7 at gmail dot com
-Package: Systems problem
+Package: COM related
[2013-12-19 08:10 UTC] cyg0x7 at gmail dot com
[2020-02-06 13:51 UTC] cmb@php.net
-Summary: COMPersistHelper::SaveToFile safe-mode bypass
+Summary: COMPersistHelper::SaveToFile can save to
wrong location
-Status: Open
+Status: Verified
-Type: Security
+Type: Bug
-Assigned To:
+Assigned To: cmb
[2020-02-06 13:51 UTC] cmb@php.net
[2020-02-06 14:02 UTC] cmb@php.net
[2020-02-06 14:02 UTC] cmb@php.net
-Status: Verified
+Status: Closed
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 14:00:01 2025 UTC |
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