<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marius Podar</title>
    <description>The latest articles on DEV Community by Marius Podar (@marius_podar).</description>
    <link>https://dev.to/marius_podar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4210083%2Fa84ab676-dccb-407f-92ca-b56aa2392831.jpg</url>
      <title>DEV Community: Marius Podar</title>
      <link>https://dev.to/marius_podar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marius_podar"/>
    <language>en</language>
    <item>
      <title>PHP RCE vulnerabilities CVE-2026-109618 and CVE-2026-109619: what to check and how to update</title>
      <dc:creator>Marius Podar</dc:creator>
      <pubDate>Tue, 27 Oct 2026 07:56:02 +0000</pubDate>
      <link>https://dev.to/marius_podar/php-rce-vulnerabilities-cve-2026-109618-and-cve-2026-109619-what-to-check-and-how-to-update-59mm</link>
      <guid>https://dev.to/marius_podar/php-rce-vulnerabilities-cve-2026-109618-and-cve-2026-109619-what-to-check-and-how-to-update-59mm</guid>
      <description>&lt;p&gt;On 21 October 2026 the PHP project released PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 to fix two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619. Both can lead to unauthenticated remote code execution. They carry a CVSS v4.0 score of 9.2 (Critical) from the PHP Group, with attack complexity listed as High, and CISA added both to its Known Exploited Vulnerabilities catalog on 26 October 2026. The advisories do not state whether exploit code is publicly available.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was found
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-109618 (RCE via OOM corruption).&lt;/strong&gt; PHP uses &lt;code&gt;longjmp()&lt;/code&gt; to abort a request when it runs out of memory. If that happens while internal request data is only partly initialized, the cleanup at the end of the request can treat invalid data as valid. The advisory lists several ways to exhaust memory with a multipart request that still looks within PHP's limits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-109619 (RCE via stale global state).&lt;/strong&gt; Some internal state points to memory owned by a single request. If a fatal error, such as a timeout, interrupts the request before that state is reset, a later request handled by the same worker can read freed memory (a use-after-free). The attack needs two requests: one leaves the stale state and the next uses it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is affected
&lt;/h2&gt;

&lt;p&gt;Every release before 8.5.12, 8.4.27, 8.3.36 and 8.2.35 in their branches. According to the PHP announcement, any installation serving web requests is in scope: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The project considers the risk highest for mod_php, where an unauthenticated attack has been demonstrated that runs before any application code. For CVE-2026-109618 a complete FPM exploit has not been demonstrated, while for CVE-2026-109619 the advisory reports a validated attack against both mod_php and FPM.&lt;/p&gt;

&lt;p&gt;PHP 8.1 and older no longer receive project updates. The security team prepared minimal source backports for 7.4, 8.0 and 8.1, and some distributions and LTS vendors provide their own fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check your PHP version
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php &lt;span class="nt"&gt;-v&lt;/span&gt;
php-fpm &lt;span class="nt"&gt;-v&lt;/span&gt;   &lt;span class="c"&gt;# the binary name varies: php-fpm8.3, php83-fpm...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command-line binary can differ from the one serving your site. To see the web version, use a temporary page that prints it, and delete it afterwards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="kc"&gt;PHP_VERSION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If PHP comes from a distribution or LTS vendor, check their advisory for the fixed package: a backported fix does not always change the version number.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to update
&lt;/h2&gt;

&lt;p&gt;Update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or a later release of the same branch. Source and Windows binaries are on php.net; on Linux, use your distribution's updates. Then restart every PHP worker (the FPM service, or Apache with mod_php). Both advisories say that updating is the only complete mitigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you cannot update today
&lt;/h2&gt;

&lt;p&gt;These measures only reduce exposure to specific attack paths; they do not make an installation safe. The same checklist is in my &lt;a href="https://todoseaprende.com/2026/10/21/php-vulnerabilidades-rce-cve-2026-109618-109619/" rel="noopener noreferrer"&gt;original article in Spanish&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For CVE-2026-109618:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;memory_limit=-1&lt;/code&gt; administratively, so the application cannot change it. It removes the controllable limit used by the confirmed attack, but it is not complete.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;post_max_size&lt;/code&gt; to 8M if the application needs no uploads, or 32M if it does, and keep &lt;code&gt;upload_max_filesize&lt;/code&gt; below it.&lt;/li&gt;
&lt;li&gt;Enforce limits at the web server or proxy for decoded request size, fields, multipart parts, headers and nesting depth, including requests without a usable &lt;code&gt;Content-Length&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use a container or cgroup limit as an availability boundary. Do not use &lt;code&gt;RLIMIT_AS&lt;/code&gt; or &lt;code&gt;RLIMIT_DATA&lt;/code&gt;: they can trigger the vulnerable failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For CVE-2026-109619:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;session.upload_progress.enabled=0&lt;/code&gt; in &lt;code&gt;php.ini&lt;/code&gt;, the FPM pool or the server configuration, and restart every worker. Do not rely on &lt;code&gt;ini_set()&lt;/code&gt; or FPM's &lt;code&gt;.user.ini&lt;/code&gt;. It does not cover other variants.&lt;/li&gt;
&lt;li&gt;On PHP 8.5, set &lt;code&gt;fatal_error_backtraces=0&lt;/code&gt; and restart.&lt;/li&gt;
&lt;li&gt;Remove invalid or deprecated settings applied per request that emit warnings before initialization. Hiding warnings with &lt;code&gt;error_reporting&lt;/code&gt;, &lt;code&gt;display_errors&lt;/code&gt; or &lt;code&gt;@&lt;/code&gt; does not help.&lt;/li&gt;
&lt;li&gt;Fix fatal errors and timeouts that an attacker can trigger.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On 23 October the project also recommended &lt;code&gt;session.upload_progress.enabled=0&lt;/code&gt; until the next bugfix release, for a separate and unlikely vector (CVE-2026-115560).&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;PHP announcement&lt;/a&gt;, &lt;a href="https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w" rel="noopener noreferrer"&gt;GHSA-w8hw-w9fx-j79w&lt;/a&gt;, &lt;a href="https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp" rel="noopener noreferrer"&gt;GHSA-6wmf-4rv5-p3rp&lt;/a&gt;, &lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-109618" rel="noopener noreferrer"&gt;NVD CVE-2026-109618&lt;/a&gt;, &lt;a href="https://nvd.nist.gov/vuln/detail/CVE-2026-109619" rel="noopener noreferrer"&gt;NVD CVE-2026-109619&lt;/a&gt; and the &lt;a href="https://www.cisa.gov/known-exploited-vulnerabilities-catalog" rel="noopener noreferrer"&gt;CISA KEV catalog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I wrote a more detailed version in Spanish here: &lt;a href="https://todoseaprende.com/2026/10/21/php-vulnerabilidades-rce-cve-2026-109618-109619/" rel="noopener noreferrer"&gt;PHP: vulnerabilidades críticas RCE (CVE-2026-109618 y 109619)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>security</category>
      <category>webdev</category>
      <category>news</category>
    </item>
    <item>
      <title>CSRF en PHP: qué es y cómo prevenirlo con un token (guía rápida)</title>
      <dc:creator>Marius Podar</dc:creator>
      <pubDate>Tue, 27 Oct 2026 06:34:04 +0000</pubDate>
      <link>https://dev.to/marius_podar/csrf-en-php-que-es-y-como-prevenirlo-con-un-token-guia-rapida-523i</link>
      <guid>https://dev.to/marius_podar/csrf-en-php-que-es-y-como-prevenirlo-con-un-token-guia-rapida-523i</guid>
      <description>&lt;p&gt;El CSRF (&lt;em&gt;Cross-Site Request Forgery&lt;/em&gt;) es una de las tres vulnerabilidades web clásicas, junto al SQL Injection y el XSS. Y tiene una particularidad: no necesita robar ninguna contraseña. Le basta con que la víctima ya tenga una sesión abierta en tu aplicación.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo funciona el ataque
&lt;/h2&gt;

&lt;p&gt;Cuando un usuario inicia sesión, el navegador guarda una cookie de sesión y la envía automáticamente en cada petición a ese dominio, sin importar desde qué página se origine. Un atacante puede aprovecharlo con una página (o un email, o un anuncio) que lance una petición a tu sitio. Si tu aplicación solo comprueba que hay sesión, la ejecutará como si la hubiera hecho el propio usuario.&lt;/p&gt;

&lt;p&gt;Imagina un formulario para cambiar el email de la cuenta que solo comprueba &lt;code&gt;$_SESSION['user_id']&lt;/code&gt;. El atacante monta una página externa con un formulario oculto que apunta a tu endpoint y se envía solo con JavaScript. Si la víctima la visita estando logueada, su email cambia sin que se entere. Desde ahí, al atacante le basta con pedir un «olvidé mi contraseña» para quedarse con la cuenta.&lt;/p&gt;

&lt;h2&gt;
  
  
  La defensa principal: un token CSRF
&lt;/h2&gt;

&lt;p&gt;La defensa estándar, recomendada por OWASP, es un token aleatorio generado por el servidor, que viaja en cada formulario y se valida al recibir la petición. El atacante no puede conocerlo ni adivinarlo, así que no puede incluirlo en su formulario falso.&lt;/p&gt;

&lt;p&gt;Genera el token y guárdalo en sesión:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;session_start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_SESSION&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'csrf_token'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$_SESSION&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'csrf_token'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;bin2hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;random_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inclúyelo en el formulario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"csrf_token"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;?= $_SESSION['csrf_token'] ?&amp;gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y valídalo antes de procesar nada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'csrf_token'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_SESSION&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'csrf_token'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;hash_equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_SESSION&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'csrf_token'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'csrf_token'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;http_response_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Petición no válida.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dos detalles importantes: usa &lt;code&gt;random_bytes()&lt;/code&gt; (nunca &lt;code&gt;rand()&lt;/code&gt; ni &lt;code&gt;uniqid()&lt;/code&gt;) y compara con &lt;code&gt;hash_equals()&lt;/code&gt; en lugar de &lt;code&gt;==&lt;/code&gt;, para evitar &lt;em&gt;timing attacks&lt;/em&gt;. En acciones muy sensibles, como cambiar la contraseña, invalida el token después de usarlo con &lt;code&gt;unset($_SESSION['csrf_token'])&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capas adicionales
&lt;/h2&gt;

&lt;p&gt;El token es la defensa principal, pero conviene combinarlo con:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cookies SameSite&lt;/strong&gt;: con &lt;code&gt;SameSite=Lax&lt;/code&gt; o &lt;code&gt;Strict&lt;/code&gt;, el navegador no envía la cookie de sesión en peticiones que vienen de otros dominios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comprobar &lt;code&gt;Origin&lt;/code&gt; o &lt;code&gt;Referer&lt;/code&gt;&lt;/strong&gt;: solo como capa extra, nunca como única defensa, porque pueden faltar en casos legítimos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usar POST, nunca GET, para acciones que modifican datos&lt;/strong&gt;: un enlace GET se explota con un simple &lt;code&gt;&amp;lt;img src="..."&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS en todo el sitio&lt;/strong&gt;, para que las cookies &lt;code&gt;secure&lt;/code&gt; se envíen siempre.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si usas un framework como Laravel o Symfony, ya trae protección CSRF integrada: actívala y no la desactives «para simplificar».&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Con un token aleatorio, &lt;code&gt;hash_equals()&lt;/code&gt; y cookies SameSite cubres la gran mayoría de los casos reales de CSRF en PHP, sin librerías complicadas.&lt;/p&gt;

&lt;p&gt;Si quieres el ejemplo completo y la explicación detallada, está en el &lt;a href="https://todoseaprende.com/2026/08/21/csrf-y-como-prevenirlo-en-php/" rel="noopener noreferrer"&gt;artículo original en Todo se Aprende&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>php</category>
      <category>security</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
