<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://vulnerability.circl.lu</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Tue, 29 Sep 2026 22:13:19 +0000</lastBuildDate>
    <item>
      <title>CVE-2026-55526 — PraisonAI: SSRF protection bypass in `spider_tools._host_is_blocked()` via DNS-resolved hostnames (`127.0.0.1.nip.io`)</title>
      <link>https://vulnerability.circl.lu/vuln/cve-2026-55526</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; MervinPraison PraisonAI, MervinPraison praisonaiagents&lt;/p&gt;
&lt;p&gt;PraisonAI is a multi-agent teams system. Prior to praisonaiagents 1.6.58, spider_tools._host_is_blocked() does not resolve ordinary hostnames before scrape_page fetches them. A hostname such as 127.0.0.1.nip.io passes validation and resolves to loopback, permitting internal HTTP access. The fix uses socket.getaddrinfo and fails closed on DNS errors. This issue is fixed in version 1.6.58.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; MervinPraison PraisonAI, MervinPraison praisonaiagents&lt;/p&gt;
&lt;p&gt;PraisonAI is a multi-agent teams system. Prior to praisonaiagents 1.6.58, spider_tools._host_is_blocked() does not resolve ordinary hostnames before scrape_page fetches them. A hostname such as 127.0.0.1.nip.io passes validation and resolves to loopback, permitting internal HTTP access. The fix uses socket.getaddrinfo and fails closed on DNS errors. This issue is fixed in version 1.6.58.&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/cve-2026-55526</guid>
    </item>
    <item>
      <title>PYSEC-2026-3905 — praisonaiagents has an SSRF protection bypass in `spider_tools._host_is_blocked()` via DNS-resolved hostnames (`127.0.0…</title>
      <link>https://vulnerability.circl.lu/vuln/pysec-2026-3905</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: praisonaiagents&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;`praisonaiagents/tools/spider_tools.py` contains an SSRF protection bypass. The function
`_host_is_blocked()` validates URLs against a list of blocked IP literals and hostname
aliases, but **never performs DNS resolution**. Any hostname that resolves to a private or
loopback IP address — including public wildcard DNS services like `127.0.0.1.nip.io` —
bypasses the protection entirely.&lt;/p&gt;
&lt;p&gt;This has been **confirmed with a live exploit**: `scrape_page(&amp;#34;http://127.0.0.1.nip.io:PORT/secret&amp;#34;)`
makes an HTTP request to `127.0.0.1:PORT` and returns the internal service response.
No attacker-controlled infrastructure is required.&lt;/p&gt;
&lt;p&gt;`scrape_page`, `extract_links`, `crawl`, and `extract_text` are all registered as
LLM-callable agent tools (see `tools/__init__.py` lines 51-55), so any agent instructed
to fetch a user-supplied URL will trigger this path.&lt;/p&gt;
&lt;p&gt;This is a **new bypass** of prior fix commit `004dcfef` (GHSA-q9pw-vmhh-384g), which only
rejected IP literal encoding tricks (hex, octal, backslash). The fix was also applied to
`web_crawl_tools.py` (line 231: `socket.gethostbyname` call), but that fix was not
ported to `spider_tools.py`.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;**Root cause — `spider_tools.py` lines 26-65:**&lt;/p&gt;
&lt;p&gt;```python
def _host_is_blocked(hostname: str) -&amp;gt; bool:
    host = hostname.lower().rstrip(&amp;#34;.&amp;#34;)
    # Checks literal aliases only — never resolves
    if host in (&amp;#34;localhost&amp;#34;, &amp;#34;0.0.0.0&amp;#34;, &amp;#34;::1&amp;#34;):
        return True
    if host in (&amp;#34;169.254.169.254&amp;#34;, &amp;#34;metadata.google.internal&amp;#34;):…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; PyPI: praisonaiagents&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;`praisonaiagents/tools/spider_tools.py` contains an SSRF protection bypass. The function
`_host_is_blocked()` validates URLs against a list of blocked IP literals and hostname
aliases, but **never performs DNS resolution**. Any hostname that resolves to a private or
loopback IP address — including public wildcard DNS services like `127.0.0.1.nip.io` —
bypasses the protection entirely.&lt;/p&gt;
&lt;p&gt;This has been **confirmed with a live exploit**: `scrape_page(&amp;#34;http://127.0.0.1.nip.io:PORT/secret&amp;#34;)`
makes an HTTP request to `127.0.0.1:PORT` and returns the internal service response.
No attacker-controlled infrastructure is required.&lt;/p&gt;
&lt;p&gt;`scrape_page`, `extract_links`, `crawl`, and `extract_text` are all registered as
LLM-callable agent tools (see `tools/__init__.py` lines 51-55), so any agent instructed
to fetch a user-supplied URL will trigger this path.&lt;/p&gt;
&lt;p&gt;This is a **new bypass** of prior fix commit `004dcfef` (GHSA-q9pw-vmhh-384g), which only
rejected IP literal encoding tricks (hex, octal, backslash). The fix was also applied to
`web_crawl_tools.py` (line 231: `socket.gethostbyname` call), but that fix was not
ported to `spider_tools.py`.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;**Root cause — `spider_tools.py` lines 26-65:**&lt;/p&gt;
&lt;p&gt;```python
def _host_is_blocked(hostname: str) -&amp;gt; bool:
    host = hostname.lower().rstrip(&amp;#34;.&amp;#34;)
    # Checks literal aliases only — never resolves
    if host in (&amp;#34;localhost&amp;#34;, &amp;#34;0.0.0.0&amp;#34;, &amp;#34;::1&amp;#34;):
        return True
    if host in (&amp;#34;169.254.169.254&amp;#34;, &amp;#34;metadata.google.internal&amp;#34;):…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/pysec-2026-3905</guid>
    </item>
  </channel>
</rss>
