{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreibvgehvuiotq6pz6z3q4ssn4ol2zb36hd3a5zo52exzoncoz3fl3q",
"uri": "at://did:plc:uycvbmlz3vrjjgtyjzs4qtgh/app.bsky.feed.post/3moipxo7uwts2"
},
"coverImage": {
"$type": "blob",
"ref": {
"$link": "bafkreidsizu6hnffqlkyvxbyy6tizjh5opwr6cihnpe5tbl6cwsmotc3ta"
},
"mimeType": "image/png",
"size": 52317
},
"path": "/getkirby/kirby/releases/tag/5.4.4",
"publishedAt": "2026-06-17T16:23:36.122Z",
"site": "https://github.com",
"tags": [
"https://getkirby.com/buzz/security-update",
"section on this topic",
"@adrgs",
"@petersevera",
"GHSA-whxw-24jc-cwmv",
"GHSA-wr9h-4r83-f4v6",
"@shafiqaimanx",
"GHSA-rhj6-r49h-5932",
"GHSA-r3w8-2c5r-h9j9",
"@EvidentObscurity",
"GHSA-4v4h-m2qq-ppgw",
"GHSA-89cp-7p28-jffg",
"@adamyordan",
"GHSA-23q2-54qv-rq5x",
"8155",
"@samyouel",
"8166",
"8180",
"8186",
"8171",
"8185",
"8173",
"8184",
"8193",
"8192"
],
"textContent": "Note\n\nThis release is part of our monthly security release series. Find out more about those releases and their background on our website: https://getkirby.com/buzz/security-update\n\n## 🚨 Security\n\n### 🛎️ Recommendation to secure your content salt and cookie key values\n\nKirby internally relies on the following values:\n\n * The `content.salt` option is used to generate secure preview and media URLs that should not be guessable by external visitors.\n * The `Kirby\\Http\\Cookie::$key` property, to sign (or authenticate) cookie values to prevent easy tampering with cookie values that have been set from the backend.\n\n\n\n**We recommend to set the`content.salt` and `Kirby\\Http\\Cookie::$key` values to long random strings for all of your sites.**\n\nWe have updated the security guide with a section on this topic and added warnings to the Panel system view if Kirby detects the unchanged defaults.\n\nThanks to @adrgs and Peter Levashov (@petersevera) for their responsible disclosure and suggestion.\n\n* * *\n\n### **External Initialization of the Panel on reverse proxy setups with the`Forwarded`, `X-Client-IP` or `X-Real-IP` header**\n\nThis vulnerability affects Kirby sites that have no configured user accounts and are running on publicly accessible servers behind a reverse proxy that sets the `Forwarded: for=...`, `X-Client-IP`, or `X-Real-IP` request header.\n\nIt was possible to install the Panel (= create the first admin user) in these setups even from remote IP addresses.\n\n**This vulnerability is of critical severity for affected sites.**\n\nYour site is _not_ affected if any of the following apply:\n\n * An admin account has already been configured\n * The Panel and API are disabled\n * The site is not running behind a reverse proxy\n * The reverse proxy sets the `X-Forwarded-For` or `Client-IP` header instead of the affected ones.\n\n\n\nAdvisory Details:\n\n * **CVE ID:** CVE-2026-54003\n * **Severity:** critical (CVSS score 9.1)\n * **Advisory:** GHSA-whxw-24jc-cwmv\n\n\n\nThanks to Peter Levashov (@petersevera) for responsibly reporting the identified issue.\n\n* * *\n\n### **Cross-site scripting (XSS) from incomplete HTML/XML sanitization in`Dom::sanitize()`**\n\nThis vulnerability affects Kirby sites and plugins that use the `writer` or `list` fields or that use `$dom->sanitize()`, `Sane::sanitize()`, `Sane\\Html::sanitize()`, `Sane\\Svg::sanitize()`, `Sane\\Xml::sanitize()`, `Sane::sanitizeFile()` or `$file->sanitizeContents()` with untrusted input.\n\nIt was possible to inject malicious markup as children of an unknown HTML/XML tag, which would then be passed through `Dom::sanitize()` without being correctly sanitized according to the provided sanitization rules, causing a cross-site scripting (XSS) risk.\n\n**This vulnerability is of high severity for affected sites.**\n\nThe default file upload protection is _not_ affected, so sites that only _validate_ uploaded files are not exposed to this vulnerability. The vulnerability can only be exploited by authenticated users.\n\n * **CVE ID:** CVE-2026-54002\n * **Severity:** high (CVSS score 8.5)\n * **Advisory:** GHSA-wr9h-4r83-f4v6\n\n\n\nThanks to Shafiq Aiman (@shafiqaimanx) for responsibly reporting the identified issue.\n\n* * *\n\n### **Self cross-site scripting (self-XSS) in the writer field**\n\nThis vulnerability affects Kirby sites that use the writer field in any blueprint.\n\nIt was possible to include a scripting link as the target of a link (or email link). This link target would then be clickable by the user who entered it.\n\nA successful attack commonly requires knowledge of the content structure by the attacker as well as social engineering of a user with access to the Panel. The attack _cannot_ be automated.\n\nIn Kirby's default configuration, the vulnerability is limited to self-XSS and _cannot_ directly affect other users or visitors of the site. Panel plugins that are directly using the `<k-writer>` component may also be affected by stored XSS if they don't sanitize the resulting HTML before saving it to the content.\n\n**This vulnerability is of high severity for affected sites.**\n\n * **CVE ID:** CVE-2026-49276\n * **Severity:** high (CVSS score 7.4)\n * **Advisory:** GHSA-rhj6-r49h-5932\n\n\n\n* * *\n\n### **`pages.access` permission is not checked in the `site/find` REST API route**\n\nThis vulnerability affects all Kirby sites where users of a particular role have no permission to access pages (`pages.access` permission is disabled). This can be due to configuration in the user blueprint(s), `options` in the model blueprint(s), or a combination of both settings.\n\nIt was possible to retrieve page information (including full content and metadata) for arbitrary pages via the `/api/site/find` route without being authorized to access the respective pages.\n\n**This vulnerability is of high severity for affected sites.**\n\nYour Kirby sites are _not_ affected if you intend all users of your site to be able to access all pages of the site. The vulnerability can only be exploited by authenticated users that know or guess the IDs or UUIDs of pages. Write actions as well as access to draft pages are _not_ affected by this vulnerability.\n\n * **CVE ID:** CVE-2026-54005\n * **Severity:** high (CVSS score 7.1)\n * **Advisory:** GHSA-r3w8-2c5r-h9j9\n\n\n\nThanks to Rizky Muhammad (@EvidentObscurity) for responsibly reporting the identified issue.\n\n* * *\n\n### **Request header injection in`Http\\Remote`**\n\nThis vulnerability affects Kirby sites and plugins that use the `Kirby\\Http\\Remote` class (including `Remote::request()`, `Remote::get()`, `Remote::post()`, and similar helpers) to send outgoing HTTP requests and that pass untrusted, user-controlled data into the `headers` option of such a request.\n\nBy including newline characters in the value of the header, it was possible to inject a separate, independent header that was not intended to be set.\n\nA successful attack requires that an application or plugin forwards attacker-influenced input into a request header value. Sites that only send static, developer-defined headers are _not_ affected. The attack does not target Panel users or site visitors directly; it targets the remote service that Kirby connects to.\n\nIn Kirby's default configuration, the `Remote` class is not exposed to untrusted input, so a default installation is _not_ affected. The vulnerability becomes relevant for custom code, plugins, or integrations that build request headers from user input.\n\n * **CVE ID:** CVE-2026-50188\n * **Severity:** moderate (CVSS score 6.9)\n * **Advisory:** GHSA-4v4h-m2qq-ppgw\n\n\n\n* * *\n\n### **Access to files of top-level drafts is not protected by permissions**\n\nThis vulnerability affects Kirby 5 sites that have the `content.fileRedirects` option enabled (set to `true` or a custom closure) as well as all Kirby 4 sites that haven't explicitly disabled this option.\n\nIt was possible to access clean file URLs of top-level drafts (e.g. `/about-us/team.jpg`) without providing authentication, without being authorized to access the top-level draft page, and without providing a valid preview token.\n\nSites on Kirby 5 using the default configuration are _not_ affected by this vulnerability (the `content.fileRedirects` option is disabled by default since Kirby 5.0.0). It was also _not_ possible to maliciously access clean file URLs for files stored in page drafts that are not on the top-level (such as `/blog/article/resource.pdf`).\n\n * **CVE ID:** CVE-2026-54004\n * **Severity:** moderate (CVSS score 6.3)\n * **Advisory:** GHSA-89cp-7p28-jffg\n\n\n\nThanks to @adamyordan for responsibly reporting the identified issue.\n\n* * *\n\n### **`pages.access` permission is not checked in the pages picker for parent pages**\n\nThis vulnerability affects all Kirby sites that use the `pages` field and where users of a particular role have no permission to access pages (`pages.access` permission is disabled). This can be due to configuration in the user blueprint(s), `options` in the model blueprint(s), or a combination of both settings.\n\nIt was possible to confirm the existence of arbitrary pages and to retrieve the value of the title field of the pages found.\n\nThe vulnerability can only be exploited by authenticated users. Write actions are _not_ affected by this vulnerability.\n\n * **CVE ID:** CVE-2026-49274\n * **Severity:** moderate (CVSS score 5.3)\n * **Advisory:** GHSA-23q2-54qv-rq5x\n\n\n\n* * *\n\n## 🚨 Security fixes\n\n * The `link` and `email` marks of the `writer` field are now protected against self-cross site scripting (self-XSS) from inserted scripting links\n * The page picker in the `pages` field now consistently checks the `pages.access` permission for the provided parent page\n * Results of the `site/find` API route are now filtered to only return pages that are accessible to the current user.\n * Files on draft pages are no longer exposed through clean file URLs when `content.fileRedirects` is enabled.\n * Kirby no longer allows to install the Panel with the first user account if a `Forwarded: for=...`, `X-Client-IP` or `X-Real-IP` request header with external IP address was provided by a reverse proxy.\n * Show warnings in the system view when the `content.salt` option and `Cookie::$key` default values have not been changed.\n\n\n\n* * *\n\n## ✨ Enhancements\n\n * Harden TOTP token verification against timing leaks using constant-time verification\n * New `$helper.url.hasDangerousScheme(url)` JS helper\n * New `$helper.string.isEmail(string, strict)` helper\n * New `cookie.key` option to allow setting the `Kirby\\Http\\Cookie::$key` directly from the config\n\n\n\n* * *\n\n## 🐛 Bug fixes\n\n * Account view: Fixed showing prev-next navigation buttons #8155 (thx @samyouel)\n * `Kirby\\Http\\Environment` now correctly extracts the `for=` value from the standardized `Forwarded` header, fixing `::isLocal()` detection behind certain proxies. #8166\n * Alt+click on email links in writer fields opens a new email to this address in the default email client\n * Pasting email addresses with modern TLDs are now also converted to email links in writer fields\n * Database queries: ensure columns exist in `->where()` and `->having()` clauses instead of simply dropping non-existing columns from those clauses #8180\n * Fixed handling of invalid JSON in `Kirby\\Image\\Focus::normalize()` #8186\n * The `(date:)` KirbyTag now escapes its output to prevent HTML being injected through special characters in the tag value. Thanks to Peter Levashov (@petersevera) for his responsible disclosure and suggestion.\n * `Html::gist()` now only embeds Gists from `gist.github.com`, so it can no longer load scripts from arbitrary URLs. Thanks to Peter Levashov (@petersevera) for his responsible disclosure and suggestion.\n * Fixed blueprint field lookups with normalized field keys for mixed-case field names #8171\n * Escape attributes of `Kirby\\Image\\QrCode::toSvg()` #8185\n * Throw error when QR code data exceeds the capacity of the max version #8185\n * Fixed content meta data (editor & modified timestamp) to fall back to the current language when no active lock exists (`Kirby\\Content\\Lock::for()` uses current language for fallback) #8173\n * Prevent division-by-zero crashed in `Kirby\\Image\\Location::num()` through malformed EXIF data #8184\n * Fixed TypeError in PageTree.preselect when refs are cleared #8193\n * The quote block no longer ignores the node configuration from the blueprint. #8192\n\n\n\n* * *\n\n## 🚨 Breaking changes\n\n * `Html::gist()` (and the `(gist:)` tag) now ignores URLs from hosts other than `gist.github.com`. Sites embedding Gists from a custom host (e.g. GitHub Enterprise) can re-allow it via `Kirby\\Toolkit\\Html::$gistDomains[] = 'gist.example.com';`.\n\n",
"title": "5.4.4",
"updatedAt": "2026-06-17T11:00:04.000Z"
}