Ironia-alerta! PHP soluciona la fallada de seguretat en el codi de validació d’entrada: Naked Security

Si utilitzeu PHP a la vostra xarxa, comproveu que esteu utilitzant la versió més recent, actualment 8.1.3.

estrenat ahir [2022-02-17]aquesta versió corregeix diversos errors de gestió incorrecta de la memòria, inclosos CVE-2021-21708que és una errada sense ús després d’una funció anomenada php_filter_float().

(Les versions 8.0 i 7.4 encara són compatibles i també són vulnerables; si no feu servir l’última versió 8.1 de PHP, necessiteu 8.0.16 i 7.4.28 respectivament.)

Un exploit de prova de concepte basat en l’ús de PHP per consultar una base de dades mostra que l’error es pot utilitzar per bloquejar el procés PHP, de manera que ja se sap que un atac de denegació de servei (DoS) funciona.

Per descomptat, com Mozilla li agrada assenyalar de manera rutinària i inquebrantable a les seves actualitzacions periòdiques, quan es corregeixen errors que mostren proves de corrupció de memòria, hauríeu de “Suposem que amb prou esforç alguns [them] podria haver estat explotat per executar codi arbitrari”.

L’execució de codi remota (RCE), on les dades enviades des de l’exterior no només poden bloquejar un programa a l’ordinador, sinó que també poden controlar-lo durant el procés, normalment condueixen a una intrusió de la xarxa, l’exfiltració de dades, la implantació de programari maliciós o un còctel de mal gust. tots ells.

Codi de validació no vàlid

Irònicament, les funcions de filtre de PHP estan dissenyades per validar les dades entrants, per exemple per assegurar-vos que si espereu que algú us enviï un nombre enter (per exemple, 5, 7, 11), no us hagi enviat una cadena de text que pugui No es pot convertir de manera fiable a un nombre sencer, com ara 3.14159 or 3/16 inch.

L’error CVE-2021-21708 forma part del codi que verifica si hi ha nombres flotants vàlids o números de coma flotant, un terme argot per al que probablement a l’escola anomeneu “nombres reals” o “decimals”.

Els decimals solen tenir un punt (o una coma, segons el vostre país) que separa la part sencera i la part fraccionària, com en 2.5 representar dos i cinc dècimes, o dos i mig.

Les funcions de filtre numèric de PHP us permeten comprovar no només que el número entrant sigui vàlid, sinó també que estigui dins d’un interval especificat, com ara assegurar-vos que no sigui superior a 2,71828 o que estigui entre -1 i 1.

Si el número que entra ja és un nombre de coma flotant (un decimal), el codi segueix com es mostra a continuació, on el codi PHP antic (8.1.2) es troba a l’esquerra i el codi nou (8.1.3) està activat. el dret. (Aquí no hi ha cap error, de manera que les dues versions són idèntiques.)

No et preocupis si no coneixes C; el més important a tenir en compte és que la comprovació d’errors es fa primer, seguida d’una línia que allibera la memòria que utilitza PHP actualment per emmagatzemar el número, seguida immediatament d’una línia que reassigna la memòria perquè l’utilitzi PHP.

Per si us ho pregunteu, el nom curiós zval_ptr_dtor() és abreviatura de Destructor de punters de memòria interna PHP:

Esquerra. PHP 8.1.2. Dret. PHP 8.1.3.
Ambdós costats segueixen l’enfocament “Mira, entra a la carretera, creua”.

Si el nombre apareix com un nombre enter, sense part decimal, s’utilitza un codi lleugerament diferent.

A continuació, com podeu veure, la seqüència de “feu la comprovació i sortiu si falla; però si està bé, desassigneu i reassigneu l’emmagatzematge per al número” es va barrejar a la versió antiga.

La seqüència era “desassignar la memòria utilitzada per aquest valor de PHP, després fer la comprovació i sortir si falla, deixant enrere un objecte PHP que es refereix a la memòria que aviat s’assignarà a una altra cosa i, per tant, més tard provocarà un ús després de l’ús lliure. conflicte; però si la comprovació està bé, torneu a assignar un nou emmagatzematge per al número.

Això és una mica com entrar primer a la carretera, i només després comprovar si és segur i completar la travessa.

El codi actualitzat a la versió 8.1.3 ha restaurat el codi a una seqüència més segura, tot i que encara seria més segur si hi hagués una única funció anomenada, per exemple, dtor_and_alloc_in_one_go()de manera que els futurs programadors no poguessin tornar a inserir el codi accidentalment entre la trucada al destructor i la trucada a l’assignador.

El nou codi és més com comprovar primer que la carretera és segura, després entrar-hi i caminar directament a l’altre costat.

La vista “diff” (argot per a codi de diferència) creat per Visual Studio Code mostra clarament com la línia marcada en vermell a la versió 8.1.2 es va moure cap avall al punt verd a la versió 8.1.3:

Esquerra. PHP 8.1.2. ‘Entra al camí, mira, creua’.
Dret. PHP 8.1.3. ‘Mira, entra al camí, creua’.

Què fer?

  • Si sou usuari de PHPactualitzar a 8.1.3. Si encara no heu passat a la versió 8.1 de PHP, encara s’admeten altres dues branques anteriors: la 8.0 necessita una actualització a 8.0.16i 7.4 s’ha d’actualitzar a 7.4.28. Si utilitzeu una distribució de Linux que gestiona PHP per a vosaltres, comproveu-ne els detalls.
  • Si ets programadorrecordeu que el codi escrit en C requereix que tingueu cura de la memòria tot el temps, i a tot arreu, perquè errors ben amagats com aquest no s’arrossin desapercebuts.
  • Si ets programadorintenteu escriure el vostre codi per reduir el nombre de maneres en què els programadors que us persegueixen poden introduir errors.

.

Leave a Comment

Your email address will not be published. Required fields are marked *