<?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: Igor</title>
    <description>The latest articles on DEV Community by Igor (@colaweb).</description>
    <link>https://dev.to/colaweb</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%2F4215235%2F8adbca44-e5fd-4bd0-9eb6-7dd5735abc11.jpeg</url>
      <title>DEV Community: Igor</title>
      <link>https://dev.to/colaweb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/colaweb"/>
    <language>en</language>
    <item>
      <title>How to Embed a PDF on a Website: HTML, iframe and Flipbooks</title>
      <dc:creator>Igor</dc:creator>
      <pubDate>Sat, 31 Oct 2026 11:53:17 +0000</pubDate>
      <link>https://dev.to/colaweb/how-to-embed-a-pdf-on-a-website-html-iframe-and-flipbooks-h0e</link>
      <guid>https://dev.to/colaweb/how-to-embed-a-pdf-on-a-website-html-iframe-and-flipbooks-h0e</guid>
      <description>&lt;p&gt;To embed a PDF on a website, point an iframe at the file's URL and give it a height. Keep a separate link below it so visitors can open the document outside the embedded viewer.&lt;/p&gt;

&lt;p&gt;For a product catalog, also check the pages with small print and decide how you will replace the file when prices change. Those details usually matter more than the embed code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: This article was prepared for WebViewPDF. The hosted example uses its public demo catalog.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Embed a PDF in HTML with an iframe
&lt;/h2&gt;

&lt;p&gt;Upload your PDF to your website, then use its URL as the iframe source:&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;iframe&lt;/span&gt;
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pdf-viewer"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/files/catalog.pdf"&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Product catalog"&lt;/span&gt;
  &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/files/catalog.pdf"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open the PDF separately&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the dimensions in CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pdf-viewer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;28rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;75vh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;56rem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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;Replace &lt;code&gt;/files/catalog.pdf&lt;/code&gt; with your file's address. This relative path assumes the PDF is hosted on the same website.&lt;/p&gt;

&lt;p&gt;The title labels the frame for assistive technology. The height gives the document room to display; &lt;code&gt;width: 100%&lt;/code&gt; fits the frame to its container. Lazy loading is useful below the fold. Remove it if the PDF is the first thing visitors should see.&lt;/p&gt;

&lt;p&gt;The browser supplies the PDF controls. Their appearance and behavior can vary, so keep the separate link even if the embed works in your browser.&lt;/p&gt;

&lt;p&gt;You can use this without a paid viewer or CMS plugin. You still need somewhere to host the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use object for fallback content
&lt;/h2&gt;

&lt;p&gt;An object element lets you put a link inside the embed as fallback HTML:&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;object&lt;/span&gt;
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pdf-viewer"&lt;/span&gt;
  &lt;span class="na"&gt;data=&lt;/span&gt;&lt;span class="s"&gt;"/files/catalog.pdf"&lt;/span&gt;
  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/pdf"&lt;/span&gt;
  &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Product catalog"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    The embedded preview is unavailable.
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/files/catalog.pdf"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open the PDF&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;.
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/object&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/files/catalog.pdf"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open the PDF separately&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the same CSS. The link outside the object remains available if a browser fails to show the fallback properly.&lt;/p&gt;

&lt;p&gt;For an occasional brochure or form, native embedding may be all you need. A recurring catalog can need more: search across pages, reading statistics, or a new edition behind the existing link.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embed a catalog with a hosted flipbook
&lt;/h2&gt;

&lt;p&gt;With a hosted flipbook, the iframe points to a reader page instead of the raw PDF. The provider handles document processing and the viewer interface; you depend on its service and plan limits.&lt;/p&gt;

&lt;p&gt;Here is the &lt;strong&gt;Quiet Form&lt;/strong&gt; demo embedded on the WebViewPDF homepage:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyyh6j4qbnnsg6nflu4zb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyyh6j4qbnnsg6nflu4zb.jpg" alt="Quiet Form PDF catalog embedded in a website with page navigation and zoom controls" width="800" height="716"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The embedded catalog, open at pages 2–3.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://webviewpdf.com/demo" rel="noopener noreferrer"&gt;Open the live catalog demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reader URL can be used in an iframe:&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;iframe&lt;/span&gt;
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pdf-viewer"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://read.webviewpdf.com/v/01a1309f-80ea-711e-aa47-62a7270af7fb"&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Quiet Form — Furniture &amp;amp; Design Collection"&lt;/span&gt;
  &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt;
  &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://read.webviewpdf.com/v/01a1309f-80ea-711e-aa47-62a7270af7fb"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Open the catalog separately
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reuse the &lt;code&gt;.pdf-viewer&lt;/code&gt; CSS above. This address opens the public demo. To display your own catalog, upload your PDF, wait for processing, and copy the embed code or reader URL for that publication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukf3skqmzuh5egn6ebiz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukf3skqmzuh5egn6ebiz.jpg" alt="A product spread in the hosted PDF catalog, with specifications and viewer controls" width="799" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pages 6–7 opened in the separate reader: the sofa on the left, dimensions and finishes on the right.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Two details are worth checking with your own document:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search needs text.&lt;/strong&gt; In the demo, searching for “sofa” returns matching pages. Selecting page 6 opens the product spread shown above. WebViewPDF's search requires a PDF text layer; a scan needs OCR before upload.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbj7zaxqwpj5vbc3h5grm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbj7zaxqwpj5vbc3h5grm.jpg" alt="Searching for sofa in the live catalog returns matching pages and opens the selected product" width="800" height="716"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The actual search results for “sofa”, with page 6 selected.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updates should preserve the publication.&lt;/strong&gt; In WebViewPDF, upload a new version of the existing publication to retain its reader link and embed code. Creating a new publication is a separate operation. For a printed QR code or a catalog embedded on several sites, keeping that address matters.&lt;/p&gt;

&lt;p&gt;If you need to build custom application controls yourself, a JavaScript viewer such as PDF.js is another route. You then maintain that integration rather than relying on a hosted reader.&lt;/p&gt;

&lt;h2&gt;
  
  
  When an embedded PDF does not display
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Blank frame
&lt;/h3&gt;

&lt;p&gt;First, open the PDF or reader URL in a private browser window. Check that it opens without your administrator login and does not return a 404 or an HTML error page.&lt;/p&gt;

&lt;p&gt;If it works directly but fails in the iframe, check the browser console. The embedded page may restrict framing through &lt;code&gt;Content-Security-Policy: frame-ancestors&lt;/code&gt; or &lt;code&gt;X-Frame-Options&lt;/code&gt;. Your own page's CSP may also block the frame origin. Follow the supported embedding configuration for the server or provider involved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download instead of preview
&lt;/h3&gt;

&lt;p&gt;Inspect the response headers. &lt;code&gt;Content-Disposition: attachment&lt;/code&gt; requests a download. Browser settings and PDF support also affect the result; changing the iframe markup may not fix it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Works on desktop, fails on mobile
&lt;/h3&gt;

&lt;p&gt;Some mobile browsers handle raw PDF embeds differently. Keep the separate link and test another viewer if inline reading is essential.&lt;/p&gt;

&lt;p&gt;Also distinguish a blank viewer from an unreadable document. A frame that fits the screen does not reflow a PDF. Open a page with small specifications on a real phone and check zooming, scrolling and text size.&lt;/p&gt;

&lt;h3&gt;
  
  
  The CMS removes the code
&lt;/h3&gt;

&lt;p&gt;Some editors and hosting plans strip iframe or script markup. Use the platform's supported HTML or embed block, then check the saved page. Support for iframes does not necessarily include permission to run an external script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you put it on a client site
&lt;/h2&gt;

&lt;p&gt;Open the finished page while signed out. Try a desktop browser and a real phone, follow a link inside the document, and check keyboard navigation and the separate PDF link. For catalogs, search for an actual product name or part number.&lt;/p&gt;

&lt;p&gt;If the document will be updated regularly, replace it once and reopen the original page. That is the easiest time to catch a workflow that generates a new URL for every edition.&lt;/p&gt;

&lt;p&gt;Embedding is not copy protection: hiding a download button does not secure a public PDF. It also does not put the PDF's text into the surrounding HTML. Keep essential product descriptions and navigation on the webpage when readers need them there.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/iframe" rel="noopener noreferrer"&gt;MDN: iframe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/object" rel="noopener noreferrer"&gt;MDN: object&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/frame-ancestors" rel="noopener noreferrer"&gt;MDN: CSP frame-ancestors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Disposition" rel="noopener noreferrer"&gt;MDN: Content-Disposition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webviewpdf.com/features" rel="noopener noreferrer"&gt;WebViewPDF: publishing and viewer features&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>pdf</category>
      <category>flipbooks</category>
    </item>
    <item>
      <title>TensorRT Was Fast. My 1080p RTSP Pipeline Wasn't.</title>
      <dc:creator>Igor</dc:creator>
      <pubDate>Fri, 30 Oct 2026 10:48:25 +0000</pubDate>
      <link>https://dev.to/colaweb/tensorrt-was-fast-my-1080p-rtsp-pipeline-wasnt-11df</link>
      <guid>https://dev.to/colaweb/tensorrt-was-fast-my-1080p-rtsp-pipeline-wasnt-11df</guid>
      <description>&lt;p&gt;I was troubleshooting low FPS in a TensorRT-based RTSP video analytics pipeline on a customer's server. The input was a 1920×1080 stream at 25 FPS, running on an NVIDIA GeForce RTX 5070 Ti. The pose model already used TensorRT, but the application was processing only &lt;strong&gt;8–10 FPS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Inference was accelerated. The video pipeline wasn't.&lt;/p&gt;

&lt;p&gt;After changing how frames moved through the application, I measured &lt;strong&gt;24.64 processed FPS&lt;/strong&gt; against the same 25 FPS source. That measurement was taken &lt;strong&gt;before the OCR queue&lt;/strong&gt;; it was not a benchmark of end-to-end OCR or video delivery latency.&lt;/p&gt;

&lt;p&gt;I didn't replace the pose model. I changed the data path around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why My RTSP + TensorRT Pipeline Was Stuck at 8–10 FPS
&lt;/h2&gt;

&lt;p&gt;The application did more than pose detection. It decoded RTSP video, detected and tracked people, extracted torso regions for OCR, checked safety-related events, and generated an RTSP output stream.&lt;/p&gt;

&lt;p&gt;The original path was roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RTSP → OpenCV/FFmpeg → CPU frame
     → GPU inference → CPU-side processing
     → OCR → output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TensorRT engine could execute on the GPU, but full frames still crossed the CPU/GPU boundary too often. Optimizing inference alone wasn't going to solve that.&lt;/p&gt;

&lt;p&gt;A 1920×1080 RGB frame contains 6,220,800 bytes, or about &lt;strong&gt;6.2 MB&lt;/strong&gt;. One full-frame transfer at 25 FPS amounts to approximately &lt;strong&gt;156 MB/s of image payload&lt;/strong&gt; in one direction. This is a size calculation, not a measured PCIe bandwidth figure from the server.&lt;/p&gt;

&lt;p&gt;Bandwidth wasn't the only concern. Intermediate buffers, format conversions, and synchronization can also add time. I needed to examine the frame's route through the application, not just the model's execution time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizing the RTSP GPU Pipeline with NVDEC and CUDA
&lt;/h2&gt;

&lt;p&gt;The revised path was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RTSP
  ↓
PyNvVideoCodec / NVDEC
  ↓
CUDA-resident frame
  ↓
GPU resize, letterbox, normalization
  ↓
Direct TensorRT inference
  ↓
GPU postprocessing and coordinate mapping
  ↓
Small metadata transfer for CPU tracking
  ↓
GPU torso ROI extraction
  ↓
OCR queue
  ↓
Downstream processing / RTSP output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Decode directly into GPU-accessible memory
&lt;/h3&gt;

&lt;p&gt;I switched the decoding path to &lt;strong&gt;PyNvVideoCodec / NVDEC&lt;/strong&gt;. This allowed decoded frames to remain in GPU-accessible memory instead of becoming CPU images that would then need to be uploaded for inference.&lt;/p&gt;

&lt;p&gt;NVDEC doesn't make an entire application zero-copy by itself. The formats and buffers used by the next stages still matter. The useful change here was removing an unnecessary full-frame detour through host memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep preprocessing on the GPU
&lt;/h3&gt;

&lt;p&gt;Resize, letterboxing, and normalization ran on the GPU. That let the pipeline prepare TensorRT input without routinely copying the full-resolution frame back to the CPU.&lt;/p&gt;

&lt;p&gt;These operations aren't necessarily expensive individually. The problem is what happens when each stage creates another buffer or forces a transfer before the next stage can run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use direct TensorRT execution
&lt;/h3&gt;

&lt;p&gt;I replaced the higher-level inference path with direct TensorRT execution using &lt;code&gt;execute_async_v3()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That gave me explicit control over device buffers and execution. It wasn't the function name that made the pipeline faster: memory layout, buffer lifetime, and synchronization still had to be handled correctly. The benefit was being able to avoid work that the earlier path performed around inference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transfer tracking metadata, not full frames
&lt;/h3&gt;

&lt;p&gt;The pose model returned person bounding boxes and &lt;strong&gt;17 body keypoints&lt;/strong&gt;. Postprocessing and coordinate mapping stayed on the GPU.&lt;/p&gt;

&lt;p&gt;Tracking still used CPU-side information, but only compact detection metadata needed to cross to the CPU. Sending an entire 1080p frame just to update tracking coordinates would have defeated much of the optimization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prepare OCR regions on the GPU
&lt;/h3&gt;

&lt;p&gt;The pose keypoints defined torso regions for OCR. I extracted those ROIs on the GPU rather than copying the complete image to the CPU just to crop it.&lt;/p&gt;

&lt;p&gt;Those ROIs then entered the OCR queue. This boundary matters when interpreting the performance number below.&lt;/p&gt;

&lt;p&gt;I didn't try to move every part of the application to CUDA. I kept large pixel buffers on the GPU and moved smaller data when a CPU-side stage actually needed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark Results: 24.64 FPS on RTX 5070 Ti
&lt;/h2&gt;

&lt;p&gt;The cover image is a frame from the tested pipeline, with tracking IDs and FPS counters overlaid.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Video source&lt;/td&gt;
&lt;td&gt;1920×1080 RTSP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source frame rate&lt;/td&gt;
&lt;td&gt;25 FPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU&lt;/td&gt;
&lt;td&gt;NVIDIA GeForce RTX 5070 Ti&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Before optimization&lt;/td&gt;
&lt;td&gt;8–10 processed FPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After optimization&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;24.64 processed FPS&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output FPS counter&lt;/td&gt;
&lt;td&gt;25.00 FPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Processing measurement boundary&lt;/td&gt;
&lt;td&gt;Before OCR queue&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The overlay showed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PROCESSED: 24.64
OUTPUT:    25.00
SOURCE:    25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compared with the original 8–10 FPS range, &lt;strong&gt;24.64 FPS is about 2.5–3.1× the initial processing throughput&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The distinction between counters is important. The processed-FPS figure was measured up to the OCR queue. The 25 FPS output counter doesn't establish that OCR, safety checks, encoding, and network delivery all finished within 40 ms. Throughput and end-to-end latency are different measurements.&lt;/p&gt;

&lt;p&gt;I also tested this architecture with &lt;strong&gt;four simultaneous camera streams on the same RTX 5070 Ti&lt;/strong&gt;. I'm not publishing per-stream throughput or latency figures for that configuration here, so the 24.64 FPS result should be understood as the single-stream measurement.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Troubleshoot Low FPS in a TensorRT Video Pipeline
&lt;/h2&gt;

&lt;p&gt;If I encountered another RTSP application that wasn't keeping up with the camera, I'd check these boundaries before changing the model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Decoder output:&lt;/strong&gt; Is each decoded frame already GPU-accessible, or is a CPU image being uploaded for inference?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preprocessing:&lt;/strong&gt; Are resize, color conversion, letterboxing, and normalization creating unnecessary host buffers or synchronization points?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference buffers:&lt;/strong&gt; Are input and output tensors already in device memory? Is execution being synchronized more often than necessary?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postprocessing and tracking:&lt;/strong&gt; Does the CPU need the full frame, or only boxes, keypoints, scores, and IDs?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queues and counters:&lt;/strong&gt; Where exactly is FPS measured? Does OCR or another downstream queue grow during a sustained run?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'd also record stage timings and queue depth instead of relying on one FPS counter. A pipeline can appear fast at the inference stage while its end-to-end latency continues to grow.&lt;/p&gt;

&lt;p&gt;For API details, NVIDIA documents &lt;a href="https://docs.nvidia.com/video-technologies/pynvvideocodec/pynvc-api-prog-guide/using_pynvvideocodec_apis.html" rel="noopener noreferrer"&gt;PyNvVideoCodec decoding and interoperability&lt;/a&gt; and &lt;a href="https://docs.nvidia.com/deeplearning/tensorrt/latest/inference-library/python-api-docs.html" rel="noopener noreferrer"&gt;TensorRT asynchronous Python inference&lt;/a&gt;. These are references for implementing similar techniques, not code taken from the customer's deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently Next Time
&lt;/h2&gt;

&lt;p&gt;I'd diagram the entire frame path before spending time tuning inference: every buffer allocation, every CPU-to-GPU or GPU-to-CPU transfer, and every synchronization point.&lt;/p&gt;

&lt;p&gt;In this project, that was where the meaningful improvement came from. A fast TensorRT engine didn't help much while the rest of the pipeline kept moving full-size frames around.&lt;/p&gt;

&lt;p&gt;I shared more context and the original benchmark in &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7494790587561406464/" rel="noopener noreferrer"&gt;my LinkedIn post about this RTSP/TensorRT optimization&lt;/a&gt;. If you've run into a similar bottleneck, I'd be interested to hear whether it was decoding, preprocessing, memory movement, or something else.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Implementation note: I configured and tested this pipeline on a customer's server. The performance figures come from that work. AI assistance was used to draft and edit the English text.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>computervision</category>
      <category>cuda</category>
      <category>gpu</category>
      <category>performance</category>
    </item>
    <item>
      <title>PHP2Shell on Ubuntu: How to Verify and Install the PHP Security Patch</title>
      <dc:creator>Igor</dc:creator>
      <pubDate>Thu, 29 Oct 2026 12:44:30 +0000</pubDate>
      <link>https://dev.to/colaweb/php2shell-on-ubuntu-how-to-verify-and-install-the-php-security-patch-1i59</link>
      <guid>https://dev.to/colaweb/php2shell-on-ubuntu-how-to-verify-and-install-the-php-security-patch-1i59</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz3m6pk398o11kg4ogfdq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz3m6pk398o11kg4ogfdq.png" alt="PHP security advisory from October 21, 2026" width="800" height="952"&gt;&lt;/a&gt;&lt;br&gt;
On October 21, 2026, the PHP security team released emergency fixes for two critical vulnerabilities that could allow &lt;strong&gt;unauthenticated remote code execution (RCE)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The issues, commonly discussed as &lt;strong&gt;PHP2Shell&lt;/strong&gt;, are tracked as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-109618&lt;/strong&gt; — Remote code execution through out-of-memory corruption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026-109619&lt;/strong&gt; — Remote code execution through stale internal request state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you run PHP on an Ubuntu VPS, updating is important. But there's a detail that can easily cause confusion: &lt;strong&gt;an Ubuntu server can have the security fixes installed while &lt;code&gt;php -v&lt;/code&gt; still reports an older upstream version.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, Ubuntu 24.04 can report PHP 8.3.6 even after installing the relevant security patches.&lt;/p&gt;

&lt;p&gt;Here's how to check the actual package revision, identify which PHP runtime serves your website, apply the update, and verify the result.&lt;/p&gt;

&lt;p&gt;This guide uses Ubuntu 24.04 LTS with PHP 8.3-FPM as its main example.&lt;/p&gt;
&lt;h2&gt;
  
  
  What exactly is PHP2Shell?
&lt;/h2&gt;

&lt;p&gt;These vulnerabilities affect the PHP interpreter itself, not just applications built with PHP.&lt;/p&gt;
&lt;h3&gt;
  
  
  CVE-2026-109618: Out-of-memory corruption
&lt;/h3&gt;

&lt;p&gt;PHP can encounter memory allocation failures while handling HTTP requests.&lt;/p&gt;

&lt;p&gt;In affected versions, an out-of-memory condition can interrupt internal request initialization. During cleanup, PHP may subsequently treat partially initialized data as valid.&lt;/p&gt;

&lt;p&gt;Under exploitable conditions, this can lead to memory corruption and remote code execution.&lt;/p&gt;
&lt;h3&gt;
  
  
  CVE-2026-109619: Stale global state
&lt;/h3&gt;

&lt;p&gt;PHP workers can process multiple requests during their lifetime.&lt;/p&gt;

&lt;p&gt;This issue involves internal request-owned state remaining accessible after its underlying memory has been freed.&lt;/p&gt;

&lt;p&gt;A later request handled by the same worker may access stale state before normal initialization resets it.&lt;/p&gt;

&lt;p&gt;That creates another potential remote code execution path.&lt;/p&gt;
&lt;h3&gt;
  
  
  Which environments are affected?
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;official PHP security advisory&lt;/a&gt; identifies web-facing PHP installations, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PHP-FPM with Nginx&lt;/li&gt;
&lt;li&gt;Apache with mod_php&lt;/li&gt;
&lt;li&gt;PHP-CGI&lt;/li&gt;
&lt;li&gt;FrankenPHP&lt;/li&gt;
&lt;li&gt;LiteSpeed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The PHP team considers Apache with mod_php particularly high risk because a demonstrated attack can be triggered before application code executes.&lt;/p&gt;

&lt;p&gt;Updating WordPress, Laravel, Drupal, or another PHP application does not fix these vulnerabilities in the underlying interpreter.&lt;/p&gt;
&lt;h2&gt;
  
  
  Which PHP versions contain the fixes?
&lt;/h2&gt;

&lt;p&gt;On October 21, PHP published the following upstream security releases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PHP branch&lt;/th&gt;
&lt;th&gt;First fixed upstream version&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PHP 8.5&lt;/td&gt;
&lt;td&gt;8.5.12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP 8.4&lt;/td&gt;
&lt;td&gt;8.4.27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP 8.3&lt;/td&gt;
&lt;td&gt;8.3.36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP 8.2&lt;/td&gt;
&lt;td&gt;8.2.35&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;PHP 8.1 and older releases no longer receive regular upstream security updates, although some Linux distributions and long-term-support vendors maintain patched packages.&lt;/p&gt;

&lt;p&gt;Here's the catch for Ubuntu administrators: &lt;strong&gt;upstream PHP version numbers and Ubuntu package revisions are not the same thing.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Ubuntu 24.04 may still show PHP 8.3.6
&lt;/h2&gt;

&lt;p&gt;Canonical frequently backports security fixes into distribution packages instead of replacing the entire PHP version with the latest upstream release.&lt;/p&gt;

&lt;p&gt;For Ubuntu 24.04 LTS, the first fixed PHP 8.3 package revision is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8.3.6-0ubuntu0.24.04.13
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the upstream part remains &lt;code&gt;8.3.6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you only run:&lt;br&gt;
&lt;/p&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;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you might still see PHP 8.3.6 and conclude that your server is vulnerable.&lt;/p&gt;

&lt;p&gt;That conclusion may be incorrect.&lt;/p&gt;

&lt;p&gt;Canonical confirms the following fixed package revisions in &lt;a href="https://ubuntu.com/security/notices/USN-8948-1" rel="noopener noreferrer"&gt;Ubuntu Security Notice USN-8948-1&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ubuntu release&lt;/th&gt;
&lt;th&gt;PHP branch&lt;/th&gt;
&lt;th&gt;First fixed package revision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;22.04 LTS&lt;/td&gt;
&lt;td&gt;8.1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;8.1.2-1ubuntu2.28&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24.04 LTS&lt;/td&gt;
&lt;td&gt;8.3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;8.3.6-0ubuntu0.24.04.13&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26.04 LTS&lt;/td&gt;
&lt;td&gt;8.5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;8.5.4-0ubuntu1.5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26.10&lt;/td&gt;
&lt;td&gt;8.5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;8.5.9-0ubuntu2.1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These versions apply to the corresponding official Ubuntu packages.&lt;/p&gt;

&lt;p&gt;If PHP was installed from a third-party PPA, a hosting control panel, or a custom source build, check that vendor's security advisory instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Identify the Ubuntu release
&lt;/h2&gt;

&lt;p&gt;Connect to your server through SSH.&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/os-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for the &lt;code&gt;VERSION_ID&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VERSION_ID="24.04"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells you which Ubuntu security notice and package revisions apply to your system.&lt;/p&gt;

&lt;p&gt;Now check the default PHP interpreter:&lt;br&gt;
&lt;/p&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;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that this checks the command-line PHP binary, which may differ from the PHP installation serving your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Identify the web-facing PHP runtime
&lt;/h2&gt;

&lt;p&gt;A server can have several PHP versions installed simultaneously.&lt;/p&gt;

&lt;p&gt;List installed PHP packages with their complete revisions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dpkg-query &lt;span class="nt"&gt;-W&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'${binary:Package} ${Version}\n'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'php8.*'&lt;/span&gt; &lt;span class="s1"&gt;'libapache2-mod-php*'&lt;/span&gt; 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the installed PHP-FPM services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl list-unit-files &lt;span class="s1"&gt;'php*-fpm.service'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your website uses Nginx, inspect the configured FastCGI targets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-T&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep &lt;/span&gt;fastcgi_pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps identify the PHP-FPM socket or upstream handling requests.&lt;/p&gt;

&lt;p&gt;For Apache installations, inspect the loaded PHP-related modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apachectl &lt;span class="nt"&gt;-M&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'php|proxy_fcgi'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only run the web-server checks that apply to your environment.&lt;/p&gt;

&lt;p&gt;For Ubuntu 24.04 with PHP 8.3-FPM, examine the package information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt-cache policy php8.3-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important fields are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Installed:&lt;/strong&gt; the package currently installed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Candidate:&lt;/strong&gt; the package available for installation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version table:&lt;/strong&gt; where those packages come from.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't classify a server as patched solely because a newer package is available. Confirm the version that is actually installed and running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Install the Ubuntu security update
&lt;/h2&gt;

&lt;p&gt;Before changing production packages, ensure that your application files, databases, and configuration are backed up.&lt;/p&gt;

&lt;p&gt;For an installation using official Ubuntu repositories, refresh package indexes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review available updates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt list &lt;span class="nt"&gt;--upgradable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During an appropriate maintenance window, apply the updates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the proposed changes before confirming.&lt;/p&gt;

&lt;p&gt;For packages maintained by Ubuntu, Canonical states that a standard system update generally installs the necessary corrections.&lt;/p&gt;

&lt;p&gt;If your server uses third-party PHP packages, check their maintainer's instructions instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify the installed PHP package revision
&lt;/h3&gt;

&lt;p&gt;On Ubuntu 24.04:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dpkg-query &lt;span class="nt"&gt;-W&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'${Package} ${Version}\n'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  php8.3-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare the resulting revision with the version in USN-8948-1.&lt;/p&gt;

&lt;p&gt;For example, an official Ubuntu package at revision:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8.3.6-0ubuntu0.24.04.13
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;contains the October 21 fixes.&lt;/p&gt;

&lt;p&gt;A later package revision from the same maintained Ubuntu repository should also be checked against Canonical's advisories.&lt;/p&gt;

&lt;p&gt;Remember: the package name and revision are only part of the answer. You also need to establish which PHP runtime is handling HTTP requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Restart PHP-FPM or Apache
&lt;/h2&gt;

&lt;p&gt;Updated PHP packages must be loaded into the processes serving requests.&lt;/p&gt;

&lt;p&gt;For PHP 8.3-FPM, start by checking its configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;php-fpm8.3 &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the configuration is valid, restart the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart php8.3-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check its status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status php8.3-fpm &lt;span class="nt"&gt;--no-pager&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the restart fails, inspect recent logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; php8.3-fpm &lt;span class="nt"&gt;-n&lt;/span&gt; 30 &lt;span class="nt"&gt;--no-pager&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Apache with mod_php, validate its configuration and restart Apache instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apachectl configtest
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid restarting unrelated services on a production system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check that the application is responding
&lt;/h3&gt;

&lt;p&gt;You can perform a basic HTTPS check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://example.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;example.com&lt;/code&gt; with your application domain.&lt;/p&gt;

&lt;p&gt;A successful response confirms basic availability. It does &lt;strong&gt;not&lt;/strong&gt; prove that the PHP vulnerabilities have been fixed.&lt;/p&gt;

&lt;p&gt;That requires checking the installed vendor-fixed package and the runtime serving your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  An additional PHP advisory from October 23
&lt;/h2&gt;

&lt;p&gt;Two days after the PHP2Shell security release, the PHP team published an &lt;a href="https://www.php.net/archive/2026.php#2026-10-23-1" rel="noopener noreferrer"&gt;informational advisory about session upload progress&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It concerns a separate potential remote code execution scenario associated with &lt;strong&gt;CVE-2026-115560&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The issue requires an unusual combination of application behavior:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;session.serialize_handler&lt;/code&gt; is configured as &lt;code&gt;php_binary&lt;/code&gt; or &lt;code&gt;php_serialize&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Application code changes the handler to &lt;code&gt;php&lt;/code&gt; using &lt;code&gt;ini_set()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The application calls &lt;code&gt;session_start()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Session upload progress is enabled.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Applications that never change the serialization handler at runtime are not exposed through this specific scenario.&lt;/p&gt;

&lt;p&gt;As of October 29, PHP recommends temporarily setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;session.upload_progress.enabled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Ubuntu 24.04 with PHP 8.3-FPM, the main configuration file is typically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/php/8.3/fpm/php.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the configuration if the recommendation is appropriate for your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sudoedit /etc/php/8.3/fpm/php.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After making the change, check for conflicting PHP-FPM pool or server configuration overrides.&lt;/p&gt;

&lt;p&gt;Then validate and restart PHP-FPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;php-fpm8.3 &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart php8.3-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setting must be applied before request parsing. Don't rely on changing it through application-level &lt;code&gt;ini_set()&lt;/code&gt; or &lt;code&gt;.user.ini&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Disabling session upload progress may affect applications that depend on this feature, so assess its impact before changing production settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This measure does not replace the PHP2Shell security updates.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The PHP team has also published other temporary mitigations for specific attack paths. Those measures reduce exposure but do not provide complete protection. Installing the security fixes remains the recommended solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if PHP runs inside Docker?
&lt;/h2&gt;

&lt;p&gt;If you deploy PHP applications in containers, updating Ubuntu on the host does not automatically update PHP inside those containers.&lt;/p&gt;

&lt;p&gt;First list running containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Identify the container serving your application.&lt;/p&gt;

&lt;p&gt;Then check the installed PHP interpreter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;CONTAINER_NAME php &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;CONTAINER_NAME&lt;/code&gt; with the actual container name.&lt;/p&gt;

&lt;p&gt;For Docker Compose deployments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the PHP image and check whether its upstream maintainer has released a patched version.&lt;/p&gt;

&lt;p&gt;Depending on your deployment, you may need to pull an updated image or rebuild a custom image using a patched base.&lt;/p&gt;

&lt;p&gt;For services that use published images, a typical deployment sequence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose pull
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For custom-built images, rebuilding and redeploying may also be required.&lt;/p&gt;

&lt;p&gt;After deployment, verify the PHP installation inside the replacement container.&lt;/p&gt;

&lt;p&gt;The same rule applies here: a PHP version banner alone might not reveal whether a distribution-based image contains backported security fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  When rebuilding on a new VPS makes sense
&lt;/h2&gt;

&lt;p&gt;For a supported Ubuntu system, applying the available security updates is usually the most practical option.&lt;/p&gt;

&lt;p&gt;However, moving to a fresh server may be worth considering when the existing environment is no longer maintainable.&lt;/p&gt;

&lt;p&gt;Examples include an unsupported operating system, an abandoned PHP repository, incompatible legacy dependencies, or a server whose integrity can no longer be trusted.&lt;/p&gt;

&lt;p&gt;If you need a new environment, &lt;a href="https://www.cherryservers.com/?affiliate=889HYC31" rel="noopener noreferrer"&gt;Cherry Servers&lt;/a&gt; offers virtual servers with Ubuntu installation options, including Ubuntu 24.04 LTS.&lt;/p&gt;

&lt;p&gt;A migration should begin with a clean, updated operating system, followed by a maintained PHP runtime and properly configured web server.&lt;/p&gt;

&lt;p&gt;Before switching production traffic, restore the application from verified backups and test its functionality.&lt;/p&gt;

&lt;p&gt;Rebuilding does not automatically resolve PHP security issues. New servers require regular patching, access controls, monitoring, and maintenance just like existing ones.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Affiliate disclosure: The Cherry Servers link above is an affiliate link. I may earn a commission if you purchase through it, at no additional cost to you.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to confirm that PHP2Shell has been patched
&lt;/h2&gt;

&lt;p&gt;A reliable verification should answer four questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Which PHP runtime serves incoming requests?&lt;/strong&gt; The CLI interpreter may not be the same one your website uses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where did the PHP package come from?&lt;/strong&gt; Official Ubuntu repositories and third-party sources can use different security patch schedules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does the installed package contain the vendor's fix?&lt;/strong&gt; Compare its complete package revision with the corresponding security advisory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Are the patched workers running?&lt;/strong&gt; Restart or replace the affected processes, then verify application availability.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If these checks are complete, you have a stronger basis for assessing remediation than simply reading the output of &lt;code&gt;php -v&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For Ubuntu 24.04, the key detail is that a properly updated PHP 8.3.6 distribution package can contain the October 21 security fixes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The package revision matters more than the upstream version banner.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Official references
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.php.net/archive/2026.php#2026-10-21-5" rel="noopener noreferrer"&gt;PHP Security Advisory — October 21, 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ubuntu.com/security/notices/USN-8948-1" rel="noopener noreferrer"&gt;Ubuntu Security Notice USN-8948-1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.php.net/archive/2026.php#2026-10-23-1" rel="noopener noreferrer"&gt;PHP Session Upload Progress Advisory — October 23, 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cherryservers.com/knowledge/docs/compute/virtual-servers" rel="noopener noreferrer"&gt;Cherry Servers Virtual Server Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>devops</category>
      <category>security</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
