diff --git a/administrator/components/com_fields/src/Model/FieldModel.php b/administrator/components/com_fields/src/Model/FieldModel.php
index 18e2d8b5aefb3..376abe272296c 100644
--- a/administrator/components/com_fields/src/Model/FieldModel.php
+++ b/administrator/components/com_fields/src/Model/FieldModel.php
@@ -997,9 +997,11 @@ protected function loadFormData()
public function validate($form, $data, $group = null)
{
// Check if the values are unique. This should only apply for list, checkboxes and radio custom field types
- if (\in_array($data['type'], ['list', 'checkboxes', 'radio'])
+ if (
+ \in_array($data['type'], ['list', 'checkboxes', 'radio'])
&& !empty($data['fieldparams']['options'])
- && \is_array($data['fieldparams']['options'])) {
+ && \is_array($data['fieldparams']['options'])
+ ) {
$tmpValues = [];
foreach ($data['fieldparams']['options'] as $option) {
$tmpValues[] = $option['value'];
diff --git a/administrator/components/com_guidedtours/src/Controller/AjaxController.php b/administrator/components/com_guidedtours/src/Controller/AjaxController.php
index cdf73f68fdfdf..7e3706abb9f49 100644
--- a/administrator/components/com_guidedtours/src/Controller/AjaxController.php
+++ b/administrator/components/com_guidedtours/src/Controller/AjaxController.php
@@ -15,6 +15,7 @@
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Response\JsonResponse;
+use Joomla\CMS\Session\Session;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
@@ -35,6 +36,12 @@ class AjaxController extends BaseController
*/
public function fetchUserState()
{
+ // The request changes persisted user state, so it must carry a valid token.
+ if (!Session::checkToken('get')) {
+ echo new JsonResponse(null, Text::_('JINVALID_TOKEN'), true);
+ $this->app->close();
+ }
+
$user = $this->app->getIdentity();
$tourId = $this->app->getInput()->getInt('tid', 0);
diff --git a/administrator/components/com_installer/tmpl/update/default.php b/administrator/components/com_installer/tmpl/update/default.php
index e493e91f3b0da..7b17f3cdf8c81 100644
--- a/administrator/components/com_installer/tmpl/update/default.php
+++ b/administrator/components/com_installer/tmpl/update/default.php
@@ -105,11 +105,11 @@
update_site_id; ?>
- security)) : ?>
+ security)) : ?>
security); ?>
-
-
+
+
client_translated; ?>
diff --git a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php
index 742ebfcbb0f4a..cd532fae82da9 100644
--- a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php
+++ b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php
@@ -511,12 +511,20 @@ public function getAutoUpdateVersion(): ?string
*/
public function getAutoUpdateRequirementsState(): bool
{
+ // Check basic requirements of the *current* system
foreach ($this->getPhpOptions() as $option) {
if ($option->state !== true) {
return false;
}
}
+ // Fetch update and check constraints - if the "otherinfo" is set, we have a constraint issue
+ $updateInfo = $this->getUpdateInformation();
+
+ if (!empty($updateInfo['object']) && !empty((array) $updateInfo['object']->get('otherUpdateInfo'))) {
+ return false;
+ }
+
return true;
}
diff --git a/administrator/components/com_menus/src/Model/ItemModel.php b/administrator/components/com_menus/src/Model/ItemModel.php
index 418ed43c5125b..0e698469872c9 100644
--- a/administrator/components/com_menus/src/Model/ItemModel.php
+++ b/administrator/components/com_menus/src/Model/ItemModel.php
@@ -235,6 +235,15 @@ protected function batchCopy($value, $pks, $contexts)
continue;
}
+ // Check that the user is allowed to access the item
+ $itemMenuTypeId = (int) $this->getMenuTypeId($table->menutype);
+
+ if ($table->menutype === 'main' || !$user->authorise('core.edit', 'com_menus.menu.' . $itemMenuTypeId)) {
+ $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT'));
+
+ return false;
+ }
+
// Copy is a bit tricky, because we also need to copy the children
$query = $db->createQuery()
->select($db->quoteName('id'))
diff --git a/administrator/components/com_templates/tmpl/template/default.php b/administrator/components/com_templates/tmpl/template/default.php
index 881f5cc9c2d93..adb5ee1acf6cb 100644
--- a/administrator/components/com_templates/tmpl/template/default.php
+++ b/administrator/components/com_templates/tmpl/template/default.php
@@ -184,10 +184,10 @@
archive as $file) : ?>
-
+ escape($file); ?>
-
+ escape($file); ?>
diff --git a/media_source/plg_system_guidedtours/js/guidedtours.es6.js b/media_source/plg_system_guidedtours/js/guidedtours.es6.js
index b3a18eda01b5a..0235495f8682b 100644
--- a/media_source/plg_system_guidedtours/js/guidedtours.es6.js
+++ b/media_source/plg_system_guidedtours/js/guidedtours.es6.js
@@ -27,8 +27,10 @@ function emptyStorage() {
*/
function fetchTourState(tid, sid, context) {
const fetchUrl = 'index.php?option=com_guidedtours&task=ajax.fetchUserState&format=json';
+ // The endpoint persists user state, so the request must carry the CSRF token.
+ const token = Joomla.getOptions('com_guidedtours.token', '');
Joomla.request({
- url: `${fetchUrl}&tid=${tid}&sid=${sid}&context=${context}`,
+ url: `${fetchUrl}&${token}=1&tid=${tid}&sid=${sid}&context=${context}`,
method: 'GET',
perform: true,
onSuccess: (response) => {
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 418dc86a677e4..7d4d3669973f6 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -3427,7 +3427,7 @@ parameters:
Throw an Exception instead of using setError$#
'''
identifier: method.deprecated
- count: 35
+ count: 36
path: administrator/components/com_menus/src/Model/ItemModel.php
-
|