<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>buffer-overflow on SecMate Blog</title><link>https://blog.secmate.dev/tags/buffer-overflow/</link><description>What we find. What we share.</description><generator>Hugo</generator><language>en-us</language><managingEditor>noreply@blog.secmate.dev//blog.secmate.dev/ (SecMate Team)</managingEditor><lastBuildDate>Tue, 25 Aug 2026 06:06:13 +0000</lastBuildDate><atom:link href="https://blog.secmate.dev/tags/buffer-overflow/index.xml" rel="self" type="application/rss+xml"/><item><title>Six Vulnerabilities in Siemens SICAM SIAPP SDK</title><link>https://blog.secmate.dev/posts/siemens-siapp-sdk-vulnerabilities-disclosure/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Maxime Rossi Bellom</dc:creator><dc:creator>Ramtine Tofighi Shirazi</dc:creator><category>Security</category><category>Vulnerability Research</category><category>IoT</category><guid>https://blog.secmate.dev/posts/siemens-siapp-sdk-vulnerabilities-disclosure/</guid><description>SecMate's automated analysis found six vulnerabilities in Siemens SICAM SIAPP SDK before 2.1.7, spanning UNIX socket helper flaws and sample application bugs used to build custom SIAPP applications. Five of the affected code paths were present in the public repository from June 2020; Siemens fixed all six in version 2.1.7 and published advisory SSA-903736 on March 10, 2026.</description><content:encoded><![CDATA[<h1 id="six-vulnerabilities-in-siemens-sicam-siapp-sdk">Six Vulnerabilities in Siemens SICAM SIAPP SDK</h1>
<p>SecMate&rsquo;s automated analysis found six vulnerabilities in Siemens SICAM SIAPP SDK before version <code>2.1.7</code>. The set includes one out-of-bounds write in shipped sample code, one stack buffer overflow in the shipped <code>DemoProject</code>, two stack overflows in UNIX socket path handling, one command injection in UNIX socket permission handling, and one uncontrolled file or socket deletion issue caused by unchecked <code>unlink()</code>.</p>
<p>SIAPP SDK is Siemens&rsquo; development kit for building custom containerized applications that run on SICAM A8000 equipment used in substation automation, distribution grids, and other power-automation environments. These findings concern the SIAPP SDK path for custom applications; they do not, by themselves, imply that the core SICAM A8000 firmware or Siemens-provided standard functionality is affected by default.</p>
<p>Taken together, the bugs fall into two buckets: four issues in the SDK&rsquo;s UNIX socket helper code and two in sample applications Siemens ships as part of the developer workflow.</p>
<p>Exploitability depends on how downstream applications use the SDK, whether untrusted input reaches the affected paths, and whether hardening measures are applied.</p>
<p>In the public repository history, <strong>five of the six affected code paths trace back to the initial public commit on June 10, 2020</strong> and remained there until Siemens fixed them in <code>SIAPP SDK 2.1.7</code> on <strong>January 16, 2026</strong>. That is <strong>2,046 days</strong> in the public repository.</p>
<p>The sixth affected code path appears later, on <strong>March 19, 2021</strong>, and remained until the same <code>2.1.7</code> fix, for <strong>1,764 days</strong> in the public repository.</p>
<p>Siemens published these issues in advisory <code>SSA-903736</code> on <strong>March 10, 2026</strong> <a href="#ref1">[1]</a>.</p>
<h2 id="what-is-sicam-siapp-sdk">What Is SICAM SIAPP SDK?</h2>
<p>SIAPP SDK is Siemens&rsquo; development kit for building and emulating <strong>SIAPPs</strong>, containerized applications intended to run on the <a href="https://www.siemens.com/global/en/products/energy/energy-automation-and-smart-grid/substation-automation/automation-and-remote-terminal-units-sicam-a8000-series.html?_originalHost=marketplace.siemens.com&amp;language=en_US" rel="noopener noreferrer" target="_blank">SICAM A8000</a> family <a href="#ref2">[2]</a> <a href="#ref3">[3]</a> <a href="#ref4">[4]</a> <a href="#ref5">[5]</a>. Siemens&rsquo; documentation describes SIAPP as an application model for <strong>CP-8031</strong> and <strong>CP-8050</strong> processor modules; developers build an app as a Docker image, emulate it locally, and then load it onto the device <a href="#ref3">[3]</a> <a href="#ref4">[4]</a>.</p>
<p>The SDK includes:</p>
<ul>
<li>build and emulation tooling</li>
<li>an <strong>EdgeData API</strong> for exchanging signals with the platform <a href="#ref6">[6]</a></li>
<li>example applications such as <code>DemoProject</code>, <code>DemoSshd</code>, and <code>CodeSnippets</code></li>
<li>a local simulation environment for testing SIAPP behavior off-device</li>
</ul>
<p>Siemens markets <a href="https://www.siemens.com/global/en/products/energy/energy-automation-and-smart-grid/substation-automation/automation-and-remote-terminal-units-sicam-a8000-series.html?_originalHost=marketplace.siemens.com&amp;language=en_US" rel="noopener noreferrer" target="_blank">SICAM A8000</a> for <strong>substation automation</strong>, <strong>distribution grids</strong>, <strong>renewable integration</strong>, and <strong>industrial power</strong> <a href="#ref5">[5]</a>. This equipment is used to monitor and control parts of the electrical grid and adjacent industrial power systems. Its SIAPP material describes use cases such as transformer controllers, energy-storage optimization, weather-driven renewable control, and energy-trading optimization <a href="#ref4">[4]</a>, and the launch material frames the platform for customers such as <strong>major energy suppliers, municipal utilities, and industrial companies</strong> <a href="#ref7">[7]</a>. The SIAPP SDK is the official development kit for building custom applications in that environment.</p>
<p>The developer workflow in the repository is straightforward <a href="#ref3">[3]</a>:</p>
<ol>
<li>Write a SIAPP project with a <code>Dockerfile</code></li>
<li>Build it with <code>build.py</code></li>
<li>Test it with <code>run.py</code> and the local simulation flow</li>
<li>Deploy it to a SICAM A8000 target</li>
</ol>
<p>The SDK ships starter applications to accelerate that process. <code>DemoProject</code> is a small web application exposing configured signals. <code>DemoSshd</code> is a test container with SSH access. <code>CodeSnippets</code> contains small example programs showing how to use the EdgeData API. That matters because this is the code developers are most likely to copy into real projects.</p>
<p>Siemens&rsquo; advisory is careful on scope: these are not generic internet-wide bugs in every installation. As Siemens states, they are exploitable <strong>if the API is used improperly or hardening measures are not applied</strong> <a href="#ref1">[1]</a>. In practice, that puts weight on the SDK itself, because developers learn the safe and unsafe paths from the code Siemens ships.</p>
<h2 id="public-repository-timeline">Public Repository Timeline</h2>
<p>Five of the six vulnerabilities trace back to the initial public commit on <strong>June 10, 2020</strong> <a href="#ref8">[8]</a> <a href="#ref10">[10]</a>:</p>
<ul>
<li><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25569" rel="noopener noreferrer" target="_blank">CVE-2026-25569</a> in <code>CodeSnippets/src/helper.c</code></li>
<li><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25571" rel="noopener noreferrer" target="_blank">CVE-2026-25571</a> in <code>edgedataapi/src/edgedata.cpp</code></li>
<li><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25572" rel="noopener noreferrer" target="_blank">CVE-2026-25572</a> in <code>edgedataapi/src/edgedata.cpp</code></li>
<li><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25573" rel="noopener noreferrer" target="_blank">CVE-2026-25573</a> in <code>edgedataapi/src/edgedata.cpp</code></li>
<li><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25605" rel="noopener noreferrer" target="_blank">CVE-2026-25605</a> in <code>edgedataapi/src/edgedata.cpp</code></li>
</ul>
<p>The one later issue was introduced on <strong>March 19, 2021</strong> <a href="#ref9">[9]</a>:</p>
<ul>
<li><a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25570" rel="noopener noreferrer" target="_blank">CVE-2026-25570</a> in <code>DemoProject/src/demo.cpp</code></li>
</ul>
<p>Four of the six vulnerabilities live in the UNIX socket IPC helper code used by the SDK. The other two live in sample applications Siemens ships as part of the developer workflow.</p>
<h2 id="vulnerability-1-codesnippets-helper-out-of-bounds-write-cve-2026-25569-11ref11">Vulnerability #1: CodeSnippets Helper Out-of-Bounds Write (CVE-2026-25569 <a href="#ref11">[11]</a>)</h2>
<p><strong>Location</strong>: <code>helper_get_edgedata_text()</code> in <code>CodeSnippets/src/helper.c</code><br>
<strong>Introduced</strong>: <code>ff331c2</code> on June 10, 2020<br>
<strong>Fixed</strong>: <code>e4edda8</code> on January 16, 2026<br>
<strong>Siemens advisory</strong>: CVSS v3.1 7.4 <a href="#ref1">[1]</a></p>
<p>This issue is in the <code>CodeSnippets</code> sample application, not in the shared IPC helper. The helper <code>helper_get_edgedata_text()</code> formats multiple fields into a caller-provided buffer and advances <code>pos</code> using each <code>snprintf()</code> return value without validating truncation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="n">pos</span> <span class="o">+=</span> <span class="p">(</span><span class="kt">uint32_t</span><span class="p">)</span><span class="nf">snprintf</span><span class="p">(</span><span class="o">&amp;</span><span class="n">edgedata_to_text</span><span class="p">[</span><span class="n">pos</span><span class="p">],</span> <span class="p">(</span><span class="n">max_len_edgedata_to_text</span><span class="o">-</span><span class="n">pos</span><span class="p">),</span> <span class="s">&#34;Topic: %s&#34;</span><span class="p">,</span> <span class="n">edge_data</span><span class="o">-&gt;</span><span class="n">topic</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="n">pos</span> <span class="o">+=</span> <span class="p">(</span><span class="kt">uint32_t</span><span class="p">)</span><span class="nf">snprintf</span><span class="p">(</span><span class="o">&amp;</span><span class="n">edgedata_to_text</span><span class="p">[</span><span class="n">pos</span><span class="p">],</span> <span class="p">(</span><span class="n">max_len_edgedata_to_text</span><span class="o">-</span><span class="n">pos</span><span class="p">),</span> <span class="s">&#34;, Type:&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="n">pos</span> <span class="o">+=</span> <span class="nf">helper_get_data_type_text</span><span class="p">(</span><span class="n">edge_data</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">edgedata_to_text</span><span class="p">[</span><span class="n">pos</span><span class="p">],</span> <span class="p">(</span><span class="n">max_len_edgedata_to_text</span><span class="o">-</span><span class="n">pos</span><span class="p">));</span>
</span></span></code></pre></div><p>If a topic exceeds remaining space, <code>pos</code> can move beyond the real buffer boundary, and subsequent writes can go out of bounds. In the shipped examples, <code>discover.c</code>, <code>subscribe.c</code>, and <code>simple_dido.c</code> call this helper with fixed 300-byte stack buffers, so oversized topic strings can trigger stack corruption.</p>
<h2 id="vulnerability-2-demoproject-floating-point-formatting-stack-overflow-cve-2026-25570-12ref12">Vulnerability #2: DemoProject Floating-Point Formatting Stack Overflow (CVE-2026-25570 <a href="#ref12">[12]</a>)</h2>
<p><strong>Location</strong>: <code>convert_value_to_str()</code> in <code>DemoProject/src/demo.cpp</code><br>
<strong>Introduced</strong>: <code>4139bfb</code> on March 19, 2021<br>
<strong>Fixed</strong>: <code>e4edda8</code> on January 16, 2026<br>
<strong>Siemens advisory</strong>: CVSS v3.1 7.4 <a href="#ref1">[1]</a></p>
<p>This issue is in the <code>DemoProject</code> sample application. <code>convert_value_to_str()</code> writes to fixed-size buffers (including <code>char value_str[50]</code>) and used unbounded <code>sprintf()</code> for floating-point values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">case</span> <span class="nl">E_EDGE_DATA_TYPE_FLOAT32</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">   <span class="nf">sprintf</span><span class="p">(</span><span class="n">out_value</span><span class="p">,</span> <span class="s">&#34;%f&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">-&gt;</span><span class="n">float32</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">   <span class="nf">sprintf</span><span class="p">(</span><span class="n">out_type</span><span class="p">,</span> <span class="s">&#34;FLOAT32&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">   <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">case</span> <span class="nl">E_EDGE_DATA_TYPE_DOUBLE64</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">   <span class="nf">sprintf</span><span class="p">(</span><span class="n">out_value</span><span class="p">,</span> <span class="s">&#34;%lf&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">-&gt;</span><span class="n">double64</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">   <span class="nf">sprintf</span><span class="p">(</span><span class="n">out_type</span><span class="p">,</span> <span class="s">&#34;DOUBLE64&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">   <span class="k">break</span><span class="p">;</span>
</span></span></code></pre></div><p>Large floating-point values can expand to strings longer than 50 bytes, causing stack overflow in <code>value_str</code>. The formatter is used in <code>/edgedata/get</code> and <code>/edgedata/get_events</code> response paths, so oversized <code>DOUBLE64</code> values can trigger memory corruption during XML serialization.</p>
<h2 id="vulnerability-3-client-unix-socket-path-overflow-cve-2026-25571-13ref13">Vulnerability #3: Client UNIX Socket Path Overflow (CVE-2026-25571 <a href="#ref13">[13]</a>)</h2>
<p><strong>Location</strong>: <code>edgedata_ipc_unix_client_connect()</code> in <code>edgedataapi/src/edgedata.cpp</code><br>
<strong>Introduced</strong>: <code>ff331c2</code> on June 10, 2020<br>
<strong>Fixed</strong>: <code>e4edda8</code> on January 16, 2026<br>
<strong>Siemens advisory</strong>: CVSS v3.1 5.1 <a href="#ref1">[1]</a></p>
<p>This is a client-side length validation issue in the shared UNIX socket helper. <code>edgedata_ipc_unix_client_connect()</code> copies a caller-provided socket path into <code>sockaddr_un.sun_path</code> using <code>strcpy()</code> without bounds checking:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="nf">strcpy</span><span class="p">(</span><span class="n">addr</span><span class="p">.</span><span class="n">sun_path</span><span class="p">,</span> <span class="n">fd</span><span class="o">-&gt;</span><span class="n">read_channel_name</span><span class="p">.</span><span class="nf">c_str</span><span class="p">());</span>
</span></span></code></pre></div><p>On Linux, <code>sun_path</code> is fixed-size (commonly 108 bytes). Longer paths can overflow the stack buffer before <code>connect()</code>. Exploitation depends on downstream integration: if untrusted or oversized input is passed into this API, the overflow is reachable.</p>
<h2 id="vulnerability-4-server-unix-socket-path-overflow-cve-2026-25572-14ref14">Vulnerability #4: Server UNIX Socket Path Overflow (CVE-2026-25572 <a href="#ref14">[14]</a>)</h2>
<p><strong>Location</strong>: <code>edgedata_ipc_unix_server_listen()</code> in <code>edgedataapi/src/edgedata.cpp</code><br>
<strong>Introduced</strong>: <code>ff331c2</code> on June 10, 2020<br>
<strong>Fixed</strong>: <code>e4edda8</code> on January 16, 2026<br>
<strong>Siemens advisory</strong>: CVSS v3.1 5.1 <a href="#ref1">[1]</a></p>
<p>This is the server-side twin of the previous bug. The same unbounded copy is used when preparing the server socket address:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="nf">strcpy</span><span class="p">(</span><span class="n">addr</span><span class="p">.</span><span class="n">sun_path</span><span class="p">,</span> <span class="n">fd</span><span class="o">-&gt;</span><span class="n">read_channel_name</span><span class="p">.</span><span class="nf">c_str</span><span class="p">());</span>
</span></span></code></pre></div><p>If a downstream application accepts an untrusted socket path and forwards it into the SDK, the server helper can overflow the stack before <code>bind()</code> runs. As with the client-side variant, the default examples do not expose this path directly to attackers; the precondition is still misuse at the API boundary.</p>
<h2 id="vulnerability-5-unix-socket-helper-command-injection-cve-2026-25573-15ref15">Vulnerability #5: UNIX Socket Helper Command Injection (CVE-2026-25573 <a href="#ref15">[15]</a>)</h2>
<p><strong>Location</strong>: <code>edgedata_ipc_unix_server_listen()</code> in <code>edgedataapi/src/edgedata.cpp</code><br>
<strong>Introduced</strong>: <code>ff331c2</code> on June 10, 2020<br>
<strong>Fixed</strong>: <code>e4edda8</code> on January 16, 2026<br>
<strong>Siemens advisory</strong>: CVSS v3.1 7.4 <a href="#ref1">[1]</a></p>
<p>This issue is more serious because the vulnerable code does not just mishandle memory. It builds shell commands from caller-controlled strings and executes them:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">snprintf</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">cmd</span><span class="p">),</span> <span class="s">&#34;chown %s %s&#34;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">addr</span><span class="p">.</span><span class="n">sun_path</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">system</span><span class="p">(</span><span class="n">cmd</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">snprintf</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">cmd</span><span class="p">),</span> <span class="s">&#34;chmod 777 %s&#34;</span><span class="p">,</span> <span class="n">addr</span><span class="p">.</span><span class="n">sun_path</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">system</span><span class="p">(</span><span class="n">cmd</span><span class="p">);</span>
</span></span></code></pre></div><p>If an application exposes <code>user</code> or <code>channel_name</code> to untrusted input, shell metacharacters become part of the command line interpreted by <code>/bin/sh</code>. This is not an abstract quoting issue. The helper literally concatenates caller-controlled data into a shell command and runs it.</p>
<p>As with the path overflows, exploitability depends on integration. The repository examples do not themselves expose arbitrary remote input for these parameters. But once a downstream application lets an untrusted user influence socket ownership or socket path values, the bug becomes command injection.</p>
<h2 id="vulnerability-6-unchecked-unlink-in-unix-socket-setup-cve-2026-25605-16ref16">Vulnerability #6: Unchecked <code>unlink()</code> in UNIX Socket Setup (CVE-2026-25605 <a href="#ref16">[16]</a>)</h2>
<p><strong>Location</strong>: <code>edgedata_ipc_unix_server_listen()</code> in <code>edgedataapi/src/edgedata.cpp</code><br>
<strong>Introduced</strong>: <code>ff331c2</code> on June 10, 2020<br>
<strong>Fixed</strong>: <code>e4edda8</code> on January 16, 2026<br>
<strong>Siemens advisory</strong>: CVSS v3.1 6.7 <a href="#ref1">[1]</a></p>
<p>Before binding the server socket, the helper called:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="nf">unlink</span><span class="p">(</span><span class="n">fd</span><span class="o">-&gt;</span><span class="n">read_channel_name</span><span class="p">.</span><span class="nf">c_str</span><span class="p">());</span>
</span></span></code></pre></div><p>There was no validation that the path pointed to an existing socket, no restriction to a dedicated socket directory, and no <code>lstat()</code> / <code>S_ISSOCK</code> guard. If a downstream application lets an untrusted party influence <code>channel_name</code>, the process can be induced to delete any file or socket it has permission to remove.</p>
<p>This does not automatically mean arbitrary file deletion from the network. The vulnerable operation is local to the API boundary, so the precondition is still that a caller passes untrusted data into the helper. But once that happens, the delete happens before the bind, with no type check at all.</p>
<h2 id="what-siemens-fixed-in-217">What Siemens Fixed in <code>2.1.7</code></h2>
<p>The <code>SIAPP SDK 2.1.7</code> commit includes direct fixes in the affected code paths:</p>
<ul>
<li><code>strcpy()</code> on <code>sun_path</code> was replaced with explicit length checks and bounded copies</li>
<li>unconditional <code>unlink()</code> was replaced with <code>lstat()</code> and socket-type validation</li>
<li>shell-based <code>chown</code> and <code>chmod</code> calls were replaced with <code>getpwnam()</code>, <code>chown()</code>, and <code>chmod()</code></li>
<li><code>sprintf()</code> was replaced with bounded <code>snprintf()</code>, and the float formatting was changed from <code>%f</code> / <code>%lf</code> to <code>%g</code></li>
<li>the <code>CodeSnippets</code> helper was rewritten to check truncation after each append and to cap copied topic length</li>
</ul>
<h2 id="disclosure-timeline">Disclosure Timeline</h2>
<div style="position: relative; padding-left: 1.5rem; margin: 1.5rem 0;">
  <div style="position: absolute; left: 0.35rem; top: 0.5rem; bottom: 0.5rem; width: 2px; background: var(--color-border);"></div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-accent); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Jan 3, 2026</div>
    <div style="color: var(--color-text);">SecMate reports six vulnerabilities to Siemens ProductCERT, including two affecting example code only <a href="#ref17">[17]</a></div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-text-secondary); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Jan 5, 2026</div>
    <div style="color: var(--color-text);">Siemens ProductCERT confirms the case was opened as <code>#33016</code> on the first business day after the January 3 report <a href="#ref17">[17]</a></div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-text-secondary); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Jan 16, 2026</div>
    <div style="color: var(--color-text);">Siemens fixes all six issues in <a href="https://github.com/siemens/siapp-sdk/commit/e4edda8">SIAPP SDK 2.1.7</a> <a href="#ref10">[10]</a></div>
  </div>
  <div style="position: relative;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: #22c55e; border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Mar 10, 2026</div>
    <div style="color: var(--color-text);">Siemens publishes advisory <a href="https://cert-portal.siemens.com/productcert/html/ssa-903736.html">SSA-903736</a> covering <code>CVE-2026-25569</code>, <code>CVE-2026-25570</code>, <code>CVE-2026-25571</code>, <code>CVE-2026-25572</code>, <code>CVE-2026-25573</code>, and <code>CVE-2026-25605</code> <a href="#ref1">[1]</a></div>
  </div>
</div>
<h2 id="closing-thoughts">Closing Thoughts</h2>
<p>Several of these patterns sat for years in a vendor SDK used to build software for power-automation environments.</p>
<p>Four of these vulnerabilities were in reusable UNIX socket SDK code, and two were in sample applications shipped to show developers how to build on the platform.</p>
<p>For SDK maintainers, especially in embedded and industrial systems, the lesson is simple: helper APIs and sample projects are part of the security boundary.</p>
<h2 id="references">References</h2>
<ul>
<li>
<p><a id="ref1"></a>[1] Siemens ProductCERT. &ldquo;SSA-903736: Multiple vulnerabilities in SICAM SIAPP SDK before V2.1.7.&rdquo; Published March 10, 2026. <a href="https://cert-portal.siemens.com/productcert/html/ssa-903736.html" rel="noopener noreferrer" target="_blank">Advisory</a></p>
</li>
<li>
<p><a id="ref2"></a>[2] Siemens. &ldquo;siapp-sdk.&rdquo; <a href="https://github.com/siemens/siapp-sdk" rel="noopener noreferrer" target="_blank">GitHub repository</a></p>
</li>
<li>
<p><a id="ref3"></a>[3] Siemens. &ldquo;SIAPP SDK README.&rdquo; <a href="https://github.com/siemens/siapp-sdk/blob/master/README.md" rel="noopener noreferrer" target="_blank">Repository documentation</a></p>
</li>
<li>
<p><a id="ref4"></a>[4] Siemens. &ldquo;SICAM application - SIAPP.&rdquo; <a href="https://www.siemens.com/global/en/products/energy/energy-automation-and-smart-grid/substation-automation/sicam-application-siapp.html" rel="noopener noreferrer" target="_blank">Product page</a></p>
</li>
<li>
<p><a id="ref5"></a>[5] Siemens. &ldquo;Automation and remote terminal units - SICAM A8000 Series.&rdquo; <a href="https://www.siemens.com/global/en/products/energy/energy-automation-and-smart-grid/substation-automation/automation-and-remote-terminal-units-sicam-a8000-series.html?_originalHost=marketplace.siemens.com&amp;language=en_US" rel="noopener noreferrer" target="_blank">Product page</a></p>
</li>
<li>
<p><a id="ref6"></a>[6] Siemens. &ldquo;EDGEDATAAPI.md.&rdquo; <a href="https://github.com/siemens/siapp-sdk/blob/master/EDGEDATAAPI.md" rel="noopener noreferrer" target="_blank">Repository documentation</a></p>
</li>
<li>
<p><a id="ref7"></a>[7] Siemens Press. &ldquo;Siemens launches new platform to create customer-specific apps for distribution grids.&rdquo; Published July 7, 2020. <a href="https://press.siemens.com/global/en/pressrelease/siemens-launches-new-platform-create-customer-specific-apps-distribution-grids" rel="noopener noreferrer" target="_blank">Press release</a></p>
</li>
<li>
<p><a id="ref8"></a>[8] Siemens. &ldquo;initial commit&rdquo; (<code>ff331c2</code>, June 10, 2020). <a href="https://github.com/siemens/siapp-sdk/commit/ff331c2" rel="noopener noreferrer" target="_blank">Commit</a></p>
</li>
<li>
<p><a id="ref9"></a>[9] Siemens. &ldquo;SIAPP SDK 1.1.1&rdquo; (<code>4139bfb</code>, March 19, 2021). <a href="https://github.com/siemens/siapp-sdk/commit/4139bfb" rel="noopener noreferrer" target="_blank">Commit</a></p>
</li>
<li>
<p><a id="ref10"></a>[10] Siemens. &ldquo;SIAPP SDK 2.1.7&rdquo; (<code>e4edda8</code>, January 16, 2026). <a href="https://github.com/siemens/siapp-sdk/commit/e4edda8" rel="noopener noreferrer" target="_blank">Commit</a></p>
</li>
<li>
<p><a id="ref11"></a>[11] NVD. &ldquo;CVE-2026-25569.&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25569" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
<li>
<p><a id="ref12"></a>[12] NVD. &ldquo;CVE-2026-25570.&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25570" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
<li>
<p><a id="ref13"></a>[13] NVD. &ldquo;CVE-2026-25571.&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25571" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
<li>
<p><a id="ref14"></a>[14] NVD. &ldquo;CVE-2026-25572.&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25572" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
<li>
<p><a id="ref15"></a>[15] NVD. &ldquo;CVE-2026-25573.&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25573" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
<li>
<p><a id="ref16"></a>[16] NVD. &ldquo;CVE-2026-25605.&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-25605" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
<li>
<p><a id="ref17"></a>[17] Email correspondence between SecMate and Siemens ProductCERT regarding <code>siapp-sdk</code>, January 3, 2026 to March 25, 2026. On file.</p>
</li>
</ul>
<hr>
<p><em>The SecMate Team</em></p>
]]></content:encoded><media:content url="https://blog.secmate.dev/images/og_image.jpg" medium="image"/></item><item><title>How SecMate Discovered two Vulnerabilities in libcoap</title><link>https://blog.secmate.dev/posts/libcoap-vulnerabilities-disclosure/</link><pubDate>Wed, 14 Jan 2026 00:00:00 +0000</pubDate><atom:updated>2026-01-14T00:00:00+00:00</atom:updated><dc:creator>Maxime Rossi Bellom</dc:creator><dc:creator>Ramtine Tofighi Shirazi</dc:creator><category>Security</category><category>Vulnerability Research</category><category>IoT</category><guid>https://blog.secmate.dev/posts/libcoap-vulnerabilities-disclosure/</guid><description>SecMate's AI-powered static analysis tool discovered two vulnerabilities in libcoap: an out-of-bounds write in address resolution (CVE-2025-34468) and an out-of-bounds read in OSCORE parsing (CVE-2025-59391). Here's the technical breakdown.</description><content:encoded><![CDATA[<h1 id="how-secmate-discovered-vulnerabilities-in-libcoap">How SecMate Discovered Vulnerabilities in libcoap</h1>
<p>We discovered two memory-safety issues in libcoap, a widely deployed IoT library. The first is an out-of-bounds write in a fixed buffer reachable via proxy requests that can crash servers with a single UDP packet. The second is an out-of-bounds read in OSCORE configuration parsing that can crash the parser on malformed input. Both vulnerabilities have amplified impact on the constrained embedded devices the library was built for.</p>
<h2 id="about-secmate">About SecMate</h2>
<p><a href="https://secmate.dev?utm_source=blog&amp;utm_medium=body&amp;utm_campaign=libcoap-vulnerabilities-disclosure&amp;utm_content=security" rel="noopener noreferrer" target="_blank" data-cta-type="body_secmate" data-post-slug="libcoap-vulnerabilities-disclosure" data-post-category="security">SecMate</a> combines static analysis with AI to find security vulnerabilities in source code, specifically in embedded devices and low-level code.</p>
<p>So far, we have reported <strong>more than 60 vulnerabilities</strong> across embedded and systems projects, most still under <a href="https://secmate.dev/disclosures?utm_source=blog&amp;utm_medium=body&amp;utm_campaign=libcoap-vulnerabilities-disclosure&amp;utm_content=security" rel="noopener noreferrer" target="_blank" data-cta-type="body_disclosures" data-post-slug="libcoap-vulnerabilities-disclosure" data-post-category="security">coordinated disclosure</a>.</p>
<p>Today, we are sharing two of our findings in libcoap (the first two CVEs uncovered with SecMate), a widely-used CoAP implementation for IoT devices.</p>
<h2 id="what-is-libcoap">What is libcoap?</h2>
<p>libcoap <a href="#ref1">[1]</a> is a C implementation of the Constrained Application Protocol (CoAP), standardized as RFC 7252 <a href="#ref2">[2]</a>. Think of CoAP as &ldquo;HTTP for IoT&rdquo;: a lightweight protocol for devices that can&rsquo;t afford the overhead of full HTTP/TCP stacks.</p>
<p>The library is mature and widely deployed:</p>
<ul>
<li>Supports multiple TLS backends (OpenSSL, GnuTLS, Mbed TLS, wolfSSL)</li>
<li>Runs on everything from Linux servers to ESP32 microcontrollers</li>
<li>Used in smart home devices, industrial sensors, and critical infrastructure</li>
</ul>
<p>Here is the catch: the devices running libcoap are often <em>constrained</em>. Limited memory, no MMU, no ASLR, no stack canaries. When you find a memory-safety issue in this context, the impact is amplified.</p>
<h2 id="vulnerability-1-static-buffer-overflow-in-address-resolution-cve-2025-34468-3ref3">Vulnerability #1: Static Buffer Overflow in Address Resolution (CVE-2025-34468 <a href="#ref3">[3]</a>)</h2>
<p><strong>Location</strong>: <code>coap_resolve_address_info()</code> in <code>src/coap_address.c</code></p>
<h3 id="the-bug">The Bug</h3>
<p>This vulnerability affects libcoap servers running in <strong>proxy mode</strong>. The vulnerable function resolves hostnames for CoAP proxy requests, copying the hostname into a fixed 256-byte static buffer without checking the length:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">static</span> <span class="kt">char</span> <span class="n">addrstr</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span>  <span class="c1">// Fixed-size static buffer
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"></span><span class="nf">memset</span><span class="p">(</span><span class="n">addrstr</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">addrstr</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="n">address</span> <span class="o">&amp;&amp;</span> <span class="n">address</span><span class="o">-&gt;</span><span class="n">length</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="nf">memcpy</span><span class="p">(</span><span class="n">addrstr</span><span class="p">,</span> <span class="n">address</span><span class="o">-&gt;</span><span class="n">s</span><span class="p">,</span> <span class="n">address</span><span class="o">-&gt;</span><span class="n">length</span><span class="p">);</span>  <span class="c1">// No bounds check!
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"></span><span class="k">else</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl">    <span class="nf">memcpy</span><span class="p">(</span><span class="n">addrstr</span><span class="p">,</span> <span class="s">&#34;localhost&#34;</span><span class="p">,</span> <span class="mi">9</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="nf">getaddrinfo</span><span class="p">(</span><span class="n">addrstr</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">hints</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">res</span><span class="p">);</span>
</span></span></code></pre></div><p>The <code>address-&gt;length</code> field comes directly from parsing CoAP options. An attacker controls this value.</p>
<h3 id="the-attack">The Attack</h3>
<p>When a CoAP server runs in proxy mode, it accepts <code>Proxy-Uri</code> options that specify where to forward requests. The hostname from this URI flows directly into the vulnerable <code>memcpy()</code>:</p>
<ol>
<li>A CoAP request arrives with a <code>Proxy-Uri</code> option containing an oversized hostname (&gt;256 bytes)</li>
<li>The proxy extracts the hostname and passes it to <code>coap_resolve_address_info()</code></li>
<li>The function calls <code>memcpy(addrstr, address-&gt;s, address-&gt;length)</code> without bounds checking</li>
<li>The fixed-size buffer overflows, corrupting adjacent memory</li>
<li>The server crashes or misbehaves; the exact impact depends on layout and mitigations</li>
</ol>
<h3 id="impact">Impact</h3>
<p>On a standard Linux system, this bug is likely to crash the server (Denial of Service). On embedded devices without memory protection, memory corruption can have broader consequences, but practical exploitation depends on layout and mitigations. One UDP packet, no authentication required when proxy mode is enabled.</p>
<h2 id="vulnerability-2-out-of-bounds-read-in-oscore-parsing-cve-2025-59391-4ref4">Vulnerability #2: Out-of-Bounds Read in OSCORE Parsing (CVE-2025-59391 <a href="#ref4">[4]</a>)</h2>
<p><strong>Location</strong>: <code>get_split_entry()</code> in <code>src/coap_oscore.c</code></p>
<h3 id="the-bug-1">The Bug</h3>
<p>OSCORE (Object Security for Constrained RESTful Environments) is a security layer for CoAP. libcoap parses OSCORE configuration files that include boolean fields. The parsing code uses <code>memcmp()</code> with a user-controlled length:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">case</span> <span class="nl">COAP_ENC_BOOL</span><span class="p">:</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">memcmp</span><span class="p">(</span><span class="s">&#34;true&#34;</span><span class="p">,</span> <span class="n">begin</span><span class="p">,</span> <span class="n">end</span> <span class="o">-</span> <span class="n">begin</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">        <span class="n">value</span><span class="o">-&gt;</span><span class="n">u</span><span class="p">.</span><span class="n">value_int</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">    <span class="k">else</span> <span class="nf">if</span> <span class="p">(</span><span class="nf">memcmp</span><span class="p">(</span><span class="s">&#34;false&#34;</span><span class="p">,</span> <span class="n">begin</span><span class="p">,</span> <span class="n">end</span> <span class="o">-</span> <span class="n">begin</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">        <span class="n">value</span><span class="o">-&gt;</span><span class="n">u</span><span class="p">.</span><span class="n">value_int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span></code></pre></div><p>The problem: <code>end - begin</code> comes from the configuration file. If an attacker provides a value like <code>trueAAAAAAAA...</code> (thousands of characters), the <code>memcmp()</code> reads past the static string <code>&quot;true&quot;</code> into adjacent memory.</p>
<h3 id="impact-1">Impact</h3>
<p>This issue requires the ability to provide malicious OSCORE configuration input, which is typically a local or trusted provisioning path rather than a network-facing vector. The realistic outcome is a crash or parse failure on malformed configs.</p>
<h3 id="theoretical-oracle-attack">Theoretical Oracle Attack</h3>
<p>In theory, if a local attacker could repeatedly provide different config files and observe success/failure signals from the parser, they could use this as an oracle to infer adjacent <code>.rodata</code> bytes one at a time. The diagram below illustrates what such an attack would look like:</p>
<svg viewBox="0 0 440 100" style="width: 100%; max-width: 440px; height: auto; margin: 1.5rem auto; display: block; font-family: monospace;">
  <style>
    .svg-label { fill: var(--color-text-secondary); }
    .svg-bg { fill: var(--color-muted-bg); stroke: var(--color-border); }
    .svg-known { fill: color-mix(in srgb, var(--color-accent) 30%, var(--color-bg-card)); stroke: var(--color-accent); }
    .svg-unknown { fill: var(--color-bg-card); stroke: var(--color-border); }
    .svg-text { fill: var(--color-text); }
    .svg-text-muted { fill: var(--color-text-secondary); }
  </style>
  <text x="220" y="14" text-anchor="middle" class="svg-label" font-size="11">memory layout</text>
  <rect x="10" y="22" width="420" height="44" rx="4" class="svg-bg" stroke-width="1"/>
  <rect x="15" y="26" width="36" height="36" rx="3" class="svg-known" stroke-width="2"/><text x="33" y="50" text-anchor="middle" class="svg-text" font-size="15">t</text>
  <rect x="56" y="26" width="36" height="36" rx="3" class="svg-known" stroke-width="2"/><text x="74" y="50" text-anchor="middle" class="svg-text" font-size="15">r</text>
  <rect x="97" y="26" width="36" height="36" rx="3" class="svg-known" stroke-width="2"/><text x="115" y="50" text-anchor="middle" class="svg-text" font-size="15">u</text>
  <rect x="138" y="26" width="36" height="36" rx="3" class="svg-known" stroke-width="2"/><text x="156" y="50" text-anchor="middle" class="svg-text" font-size="15">e</text>
  <rect x="179" y="26" width="36" height="36" rx="3" class="svg-known" stroke-width="2"/><text x="197" y="50" text-anchor="middle" class="svg-text" font-size="12">\0</text>
  <rect x="220" y="26" width="36" height="36" rx="3" class="svg-unknown" stroke-width="1"><animate attributeName="fill" values="var(--color-bg-card);#7f1d1d;#166534;#166534;#166534;#166534" dur="6s" repeatCount="indefinite"/><animate attributeName="stroke" values="var(--color-border);#dc2626;#22c55e;#22c55e;#22c55e;#22c55e" dur="6s" repeatCount="indefinite"/></rect>
  <text x="238" y="50" text-anchor="middle" class="svg-text-muted" font-size="15"><animate attributeName="opacity" values="1;1;0;0;0;0" dur="6s" repeatCount="indefinite"/>?</text>
  <text x="238" y="50" text-anchor="middle" class="svg-text" font-size="15"><animate attributeName="opacity" values="0;0;1;1;1;1" dur="6s" repeatCount="indefinite"/>f</text>
  <rect x="261" y="26" width="36" height="36" rx="3" class="svg-unknown" stroke-width="1"><animate attributeName="fill" values="var(--color-bg-card);var(--color-bg-card);var(--color-bg-card);#7f1d1d;#166534;#166534" dur="6s" repeatCount="indefinite"/><animate attributeName="stroke" values="var(--color-border);var(--color-border);var(--color-border);#dc2626;#22c55e;#22c55e" dur="6s" repeatCount="indefinite"/></rect>
  <text x="279" y="50" text-anchor="middle" class="svg-text-muted" font-size="15"><animate attributeName="opacity" values="1;1;1;1;0;0" dur="6s" repeatCount="indefinite"/>?</text>
  <text x="279" y="50" text-anchor="middle" class="svg-text" font-size="15"><animate attributeName="opacity" values="0;0;0;0;1;1" dur="6s" repeatCount="indefinite"/>a</text>
  <rect x="302" y="26" width="36" height="36" rx="3" class="svg-unknown" stroke-width="1"/><text x="320" y="50" text-anchor="middle" class="svg-text-muted" font-size="15">?</text>
  <rect x="343" y="26" width="36" height="36" rx="3" class="svg-unknown" stroke-width="1"/><text x="361" y="50" text-anchor="middle" class="svg-text-muted" font-size="15">?</text>
  <rect x="384" y="26" width="36" height="36" rx="3" class="svg-unknown" stroke-width="1"/><text x="402" y="50" text-anchor="middle" class="svg-text-muted" font-size="15">?</text>
  <text x="135" y="88" text-anchor="start" font-size="15" font-weight="bold" class="svg-label">true\0</text>
  <text x="200" y="88" text-anchor="start" font-size="15" font-weight="bold" class="svg-label"><animate attributeName="opacity" values="1;0;0;0;0;0" dur="6s" calcMode="discrete" repeatCount="indefinite"/>...</text>
  <text x="200" y="88" text-anchor="start" font-size="15" font-weight="bold" fill="#dc2626"><animate attributeName="opacity" values="0;1;0;0;0;0" dur="6s" calcMode="discrete" repeatCount="indefinite"/>Y ✗</text>
  <text x="200" y="88" text-anchor="start" font-size="15" font-weight="bold" fill="#22c55e"><animate attributeName="opacity" values="0;0;1;0;0;0" dur="6s" calcMode="discrete" repeatCount="indefinite"/>f ✓</text>
  <text x="200" y="88" text-anchor="start" font-size="15" font-weight="bold" fill="#dc2626"><animate attributeName="opacity" values="0;0;0;1;0;0" dur="6s" calcMode="discrete" repeatCount="indefinite"/>fK ✗</text>
  <text x="200" y="88" text-anchor="start" font-size="15" font-weight="bold" fill="#22c55e"><animate attributeName="opacity" values="0;0;0;0;1;0" dur="6s" calcMode="discrete" repeatCount="indefinite"/>fa ✓</text>
  <text x="200" y="88" text-anchor="start" font-size="15" font-weight="bold" fill="#22c55e"><animate attributeName="opacity" values="0;0;0;0;0;1" dur="6s" calcMode="discrete" repeatCount="indefinite"/>fa</text>
</svg>
<p>However, this attack is impractical: OSCORE configuration is loaded from local files, so an attacker would need repeated local access to provide different config files and observe results. At that point, they likely have access that makes this leak scenario moot.</p>
<blockquote class="admonition admonition-insight">
<strong>Why This Bug is Easy to Miss</strong>
<p>This vulnerability is subtle: the out-of-bounds read in <code>memcmp()</code> may not crash or produce obvious symptoms during normal operation. Spotting it requires reasoning about how data flows through multiple operations, something traditional static analysis tools typically miss.</p>
</blockquote>
<h2 id="the-embedded-security-challenge">The Embedded Security Challenge</h2>
<p>Both vulnerabilities share a common theme: <strong>they are worse on the devices libcoap is designed for</strong>.</p>
<p>Desktop and server systems have decades of hardening:</p>
<ul>
<li>ASLR randomizes memory layout</li>
<li>Stack canaries detect buffer overflows</li>
<li>DEP/NX prevents code execution from data segments</li>
<li>Sandboxing limits blast radius</li>
</ul>
<p>Constrained embedded devices often have none of these. A microcontroller running FreeRTOS or bare metal has:</p>
<ul>
<li>Flat, predictable memory layout</li>
<li>No memory protection unit (MPU) or it is disabled for performance</li>
<li>No operating system to enforce isolation</li>
<li>Direct hardware access for any code that runs</li>
</ul>
<p>This isn&rsquo;t a criticism of libcoap. It is the reality of their target environment. But it means bugs like these deserve extra scrutiny.</p>
<blockquote class="admonition admonition-insight">
<strong>Key Insight</strong>
<p>When auditing code for constrained devices, assume the worst-case exploitation scenario. Mitigations you take for granted on desktop systems simply don't exist.</p>
</blockquote>
<h2 id="disclosure-and-fix">Disclosure and Fix</h2>
<p>We reported both vulnerabilities to the libcoap maintainers through coordinated disclosure. The team responded quickly and professionally, and fixes are now available in version 4.3.5a.</p>
<h3 id="disclosure-timeline">Disclosure Timeline</h3>
<div style="position: relative; padding-left: 1.5rem; margin: 1.5rem 0;">
  <div style="position: absolute; left: 0.35rem; top: 0.5rem; bottom: 0.5rem; width: 2px; background: var(--color-border);"></div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-accent); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Sep 3, 2025</div>
    <div style="color: var(--color-text);">SecMate reported OSCORE out-of-bounds read to libcoap security team</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-text-secondary); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Sep 3, 2025</div>
    <div style="color: var(--color-text);">Maintainer acknowledged and confirmed the issue is reproducible</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-accent); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Sep 10, 2025</div>
    <div style="color: var(--color-text);">SecMate reported static buffer overflow to libcoap security team</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-text-secondary); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Sep 10, 2025</div>
    <div style="color: var(--color-text);">Maintainer acknowledged the second vulnerability</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: #22c55e; border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Sep 15, 2025</div>
    <div style="color: var(--color-text);">Fix for OSCORE issue merged (<a href="https://github.com/obgm/libcoap/pull/1730">PR #1730</a>)</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: #22c55e; border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Sep 15, 2025</div>
    <div style="color: var(--color-text);">Fix for static buffer overflow merged (<a href="https://github.com/obgm/libcoap/pull/1737">PR #1737</a>)</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: var(--color-text-secondary); border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Sep 15, 2025</div>
    <div style="color: var(--color-text);">CVE requests submitted to MITRE for both issues</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: #22c55e; border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Nov 27, 2025</div>
    <div style="color: var(--color-text);">libcoap v4.3.5a released with patches for both vulnerabilities</div>
  </div>
  <div style="position: relative; padding-bottom: 1.25rem;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: #f59e0b; border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Dec 8, 2025</div>
    <div style="color: var(--color-text);">CVE-2025-59391 assigned by MITRE <span style="color: var(--color-text-secondary);">(85 days after request)</span></div>
  </div>
  <div style="position: relative;">
    <div style="position: absolute; left: -1.15rem; top: 0.35rem; width: 10px; height: 10px; border-radius: 50%; background: #f59e0b; border: 2px solid var(--color-bg);"></div>
    <div style="font-size: 0.75rem; color: var(--color-text-secondary); font-weight: 600;">Dec 31, 2025</div>
    <div style="color: var(--color-text);">CVE-2025-34468 assigned by <a href="https://vulncheck.com/">VulnCheck</a> <span style="color: var(--color-text-secondary);">(same day, MITRE never responded)</span></div>
  </div>
</div>
<p>We want to thank the libcoap team, particularly Jon Shallow, for their responsiveness in addressing these issues. The maintainer responded on the same day for both reports. Maintaining open-source security infrastructure is often thankless work, and their quick turnaround made the ecosystem safer.</p>
<h2 id="whats-next">What&rsquo;s Next</h2>
<p>These two CVEs are just a sample of what SecMate has found. We&rsquo;re continuing to analyze embedded codebases and report vulnerabilities through coordinated disclosure.</p>
<p>If you&rsquo;re curious about our other findings, check out our <a href="https://secmate.dev/disclosures?utm_source=blog&amp;utm_medium=body&amp;utm_campaign=libcoap-vulnerabilities-disclosure&amp;utm_content=security" rel="noopener noreferrer" target="_blank" data-cta-type="body_disclosures" data-post-slug="libcoap-vulnerabilities-disclosure" data-post-category="security">disclosure page</a>. And if you&rsquo;re building embedded systems and want to find vulnerabilities before attackers do, <a href="https://secmate.dev/register?utm_source=blog&amp;utm_medium=body&amp;utm_campaign=libcoap-vulnerabilities-disclosure&amp;utm_content=security" rel="noopener noreferrer" target="_blank" data-cta-type="body_register" data-post-slug="libcoap-vulnerabilities-disclosure" data-post-category="security">reach out</a>.</p>
<h2 id="references">References</h2>
<ul>
<li>
<p><a id="ref1"></a>[1] libcoap. &ldquo;libcoap - C-Implementation of CoAP&rdquo; <em>GitHub</em>. <a href="https://github.com/obgm/libcoap" rel="noopener noreferrer" target="_blank">Repository</a></p>
</li>
<li>
<p><a id="ref2"></a>[2] IETF. &ldquo;RFC 7252 - The Constrained Application Protocol (CoAP)&rdquo; <em>IETF Datatracker</em>, June 2014. <a href="https://datatracker.ietf.org/doc/html/rfc7252" rel="noopener noreferrer" target="_blank">RFC</a></p>
</li>
<li>
<p><a id="ref3"></a>[3] NVD. &ldquo;CVE-2025-34468 - Static Buffer Overflow in libcoap&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-34468" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
<li>
<p><a id="ref4"></a>[4] NVD. &ldquo;CVE-2025-59391 - Out-of-Bounds Read in libcoap&rdquo; <em>National Vulnerability Database</em>. <a href="https://nvd.nist.gov/vuln/detail/CVE-2025-59391" rel="noopener noreferrer" target="_blank">CVE</a></p>
</li>
</ul>
<hr>
<p><em>The SecMate Team</em></p>
]]></content:encoded><media:content url="https://blog.secmate.dev/images/og_image.jpg" medium="image"/></item></channel></rss>