Skip to content

Commit 03ee9fe

Browse files
1 parent cb2c12a commit 03ee9fe

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-g2j9-g8r5-rg82",
4+
"modified": "2025-11-14T20:33:36Z",
5+
"published": "2025-11-14T20:33:35Z",
6+
"aliases": [
7+
"CVE-2025-64714"
8+
],
9+
"summary": "PrivateBin's template-switching feature allows arbitrary local file inclusion through path traversal",
10+
"details": "## Summary\n\nAn unauthenticated Local File Inclusion exists in the template-switching feature: if `templateselection` is enabled in the configuration, the server trusts the `template` cookie and includes the referenced PHP file. An attacker can read sensitive data or, if they manage to drop a PHP file elsewhere, gain RCE.\n\n## Affected versions\n\nPrivateBin versions since 1.7.7.\n\n## Conditions\n\n- `templateselection` got enabled in `cfg/conf.php`\n- Visitor sets a cookie `template` pointing to an existing PHP file without it's suffix, using a path relative to the `tpl` folder. Absolute paths do not work.\n\n## Impact\n\nThe constructed path of the template file is checked for existence, then included. For PrivateBin project files this does not leak any secrets due to data files being created with PHP code that prevents execution, but if a configuration file without that line got created or the visitor figures out the relative path to a PHP script that directly performs an action without appropriate privilege checking, those might execute or leak information.\n\n### Impact analysis\nIn detail, we have analyzed different ways of exploiting this vulnerability and found no way to cause a full remote code execution (RCE) vulnerability or denial of service (DoS) as recursive includes, e.g., are not possible.\n\nGenerally, it is again notably to remember only PHP files of the local filesystem can be included. That's why potentially at risk PrivateBin PHP files have been analyzed.\n\n* the PrivateBin config file is by default [protected as it prevents access itself](https://github.com/PrivateBin/PrivateBin/blob/591d2d40e16a196aa628e3962a1c21bdf9793db2/cfg/conf.sample.php#L1) resulting in a 403 HTTP status code. This is called the “(PHP) protection line”.\n* Likewise, the paste data cannot be accessed due to that “protection line”. [Each created file contains the same line protecting it against](https://github.com/PrivateBin/PrivateBin/blob/591d2d40e16a196aa628e3962a1c21bdf9793db2/lib/Data/Filesystem.php#L46) PHP execution/inclusion.\n* As for the `salt`, `purge_` and `traffic_limiter` files, they get included, but no data is displayed (variables or comments only), and a webserver specific error message is returned.\n* When one tries to include `index.php`, you get a PHP error (possibly visible, depending on the webserver setup), due to define being called twice.\n* With any of the files in lib and likely those in vendor (we have not verified each dependency), code is only declared and not executed and the result is again a webserver specific error message.\n* With the scripts in bin, the result is an error message, but code is executed to some extent, but you cannot pass arguments to any administrative scripts [as they are read via `$_SERVER['argc']`](https://github.com/PrivateBin/PrivateBin/blob/d32ac29925066c668241a165264c76de051398e3/bin/administration#L357C37-L357C54).\n\nThat said, the vulnerability could be used to chain more attacks or execute other non-PrivateBin related PHP files on the host system, if such other files exist and the (relative) path to them can be guessed.\nAlso, should for some reason the PHP “protection line” be missing on your deployment the impact could be much worse and e.g. data like the URL shortener token or the database configuration from the configuration file could possibly be exfiltrated.\n\n### Real-life impact\n\nPrivateBin has checked all instances versioned 1.7.7 and above listed in the [PrivateBin directory](https://privatebin.info/directory/) and did find 11 instances that had the template switcher enabled. The following script was used to detect this:\n\n```shell\nfor URL in $(\n curl --silent --header 'Accept: application/json' 'https://privatebin.info/directory/api?top=100&version=1.7.7' | jq --raw-output '.[].url'\n) $(\n curl --silent --header 'Accept: application/json' 'https://privatebin.info/directory/api?top=100&version=1.7.8' | jq --raw-output '.[].url'\n) $(\n curl --silent --header 'Accept: application/json' 'https://privatebin.info/directory/api?top=100&version=2' | jq --raw-output '.[].url'\n)\ndo\n curl --silent \"$URL\" | grep -q 'id=\"template\"' && echo \"$URL uses template switcher\"\ndone\n```\n\nNone of these instances had an unprotected PrivateBin configuration file in use. The following script was used and may be adapted to check any single instance:\n\n```shell\ncurl --silent --cookie 'template=../cfg/conf' https://privatebin.net\n```\n\n## Technical Description\n\nUsers can select their preferred template via the `template` cookie, as seen in `TemplateSwitcher::getSelectedByUserTemplate`:\n\n```php\n private static function getSelectedByUserTemplate(): ?string\n {\n $selectedTemplate = null;\n $templateCookieValue = $_COOKIE['template'] ?? '';\n\n if (self::isTemplateAvailable($templateCookieValue)) {\n $selectedTemplate = $templateCookieValue;\n }\n\n return $selectedTemplate;\n }\n```\n\nIn [this commit](44f8cfbfb8df4b4bec1cbf79aa8ce51abdb18be3), introduced in 1.7.7, the `TemplateSwitcher::isTemplateAvailable` method went from this:\n\n```php\n public static function isTemplateAvailable(string $template): bool\n {\n return in_array($template, self::getAvailableTemplates());\n }\n```\n\nto this:\n\n```php\n public static function isTemplateAvailable(string $template): bool\n {\n $available = in_array($template, self::getAvailableTemplates());\n\n if (!$available && !View::isBootstrapTemplate($template)) {\n $path = View::getTemplateFilePath($template);\n $available = file_exists($path);\n }\n\n return $available;\n }\n```\n\nThe new code will now blindly trust `$template`, unless it starts with the string `bootstrap-`.\n\n`View::getTemplateFilePath` will return `PATH . 'tpl' . DIRECTORY_SEPARATOR . $file . '.php'`, allowing directory traversal, but preventing non-PHP files to be included.\n\n`View::draw` will then include the user-submitted template:\n\n```php\n public function draw($template)\n {\n $path = self::getTemplateFilePath($template);\n if (!file_exists($path)) {\n throw new Exception('Template ' . $template . ' not found!', 80);\n }\n extract($this->_variables);\n include $path;\n }\n```\n\n**Note:** this is only possible if `templateselection` configuration is enabled, or if no template has been set. The `template` will be rewritten if this condition isn't met:\n\n```php\n private function _setDefaultTemplate()\n {\n $templates = $this->_conf->getKey('availabletemplates');\n $template = $this->_conf->getKey('template');\n TemplateSwitcher::setAvailableTemplates($templates);\n TemplateSwitcher::setTemplateFallback($template);\n\n // force default template, if template selection is disabled and a default is set\n if (!$this->_conf->getKey('templateselection') && !empty($template)) {\n $_COOKIE['template'] = $template;\n setcookie('template', $template, array('SameSite' => 'Lax', 'Secure' => true));\n }\n }\n```\n\n### Reproduction Steps\n\n1. Configure PrivateBin with templateselection = true (default template list is fine).\n2. Send a request with a malicious template cookie like `template=../cfg/conf`, where the relative path points to a PHP file without its file suffix\n3. The script now includes the select PHP file (leading to a 500 in that specific case).\n\n## Mitigation\n\n### Patches\n\nThe issue has been patched in version 2.0.3.\n\n### Workarounds\n\nSet `templateselection = false` in `cfg/conf.php` or remove it, it's default is `false`.\n\n## Credits\n\nPrivateBin would like to thank [Benoit Esnard](https://github.com/esnard), who reported this vulnerability.\n\nIn general, PrivateBin would like to thank everyone reporting issues and potential vulnerabilities to us.\n\nIf a user suspects they have found a vulnerability or potential security risk, [PrivateBin kindly asks them to follow the security policy](https://github.com/PrivateBin/PrivateBin/blob/master/SECURITY.md) and report it to PrivateBin. After submssion the report is assessed and necessary actions will be taken to address it.\n\n## Timeline\n\n- 2025-11-09 Received report via GitHub Security Advisory\n- 2025-11-10 Discussed and reproduced issue, wrote a unit test case based on this, started work on a patch\n- 2025-11-11 Further work on patch, refactored related code\n- 2025-11-12 Released patch with PrivateBin 2.0.3",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "privatebin/privatebin"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "1.7.7"
29+
},
30+
{
31+
"fixed": "2.0.3"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/PrivateBin/PrivateBin/security/advisories/GHSA-g2j9-g8r5-rg82"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-64714"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/PrivateBin/PrivateBin/commit/4434dbf73ac53217fda0f90d8cf9b6110f8acc4f"
50+
},
51+
{
52+
"type": "PACKAGE",
53+
"url": "https://github.com/PrivateBin/PrivateBin"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-23",
59+
"CWE-73",
60+
"CWE-98"
61+
],
62+
"severity": "MODERATE",
63+
"github_reviewed": true,
64+
"github_reviewed_at": "2025-11-14T20:33:35Z",
65+
"nvd_published_at": "2025-11-13T16:15:56Z"
66+
}
67+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-r9x7-7ggj-fx9f",
4+
"modified": "2025-11-14T20:33:52Z",
5+
"published": "2025-11-14T20:33:52Z",
6+
"aliases": [
7+
"CVE-2025-64711"
8+
],
9+
"summary": "PrivateBin vulnerable to malicious filename use for self-XSS / HTML injection locally for users",
10+
"details": "## Summary\n\nDragging a file whose filename contains HTML is reflected verbatim into the page via the drag-and-drop helper, so any user who drops a crafted file on PrivateBin will execute arbitrary JavaScript within their own session (self-XSS). This allows an attacker who can entice a victim to drag or otherwise attach such a file to exfiltrate plaintext, encryption keys, or stored pastes before they are encrypted or sent.\n\n**Note 1:** as the malicious filename must contain the `>` character, the victim must not be using Windows for this to work, since this OS simply forbids this character in filenames.\n\n**Note 2:** most PrivateBin instances use the Content-Security-Policy header to prevent most use-cases of this vulnerability. This report will describe the impact as if this header had been disabled by the PrivateBin instance owner.\n\n## Affected versions\n\nPrivateBin versions since 1.7.7.\n\n## Conditions\n\n* Only macIOS or Linux users are affected, due to the way the `>` character is treated in a file name on Windows.\n* The PrivateBIn instance needs to have file upload enabled.\n* An attacker needs to have access to the local file system or somehow convince the user to create (or download) a malicious file (name).\n* An attacker needs to convince the user to attach that malicious file to PrivateBin.\n\n## Impact\n\nAny Mac / Linux user who can be tricked into dragging a maliciously named file into the editor is impacted; code runs in the origin of the PrivateBin instance they are using. Attackers can steal plaintext, passphrases, or manipulate the UI before data is encrypted, defeating the zero-knowledge guarantees for that victim session, assuming counter-measures like Content-Security-Policy (CSP) have been disabled.\n\nIf CSP is not disabled, similar HTML injection attacks as described in CVE-2025-62796 may be possible - like redirecting to a foreign website, phishing etc.\n\n### Real-life impact\n\nAs the whole exploit needs to be included in the file name of the attached file and only affects the local session of the user (aka it is neither persistent nor remotely executable) _and_ that user needs to interact and actively attach that file to the paste, the impact is considered to be practically low.\n\n## Technical Description\n\nWhen a file is dropped, `readFileData` collects all filenames and calls `printDragAndDropFileNames`:\n\n```js\nconst fileNames = loadedFiles.map((loadedFile => loadedFile.name));\nprintDragAndDropFileNames(fileNames);\n```\n\n`printDragAndDropFileNames` then renders those names:\n\n```js\n function printDragAndDropFileNames(fileNames) {\n $dragAndDropFileNames.html(fileNames.join('<br>'));\n }\n```\n\nThis will insecurely render the user-submitted filenames as HTML.\n\nThis vulnerability has been introduced in [this commit](https://github.com/PrivateBin/PrivateBin/commit/095a5be0b6390a6e47b97d3668a23f6edec95c15) (introduced in 1.7.7).\n\nThe previous render method was using `.text()`:\n\n```js\n$dragAndDropFileName.text(loadedFile.name);\n```\n\n## Reproduction Steps\n\n1. On a Unix-like system, create a file with an HTML/JS payload in its name, e.g. by running `touch '\"><img src=x onerror=alert(document.domain)>.txt'`.\n2. Deploy or use any PrivateBin instance with attachments enabled (including https://privatebin.net/).\n3. Open the UI in a browser and start a new paste.\n4. Drag the crafted file anywhere on the page\n5. As soon as it is dropped, the filename is inserted into `#dragAndDropFileName` as HTML and the onerror handler fires (assuming CSP is disabled), showing the alert.\n\n## Mitigation\n\nPrivateBin strongly recommends users to **upgrade to the latest release**. However, here are some workarounds that may help users to mitigate this vulnerability without upgrade:\n\n* Update the [CSP in your configuration file](https://github.com/PrivateBin/PrivateBin/wiki/Configuration#cspheader) to the latest recommended settings and check that it isn't getting reverted or overwritten by the web server, reverse proxy or CDN, i.e. using [PrivateBin's offered check service](https://privatebin.info/directory/check).\n **Note:** Users should check the CSP independently, even if they've upgrade to a fixed version.\n* Deploying PrivateBin on a separate domain may limit the scope of the vulnerability to PrivateBin itself and thus, as described in the “Impact” section, effectively prevent any damage by the vulnerability to other resources users are hosting.\n* As explained in the impact assessment, disabling attachments also prevents this issue.\n\n### Patches\n\nThe issue has been patched in version 2.0.3.\n\n## Credits\n\nPrivateBin would like to thank [Benoit Esnard](https://github.com/esnard), who reported this vulnerability.\n\nIn general, PrivateBin would like to thank everyone reporting issues and potential vulnerabilities.\n\nIf a user thinks they have found a vulnerability or potential security risk, [PrivateBin would kindly ask you to follow our security policy](https://github.com/PrivateBin/PrivateBin/blob/master/SECURITY.md) and report it. PrivateBin will then assess the report and will take the necessary actions to address it.\n\n## Timeline\n\n- 2025-11-09 Received report via GitHub Security Advisory\n- 2025-11-10 Discussed and reproduced issue, created a patch\n- 2025-11-11 Further work on patch\n- 2025-11-12 Released patch with PrivateBin 2.0.3",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:L/I:L/A:N"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "privatebin/privatebin"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "1.7.7"
29+
},
30+
{
31+
"fixed": "2.0.3"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/PrivateBin/PrivateBin/security/advisories/GHSA-r9x7-7ggj-fx9f"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-64711"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/PrivateBin/PrivateBin/commit/f9550e513381208b36595ee2404e968144bba78b"
50+
},
51+
{
52+
"type": "PACKAGE",
53+
"url": "https://github.com/PrivateBin/PrivateBin"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-79"
59+
],
60+
"severity": "LOW",
61+
"github_reviewed": true,
62+
"github_reviewed_at": "2025-11-14T20:33:52Z",
63+
"nvd_published_at": "2025-11-13T03:16:29Z"
64+
}
65+
}

0 commit comments

Comments
 (0)