# Zrok Python ProxyShare can be used as an SSRF proxy through absolute URL paths

**URL:** <https://openziti.discourse.group/t/zrok-python-proxyshare-can-be-used-as-an-ssrf-proxy-through-absolute-url-paths/5828>\
**Category:** Security Adivsories\
**Created:** [May 13, 2026, 12:46pm UTC](https://openziti.discourse.group/t/zrok-python-proxyshare-can-be-used-as-an-ssrf-proxy-through-absolute-url-paths/5828 "2026-05-13T12:46:05Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike.gorman](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/mike.gorman/32/7_2.png) [@mike.gorman](https://openziti.discourse.group/u/mike.gorman)\
**Post date:** [May 13, 2026, 12:46pm UTC](https://openziti.discourse.group/t/zrok-python-proxyshare-can-be-used-as-an-ssrf-proxy-through-absolute-url-paths/5828/1 "2026-05-13T12:46:05Z")

</div>

## CVE-2026-45568

## **Summary**

Alice exposes a Python SDK `ProxyShare` with a fixed target URL. Bob sends a request to the share with an absolute URL in the path. The Flask handler passes that path to `urllib.parse.urljoin`, which replaces Alice's configured target host with Bob's host and returns the server-side response to Bob.

## **Details**

The Python SDK proxy route accepts every path under the share:

```auto
@app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
def proxy(path):

```

It constructs the outbound URL with `urljoin` and then sends the request:

```auto
url = urllib.parse.urljoin(self.target, path)
resp = requests.request(
    method=request.method,
    url=url,
    headers={key: value for (key, value) in request.headers
             if key.lower() not in HOP_BY_HOP_HEADERS},
    data=request.get_data(),
    cookies=request.cookies,
    allow_redirects=False,
    stream=True,
    verify=self.verify_ssl
)

```

When `path` is `[``http://127.0.0.1:19190/metadata`]([http://127.0.0.1:19190/metadata%60](http://127.0.0.1:19190/metadata%60)), `urljoin(self.target, path)` returns `[``http://127.0.0.1:19190/metadata`]([http://127.0.0.1:19190/metadata%60](http://127.0.0.1:19190/metadata%60)). The proxy sends the request to Bob's chosen URL rather than Alice's target.

**Package**

**zrok**

## **Affected versions**

v0.4.47 - v2.0.2

## **Patched versions**

2.0.3

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:L

Thanks go to aisafe-bot for reporting this issue.
