Nerijus Kislauskas rašė: > On 03/23/2012 11:42 AM, Laimis wrote: >> Reikia skaityti ir nagrinėti. > > Na, paskaičiau, pasinagrinėjau ir mano apibendrinimas būtų toks: > > allow_url_include (priklausantis nuo allow_url_fopen) yra mechanizmas > reguliuoti funkcijų include(), include_once(), require(), require_once() > veikimą. Jei nori includinti/requirinti iš URL, turi dar suhosin > blacklist/whitelist mechanizmą kaip apsaugą. Iš tikrųjų yra taip: include/require kviečia (trasa): zend_stream_open() ...-> php_stream_open_for_zend() -> php_stream_open_for_zend_ex() -> php_stream_open_wrapper() == _php_stream_open_wrapper_ex() -> php_stream_locate_url_wrapper() Tuo tarpu fopen() ir kt. funkcijos atbėga iki php_stream_locate_url_wrapper() savarankiškai (ne per zend_stream_open()) Būtent php_stream_locate_url_wrapper() (streams.c) funkcijoje ir yra tikrinama allow_url_fopen bei allow_url_include: if (wrapperpp && (*wrapperpp)->is_url && (options & STREAM_DISABLE_URL_PROTECTION) == 0 && (!PG(allow_url_fopen) || (((options & STREAM_OPEN_FOR_INCLUDE) || PG(in_user_include)) && !PG(allow_url_include)))) { if (options & REPORT_ERRORS) { /* protocol[n] probably isn't '\0' */ char *protocol_dup = estrndup(protocol, n); if (!PG(allow_url_fopen)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_fopen=0", protocol_dup); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_include=0", protocol_dup); } efree(protocol_dup); } return NULL; } suhosin'as įsiterpia į zend_stream_open() todėl include/require galioja papildoma apsauga, tačiau tai neįtakoja fopen() ir kt. funkcijų, kurios kviečia php_stream_locate_url_wrapper(). Išeitis yra pasiredaguoti pačiam streams.c arba, — turbūt būtų paprasčiau, — pasinaudoti jau minėto suhosin'o tėvo Hardening-Patch: http://www.hardened-php.net/hardening_patch.14.html funkcija php_is_valid_include() (ir susijusiu kodu), kuri realizuoja whitelist'ą/blacklist'ą ir kuri būtų kviečiama iš php_stream_locate_url_wrapper(). Gal kiek bjauresnė užduotis/problema — atsirankioti susijusį kodą iš įvairių patch'intų failų/vietų, tačiau neturėtų būti labai sunku. Kita vertus, dar paprasčiau būtų modifikuoti patį suhosin'ą (kartu su php:streams.c) ir pasinaudoti execute.c:suhosin_check_filename(), kuri būtų kviečiama iš php_stream_locate_url_wrapper(). > Kažkaip sunku patikėti, kad PHP kūrėjai nepagalvojo, kad fopen() gali > naudotis tiek geriečiai, tiek blogiečiai, ir kad administratoriams yra > būtinybė skirstyti URL į gerus ir blogus. Suhosin bent jau galėjo apie > tai pagalvoti. Tai tada PHP kūrėjai „nepagalvojo“, kad bet kokia tinklinė komunikacija yra blogis... Ar pakiši cutom url'ą fopen(), ar ip socket'ui, ar bet kokiai kitai tinklinei funkcijai. Uždrausti viską? fopen() juk gauna duomenis ir pagal visą gerąją (saugumo ir apskritai) praktiką yra kvaila ir/ar griežtai nerekomenduojama to turinio interpretuoti kaip kodo (eval). Suhosin apie tai pagalvojo, nes įvedė apsaugą (na, whitelist'us/blacklist'us, nes pagal viską turbūt daugumoje konfigūracijų allow_url_fopen/allow_url_include = 0) include/require su ta mintim, kad gali egzistuoti patikimi host'ai, iš kurių būtų galima include'inti. Tačiau tai blankiai galioja fopen() ir alike, nes tuomet balcklist'us/whitelist'us reikėtų iš esmės kurti visoms tinklinėms komunikacijoms.