Skip to content

Releases: getkirby/kirby

5.4.0

23 Apr 08:14
8006161

Choose a tag to compare

🚨 Security

Server-Side Template Injection (SSTI) via double template resolution in option rendering

This vulnerability affects all Kirby sites that use option fields (checkboxes, color, multiselect, select, radio, tags or toggles) with options from a query or API whose values may not be fully trusted. It also affects direct uses of the OptionsApi or OptionsQuery classes of Kirby's Options package from plugin or site code. The attack requires either an
attacker in the group of authenticated Panel users or user interaction of another authenticated user.

This vulnerability is of high severity for affected sites.

Your Kirby sites are not affected if you are not using any of the mentioned fields or the Options package, if all options are defined statically in the blueprints or if all dynamically gathered options are to be trusted.

Thanks to @offset for responsibly reporting the identified issue.

Page, file and user creation APIs bypass create permission check via unfiltered blueprint parameter

This vulnerability affects all Kirby sites where users of a particular role have no permission to create pages, files or users (pages.create, files.create or users.create permission is disabled). This can be due to configuration in the user blueprint(s), via options in the model blueprint(s) or via a combination of both settings.

This vulnerability is of high severity for affected sites.

Your Kirby sites are not affected if you intend all users of your site to be able to create pages, files and users. The vulnerability can only be exploited by authenticated users.

Thanks to @offset for responsibly reporting the identified issue.

pages.access/list and files.access/list permissions are not consistently checked in the Panel and REST API

This vulnerability affects all Kirby sites where users of a particular role have no permission to access or list pages or files (pages.access, pages.list, files.access or files.list permission is disabled). This can be due to configuration in the user blueprint(s), via options in the model blueprint(s) or via a combination of both settings.

This vulnerability is of high severity for affected sites.

Your Kirby sites are not affected if you intend all users of your site to be able to access all pages and files of the site. The vulnerability can only be exploited by authenticated users.
Write actions are not affected by this vulnerability.

Read access to site, user and role information is not gated by permissions

This vulnerability affects all Kirby sites that might have potential attackers in the group of authenticated Panel users.

This vulnerability is of high severity for affected sites.

Your Kirby sites are not affected if you intend all users of your site to be able to list and access the site model and all users and roles, including the content stored within these models.
Write actions are not affected by this vulnerability as they were gated by permissions before.

Thanks to @HuajiHD for responsibly reporting the identified issue.

XML Injection in the XML creator toolkit

This vulnerability only affects Kirby sites that use the Xml data handler (e.g. Data::encode($string, 'xml')) or the Xml::create(), Xml::tag() or Xml::value() method(s) in site or plugin code. The Kirby core does not use any of the affected methods.

If you use an affected method and cannot rule out input to these methods controlled by an attacker, we strongly recommend to update to a patch release.

Thanks to Patrick Falb (@dapatrese) at FORMER 03 for responsibly reporting the identified issue.

User avatar creation, replacement and deletion are not gated by user update permissions

This vulnerability affects all Kirby sites where users of a particular role have no permission to update user information (user.update or users.update permission is disabled). This can be due to configuration in the blueprint(s) of the acting users, via options in the blueprint(s) of the target users or via a combination of both settings.

Your Kirby sites are not affected if you intend all users of your site to be able to upload, replace or delete user avatars. The vulnerability can only be exploited by authenticated users.

Page creation API bypasses changeStatus permission check via unfiltered isDraft parameter

This vulnerability affects all Kirby sites where users have the permission to create pages (pages.create permission is enabled) but not the permission to change the status of pages (pages.changeStatus permission is disabled). This can be due to configuration in the user blueprint(s), via options in the page blueprint(s) or via a combination of both settings.

Your Kirby sites are not affected if your use case does not consider the creation of published pages a malicious action. The vulnerability can only be exploited by authenticated users.

Thanks to @offset for responsibly reporting the identified issue.

System API endpoint leaks installed version and license data to authenticated users

This vulnerability affects all Kirby sites that might have potential attackers in the group of authenticated Panel users.

Thanks to @HuajiHD and @0x-bala for responsibly reporting the identified issue.

✨ Enhancements

  • Site permissions
    • New access permission for the site
    • New Kirby\Cms\Site::isAccessible() method checking if the current user has access permission for the site
    • New static Kirby\Cms\Find::site() method returning the site object or throwingKirby\Exception\NotFoundException if the site is not accessible
    • New i18n string error.site.notAccessible added to i18n/translations/en.json
  • User permissions
    • New access and list permissions for users and the current user.
    • New Kirby\Cms\User::isAccessible() method checking if the current user has access permission for a given user
    • New Kirby\Cms\User::isListable() method checking if a user is both accessible and has list permission. Inaccessible users are implicitly not listable
    • New static Kirby\Cms\Find::users() method returning only users filtered by isListable()
  • Role permissions
    • New Kirby\Cms\Role::isAccessible() method checking if the current user has users.access or user.access permission. If the role is the same role as the user's, the user.access permissions are checked. Otherwise users.access.
    • New static Kirby\Cms\Find::role() and Kirby\Cms\Find::roles() methods returning only roles filtered by isAccessible()
    • Added a new error.role.notFound translation key.
  • Avatar permissions
    • New avatar hooks user.createAvatar, user.replaceAvatar, user.deleteAvatar (including :before and :after)
    • New User class methods: User::createAvatar(), User::replaceAvatar(), User::deleteAvatar()
    • New User rules: UserRules::createAvatar(), UserRules::replaceAvatar(), UserRules::deleteAvatar(), UserRules::validAvatar()

🚨 Security fixes

  • The GET /system API route now consistently filters the relevant set of information by current system state
  • Kirby\Cms\Find::parent() now uses Kirby\Cms\Find::site() instead of $kirby->site() for the site model lookup
  • Kirby\Cms\Api::site() now delegates to Kirby\Cms\Find::site() instead of $this->kirby->site()
  • config/api/models/System.php the title field now reads directly from $this->kirby()->site() to bypass the site.access permission check, ensuring the title is always available
  • The page.move dialog now uses Kirby\Cms\Find::site() in the submit handler, when a page gets moved to the top-level
  • Kirby\Cms\Find::user() now enforces isAccessible() on the resolved user, throwing Kirby\Exception\NotFoundException if the user exists but is inaccessible
  • API routes (config/api/routes/users.php): all `$this->user()...
Read more

4.9.0

23 Apr 08:14

Choose a tag to compare

🚨 Security

This is a backport of our security release for Kirby 5. For all details and vulnerabilities see: https://github.com/getkirby/kirby/releases/tag/5.4.0

We recommend all users upgrade to Kirby 5. If an upgrade is not possible, this security release is the alternative solution.

5.3.3

26 Mar 11:47
90c285c

Choose a tag to compare

🐛 Bug fixes

  • Pages section table index resets to 1 on each pagination page #8002
  • Added missing return types to Kirby\Cms\Responder #8013
  • Disabling PHP's post_max_size no longer causes uploads to fail. #8022
  • Fixed the Panel offline warning dialog text in dark mode #8047
  • Fixed site view buttons when home preview is false #8046
  • Added labels to the blocks field options button and the form controls more button (thanks @FlorianBoe) #8035

🧹 Housekeeping

  • Improve test coverage for the Database package #8021
  • Updated JS dependencies

5.3.2

03 Mar 13:12
bbb64db

Choose a tag to compare

🐛 Bug fixes

  • Child page content no longer includes parent’s content after using page create dialog #7970
  • Url::to() strips content representation extension on multilang sites #7965
  • Prevent duplicate draft when using page.create:after hook (Kirby 5.3.x) #7957

🧹 Housekeeping

  • Switch to type module #7962
  • Upgrade JS and PHP dependencies

5.3.1

16 Feb 19:46
0ccfcab

Choose a tag to compare

✨ Enhancements

  • Updated translation (tr)

🐛 Bug fixes

  • Using $users->find() with more than one argument or $field->toUsers()/$field->toUser() no longer results in unfiltered collections. #7943
  • Calling $users->find(false) no longer loads an invalid empty user object. #7952
  • $lazyCollection->prepend() and $users->prepend() ensure the intended element order even if the collection was not initialized before. #7952
  • $lazyCollection->empty() and $users->empty() no longer result in populated collections if the original collection was not initialized before. #7952
  • Toggle field: Fixed duplicate display of field icon #7939
  • Fixed styling of tags with icons (e.g. link field preview) #7938
  • Fixed view button actions on the file view #7954

🧹 Housekeeping

  • Add missing code comments on the behavior of $collection->find(false, false, ...$data) #7952
  • Updated CI config for backend tests

5.3.0

10 Feb 12:31
3e14463

Choose a tag to compare

Caution

Unfortunately the Kirby 5.3.0 release introduced a regression in the user handling that leads to wrong results when using $users->find(), $field->toUsers() or $field->toUser(). All of these wrongly return the entire set of users without filtering.

Please update to Kirby 5.3.1 or later.


🎉 Features

  • Support for option icons in checkboxes, multiselect, radio and tags field #7673
    image
    image
    image
  • New <k-code-token> component and global styles for inline <code> elements with data-type attribute. The styles for the colored inline elements have been taken from our lab examples and are now available anywhere. The type can either be a generic type (string, float, bool, etc.) or a color keyword from our design system (green, red, orange, etc.) #7765
    image
  • New <k-stack> component to help with horizontal and vertical layouts. Think of it as a flex layout helper component. It's perfect to create equal gaps between elements in a column or row. E.g. different sections or the gap between the headline and contents of a container. #7766
    image
    You can either use the component as a wrapper (which will create a div):
    <k-stack>
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    </k-stack>    
    … or use the k-stack class on an existing wrapper element to inherit the basic stack styles:
    <ul class="k-stack">
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </ul>    
    Use the attributes gap, direction, align and justify to control the layout.
    <k-stack gap="var(--spacing-12)" align="center" direction="row" justify="space-between">
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    </k-stack>    
    Those are applied as inline styles. If you use the k-stack class on a custom element, you need to set the inline styles manually or with the CSS rules for your element.
  • New <k-definitions> and <k-definition> components to build definition lists in the style of our tables. This is particularly useful to show any kind of information in a semantic way. We will use this for our new error dialogs. #7767
    image
    <k-definitions>
    	<k-definition term="Term" description="Description" />
    	<k-definition term="Term" description="Description" />
    	<k-definition term="Term" description="Description" />
    </k-definitions>    
    Definition items can also be created with custom slots:
    <k-definitions>
    	<k-definition>
    		<template #term><em>Term</em></template>
    		<p class="k-text">
    			<a href="<https://getkirby.com>">Description</a>
    		</p>
    	</k-definition>
    	<k-definition>
    		<template #term><em>Term</em></template>
    		<p class="k-text">
    			<a href="<https://getkirby.com>">Description</a>
    		</p>
    	</k-definition>
    	<k-definition>
    		<template #term><em>Term</em></template>
    		<p class="k-text">
    			<a href="<https://getkirby.com>">Description</a>
    		</p>
    	</k-definition>
    </k-definitions>    
  • New <k-checklist> component to create appealing lists of items that are marked as checked, to be noticed or errors. We will be using this in our new error dialogs, but the component is also very helpful for all kinds of scenarios in plugins and other parts of the Panel. #7771
    image
    <k-checklist>
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </k-checklist>
    Applying a theme:
    <k-checklist theme="negative">
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </k-checklist>
    All color themes are supported. notice and negative will automatically change the marker (see screenshot) You can easily add your own custom markers as well.
    <k-checklist style="--checklist-marker: '💛'">
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </k-checklist>
  • New Kirby\Http\Url::editor($editor, $file, $line) method, to create local editor URLs to open files in a code editor at the given line. #7768
    <a href="<?= Url::editor('vscode', '/my/local/file.php', 12) ?>">Open in VSCode</a>
  • Preview view: Button to sync scrolling in the compare mode #7813
  • New scroll-to-bottom and scroll-to-bottom-fill icons #7813
  • New LazyCollection class that initializes and loads its data and elements only when they are first needed #7839

⚡Performance

  • Improved performance of UUID enabled check #7094
  • User credentials (main data from index.php) are only loaded once when the user object is first created, improving system performance with many user accounts.
  • Significantly improved performance when large numbers of user accounts are set up #7841

✨ Enhancements

  • $visitor->ip() supports new $hash parameter to retrieve a 50 char long hash of the visitor's IP
  • More readable file paths in JSON error responses for the Panel. Absolute paths to the kirby folder, site folder and index folder will now be replaced with {kirby}, {site} and {index}. This will keep the responses more readable and easier to debug. It will also disguise the filesystem a bit. Although this is not the main intention, since those paths are only visible in debug mode anyway. #7772
  • New layout-top + layout-bottom icons #7814
  • Child classes of Iterator (mostly collections) can now implement a custom iterator and are not pinned to ArrayIterator #7838
  • New User::hasPassword() method to provide a solid check for an existing password #7869
  • The user dropdown now uses "Set password" instead of "Change password" for users that don't have a password so far. #7869
    image
  • Added support for view button separators using (thx @tobimori ) #7873
buttons:
  - open
  - preview
  - '-'
  - languages
  - '-'
  - settings
  • New OfflineError error type in kirby/panel/src/errors/OfflineError.js.
  • kirby/panel/src/panel/request.js now uses safeFetch() and emits offline on network failures.
  • kirby/panel/src/api/request.js uses safeFetch() instead of raw fetch().
  • kirby/panel/src/panel/panel.js catches OfflineError and sets isOffline.
  • Kirby now can handle HTTP range requests for partial content delivery #1207
  • New Filesystem\F::range($file, $offset, $length) method to only read parts of a file
  • New Http\Range class for handling HTTP range requests
  • <k-drawer> has new size prop (options: tiny, small, default, large, huge) #7900
  • <k-tag>: support for icon. #7886
  • <k-checkboxes-input>, <k-radio-input>, <k-toggle-input>: support for additional icon alongside text and info for the label #7886
  • Kirby\Filesystem\F::load() has a new cache parameter which will return the file content from cache or add the loaded file content to a cache on the first time its loaded #7920

🐛 Bug fixes

  • Page move dialog: show spinner while loading https://feedback.getkirby.com/652
  • Fixes broken selection state in textarea buttons if not initialized #7831
  • Iterator::has() and the has() method of collections correctly treats an existing but null value as a valid collection element #7838
  • UUID cache gets populated on model actions (e.g. page creation) #7809
  • Users can now set their first password (if they had none so far) without providing their current one. This only works for their own account. A user without password cannot change the password of any other user. #7869
  • Empty passwords are no longer incorrectly hashed #7869
  • A::get(): Prefer dotted prefix keys to avoid option collisions of full dotted pr...
Read more

6.0.0-alpha.2

04 Feb 12:30
d960733

Choose a tag to compare

6.0.0-alpha.2 Pre-release
Pre-release

TL;DR:

Kirby 6.0.0-alpha.2 is an early developer preview. We plan for a final release in the second half of 2026. Kirby 6 will be a free upgrade for all Kirby 4 & 5 license holders.

Important

Don't use Kirby 6 in production yet

Highlights

✍️ Live editor
📄 Simplified blueprint definition
🥞 New template stacks
🔘 New buttons field

Changelog

We are collecting all changes in our pre-release changelog, if you already want to dive deeper: https://github.com/getkirby/kirby/blob/6.0.0-alpha.2/CHANGELOG.md

5.3.0-rc.1

03 Feb 11:10
38205e9

Choose a tag to compare

5.3.0-rc.1 Pre-release
Pre-release

🎉 Features

  • Support for option icons in checkboxes, multiselect, radio and tags field #7673
    image
    image
    image
  • New <k-code-token> component and global styles for inline <code> elements with data-type attribute. The styles for the colored inline elements have been taken from our lab examples and are now available anywhere. The type can either be a generic type (string, float, bool, etc.) or a color keyword from our design system (green, red, orange, etc.) #7765
    image
  • New <k-stack> component to help with horizontal and vertical layouts. Think of it as a flex layout helper component. It's perfect to create equal gaps between elements in a column or row. E.g. different sections or the gap between the headline and contents of a container. #7766
    image
    You can either use the component as a wrapper (which will create a div):
    <k-stack>
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    </k-stack>    
    … or use the k-stack class on an existing wrapper element to inherit the basic stack styles:
    <ul class="k-stack">
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </ul>    
    Use the attributes gap, direction, align and justify to control the layout.
    <k-stack gap="var(--spacing-12)" align="center" direction="row" justify="space-between">
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    	<k-box theme="white">Test Box</k-box>
    </k-stack>    
    Those are applied as inline styles. If you use the k-stack class on a custom element, you need to set the inline styles manually or with the CSS rules for your element.
  • New <k-definitions> and <k-definition> components to build definition lists in the style of our tables. This is particularly useful to show any kind of information in a semantic way. We will use this for our new error dialogs. #7767
    image
    <k-definitions>
    	<k-definition term="Term" description="Description" />
    	<k-definition term="Term" description="Description" />
    	<k-definition term="Term" description="Description" />
    </k-definitions>    
    Definition items can also be created with custom slots:
    <k-definitions>
    	<k-definition>
    		<template #term><em>Term</em></template>
    		<p class="k-text">
    			<a href="<https://getkirby.com>">Description</a>
    		</p>
    	</k-definition>
    	<k-definition>
    		<template #term><em>Term</em></template>
    		<p class="k-text">
    			<a href="<https://getkirby.com>">Description</a>
    		</p>
    	</k-definition>
    	<k-definition>
    		<template #term><em>Term</em></template>
    		<p class="k-text">
    			<a href="<https://getkirby.com>">Description</a>
    		</p>
    	</k-definition>
    </k-definitions>    
  • New <k-checklist> component to create appealing lists of items that are marked as checked, to be noticed or errors. We will be using this in our new error dialogs, but the component is also very helpful for all kinds of scenarios in plugins and other parts of the Panel. #7771
    image
    <k-checklist>
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </k-checklist>
    Applying a theme:
    <k-checklist theme="negative">
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </k-checklist>
    All color themes are supported. notice and negative will automatically change the marker (see screenshot) You can easily add your own custom markers as well.
    <k-checklist style="--checklist-marker: '💛'">
    	<li>Item A</li>
    	<li>Item B</li>
    	<li>Item C</li>
    </k-checklist>
  • New Kirby\Http\Url::editor($editor, $file, $line) method, to create local editor URLs to open files in a code editor at the given line. #7768
    <a href="<?= Url::editor('vscode', '/my/local/file.php', 12) ?>">Open in VSCode</a>
  • Preview view: Button to sync scrolling in the compare mode #7813
  • New scroll-to-bottom and scroll-to-bottom-fill icons #7813
  • New LazyCollection class that initializes and loads its data and elements only when they are first needed #7839

⚡Performance

  • Improved performance of UUID enabled check #7094
  • User credentials (main data from index.php) are only loaded once when the user object is first created, improving system performance with many user accounts.
  • Significantly improved performance when large numbers of user accounts are set up #7841

✨ Enhancements

  • $visitor->ip() supports new $hash parameter to retrieve a 50 char long hash of the visitor's IP
  • More readable file paths in JSON error responses for the Panel. Absolute paths to the kirby folder, site folder and index folder will now be replaced with {kirby}, {site} and {index}. This will keep the responses more readable and easier to debug. It will also disguise the filesystem a bit. Although this is not the main intention, since those paths are only visible in debug mode anyway. #7772
  • New layout-top + layout-bottom icons #7814
  • Child classes of Iterator (mostly collections) can now implement a custom iterator and are not pinned to ArrayIterator #7838
  • New User::hasPassword() method to provide a solid check for an existing password #7869
  • The user dropdown now uses "Set password" instead of "Change password" for users that don't have a password so far. #7869
    image
  • Added support for view button separators using (thx @tobimori ) #7873
buttons:
  - open
  - preview
  - '-'
  - languages
  - '-'
  - settings
  • New OfflineError error type in kirby/panel/src/errors/OfflineError.js.
  • kirby/panel/src/panel/request.js now uses safeFetch() and emits offline on network failures.
  • kirby/panel/src/api/request.js uses safeFetch() instead of raw fetch().
  • kirby/panel/src/panel/panel.js catches OfflineError and sets isOffline.
  • Kirby now can handle HTTP range requests for partial content delivery #1207
  • New Filesystem\F::range($file, $offset, $length) method to only read parts of a file
  • New Http\Range class for handling HTTP range requests
  • <k-drawer> has new size prop (options: tiny, small, default, large, huge) #7900
  • <k-tag>: support for icon. #7886
  • <k-checkboxes-input>, <k-radio-input>, <k-toggle-input>: support for additional icon alongside text and info for the label #7886
  • Kirby\Filesystem\F::load() has a new cache parameter which will return the file content from cache or add the loaded file content to a cache on the first time its loaded #7920

🐛 Bug fixes

  • Page move dialog: show spinner while loading https://feedback.getkirby.com/652
  • Fixes broken selection state in textarea buttons if not initialized #7831
  • Iterator::has() and the has() method of collections correctly treats an existing but null value as a valid collection element #7838
  • UUID cache gets populated on model actions (e.g. page creation) #7809
  • Users can now set their first password (if they had none so far) without providing their current one. This only works for their own account. A user without password cannot change the password of any other user. #7869
  • Empty passwords are no longer incorrectly hashed #7869
  • A::get(): Prefer dotted prefix keys to avoid option collisions of full dotted prefix vs. nested array, e.g. with plugin options #6242
  • Radio input: Fixed resetting via clicking the input label #5845
  • Options from query: if the query returns an associative array, Kirby now uses the array keys as values by default [#5807](https://github.com/getkirby/kirby/issue...
Read more

5.2.3

03 Feb 10:31
a7697cd

Choose a tag to compare

🐛 Bug fixes

  • Using page title in string template of other fields #7834
  • Writer Text field cannot handle multi-domain multi-language page links #7786
  • The time field does now submit the form when pressing enter. #774
  • Fixed console error for skipped page create dialogs #7877
  • Fixed "Change Template" options for files: All available file templates are shown when sections don't define available templates #6761
  • Fixed opening TOTP disable dialog #7895
  • Thumb jobs files do not get regenerate if they already exist #7861
  • Blocks field
    • Fixed options toolbar position when open #7637
    • Deselect blocks when focus moves to an element outside of the blocks field #6599
    • Fix blocks becoming unresponsive when external apps steal focus #7914 (thx @tobimori)

5.2.2

08 Jan 10:50
55563aa

Choose a tag to compare

Caution

🚨 Security

Missing permission checks in the content changes API

CVE ID: CVE-2026-21896
Severity: medium (CVSS score 5.8)

This vulnerability affects all Kirby sites (Kirby 5.0.0-5.2.1) where user permissions are configured to prevent specific role(s) from performing write actions, specifically by disabling the update permission with the intent to prevent modifications to site content.

If you haven't configured any user permissions that deviate from the default of allowing all actions, your site is not affected.

🐛 Bug fixes

  • Prevent error when calling Remote::json() with single-value JSON content (e.g. a single string, single int) #7806
  • Fixed Kirby\Toolkit\Dom for newer libxml versions #7802
  • Writer field: fixed inline toolbar position on views without Panel menu #7799
  • $collection->group(callable) should accept empty string result as key #7830
  • Fixed filename field bug in upload dialog #7662

♻️ Refactored

  • Reset $_SERVER manipulation in tests #7807