Quantcast
Channel: Issues for Drupal core
Viewing all 297157 articles
Browse latest View live

timezone.js calls the system.timezone route with a date parameter that is never used

$
0
0

Problem/Motivation

timezone.js generates this kind of AJAX URL: /system/timezone/0/3600/0?date=Sun%20Mar%2023%202025%2015%3A58%3A36%20GMT%2B0100%20(heure%20normale%20d%E2%80%99Europe%20centrale)

But it seems the date query parameter is never used in TimezoneController.

Steps to reproduce

I'm not sure how to trigger the AJAX call, it seems it is only triggered if new Intl.DateTimeFormat().resolvedOptions().timeZone returns an unsupported timezone name.

Proposed resolution

Remove the parameter and make sure it does not break anything.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet


Flood control on reset password form blocks IP address but not the account

$
0
0

This issue has been approved for public discussion by the Drupal Security Team.

Problem/Motivation

The IP address blocking system works fine, but if the reset password for the same account is made from a different IP address, the user is still able to do the same number of attempts until the new IP address gets blocked.

In the validateForm of UserPasswordForm, these 3 lines currently don't do anything, since a simple return in validateForm doesn't trigger any error.

if (!$this->flood->isAllowed('user.password_request_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
    return;
}

The setError has been removed as part of https://www.drupal.org/node/1521996 which ultimately changed the behaviour and left redundant code (as stated before, the lines above don't do anything). And currently there is no Change Request to put the behaviour described here https://www.drupal.org/node/3085704 back in place.

Steps to reproduce

1. Go to the reset password form
2. Attempt to reset the password for a given account 5 times (ip_limit changed to 5 for testing purposes)
3. After these 5 attempts, the "IP blocked" error message appears
4. Change the IP address (via VPN for instance)
5. Do a new attempt on the same account
6. The same amount of attempts can be done before getting the new IP blocked

Proposed resolution

The account should be appropriately blocked according to the user_limit value. In our example, the account should be blocked at the same time as the first IP address being blocked, since it is set by default to 5.
- Put back the message but with a more generic sentence, so it is unclear if an account exists or not.

if (!$this->flood->isAllowed('user.password_request_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
$form_state->setErrorByName('name', $this->t('Too many password recovery requests. Try again later or contact the site administrator.'));
    return;
}

Protect initial login link against abuse and username leaking

$
0
0

Copied from https://security.drupal.org/node/166626 which was reviewed and determined it was OK to make it public as the impact is minimal. The reporter was via email and did not provide details on their d.o account to be able to give them credit.

Problem/Motivation

The "initial login link" that a user gets in their email when registering for an account on a site that allows anonymous registration without approval has a few interesting elements:

  1. It never expires - while the password reset link expires in 24 hours.
  2. The default robots.txt allows crawling these links

That combination means that if the url gets "leaked" somehow it is very easy to use a search engine to find unused login links.

Note that this issue seems to primarily affect accounts created using disposable email services where the inbox contents become crawlable on the internet.

Proposed resolution

A simple change is to update robots.txt to disallow crawling of /user/reset/*

A behavior breaking change that is worthwhile would be to validate the initial login link is being used within a certain period of time, perhaps 2 days. (The current patch makes it have the same value as the 'password_reset_timeout' configuration value, which currently is 24 hours and has no UI in Core. Is there ar reason to differentiate them?)

Remaining tasks

Lots.

User interface changes

robots.txt disallows access to password reset links.
(maybe) the initial login link verifies a timestamp.

API changes

$expiration_date for UserPasswordResetForm is now effectively mandatory. (Is this an API change? I'm not sure. --roderik)

Data model changes

None.

Release notes snippet

Links in e-mails sent out to newly created users are now valid for a limited time only, like links in "password reset" e-mails already are.

Block access to .scss, .sass, .less, .pcss and .pcss.css files

$
0
0

Problem/Motivation

SASS preprocessor is widely used for Drupal theming. That means many Drupal projects keep their styles in scss files. As these files are used only for compiling CSS files there is no need to keep them publicly accessible. Furthermore themers can use silent comments // to keep sensible information in the scss files so that it may be considered as a security issue.

.sass is a valid sass file extension, see https://sass-lang.com/documentation/syntax. Meanwhile, .less is a similar one (e.g. Less is used in Bootstrap 3)

Steps to reproduce

Create some scss file in your theme directory and visit the following URL.
https://example.com/themes/THEME_NAME/scss/SOME_FILE.scss

Proposed resolution

Update .htaccess and web.config to block access to scss, .sass, .less, .pcss and .pcss.css files

Remaining tasks

Discuss. Create a patch.

User interface changes

No

API changes

No

Data model changes

Release notes snippet

Drupal's generated .htaccess file has been updated to disallow viewing of scss, .sass, .less, .pcss and .pcss.css files

Layout Builder move block and add section routes vulnerable to CSRF

$
0
0

Problem/Motivation

This was originally logged as a private issue to the security team, but was cleared to be moved to the public queue
Drupal Core's Layout Builder module has a mild CSRF vulnerability.

This is only a mild nuisance because it would require someone to save changes for the layout and commit the 'tempstore'. The action for that is behind a form, and hence not vulnerable to CSRF.

Steps to reproduce

1. Enabling the layout builder module
2. As a malicious user, craft a url that matches the layout_builder.move_block route, i.e '/layout_builder/move/block/{section_storage_type}/{section_storage}/{delta_from}/{delta_to}/{region_to}/{block_uuid}/{preceding_block_uuid}
3. Trick a user with the ability to view layout builder for the given storage type (defaults, or overrides) and storage (a view display or a specific entity)
4. Note that the block is moved in the temp store for the given layout
5. The route layout_builder.add_section has the same issue

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Stop calling Html::escape() for checkbox options

$
0
0

Problem/Motivation

Coming from #3348093-17: Deprecate user_roles() and user_role_names()
There few places in core which using to escape options for no reason (all other places don't)

Proposed resolution

Remove escaping as twig cares to escape on render and other places not using using it

Probably it could be backported to 9.5

Remaining tasks

path/review/commit

User interface changes

no

API changes

no

Data model changes

no

Release notes snippet

Illegal mix of collations leads to error 500

$
0
0

"Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (ascii_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '=': SELECT name, value FROM {key_value_expire} WHERE expire > :now AND name IN ( :keys__0 ) AND collection = :collection; Array ( [:now] => 1608110913 [:collection] => form [:keys__0] => NS09<s1﹥DBLʺSNGLʹNS09 ) in Drupal\Core\KeyValueStore\StorageBase->get() (line 35 of /var/www/html/core/lib/Drupal/Core/KeyValueStore/StorageBase.php)."
This issue occurs when we modify the POST request data to a form and insert some utf-8 character in form_build_id.
ParameterName: form_build_id
ParameterType: POST
Payload: NS09<s1﹥DBLʺSNGLʹNS09
But the database uses 'utf8mb4_general_ci' collation and also all the tables in the database also has 'utf8mb4_general_ci' collation.
I could not find any table using the collation 'ascii_general_ci'

Url::access() doesn't allow cacheability metadata to be bubbled

$
0
0

Problem/Motivation

Url::access() doesn't bubble cacheability metadata, and consequently could lead to security vulnerabilities in case developers fail to take this into account.

See #2661200-52: Make admin/help page more flexible, and list tours on it's interdiff-url-changes.txt for an initial patch.

Proposed resolution

Make it bubble cacheability metadata.

Remaining tasks

TBD

User interface changes

None.

API changes

TBD

Data model changes

None.


Node access default grant behavior is not clear

$
0
0

Problem/Motivation

Followup from #2461049: Node module permissions are broken if hook_node_grants is implemented.

The node grant/access record system has a behavior where if no hook_node_grant() implementations are defined and therefore no modules provide node access records for specific nodes, a global "view all grant" is written instead. Having this default behavior buried inside the storage is already confusing, but the documentation for it is already pretty thin. The NodeGrantDatabaseStorageInterface::writeDefault()method docs say:

Creates the default node access grant entry.

...So that's nice but what is the "default node access grant entry"?
There is also no documentation inside the main implementation of NodeGrantDatabaseStorage::writeDefault() about what the "default grant" is (i.e., fall back to a view access grant for all).

Also see

Furthermore, none of the classes and interfaces involved in node access belong to the node access documentation topic, so the default behavior is not discoverable or clear in the "big picture" there. This is important because "view access for all but no edit nor delete access" is only the default behavior when (a) the "bypass node access" permission is not granted (b) the "view published content" permission is granted (c) no hook_entity_access() or hook_node_access() implementations already allowed or denied access for the operation (d) the node is not unpublished.

Finally, this logic seems somewhat like it should be part of the node access control handler (as a conceptual default behavior), and the storage implementation should just be... a storage implementation. #2461049: Node module permissions are broken if hook_node_grants is implemented adds the logic as actual code, but then it's in two places. Maybe there should be a grantDefaultAccess() method or something that we factor out?

Proposed resolution

  1. Improve the NodeGrantDatabaseStorage::writeDefault() method docblock and the NodeAccessControlHandlerInterface::writeDefaultGrant() documentation.
  2. Add inline documentation to NodeGrantDatabaseStorage::writeDefault() explaining what logic the storage implementation is implementing. - Not done, this would be repeating the docblock comments
  3. Clarify the default grant behavior in the node access group documentation.
  4. Decide whether we should factor out the logic of the default behavior into its own method (or something). - Not done, let's leave it where it is. We already have weird duplication in the access control handler.

Related: #2473123: Add node grant classes and interfaces to the node access topic

Remaining tasks

TBD

User interface changes

N/A

API changes

TBD

Postponed until

#2461049: Node module permissions are broken if hook_node_grants is implemented

<em> tag appears in revision log message when a revision entry is reverted

$
0
0

Problem/Motivation

Created a Content Revision view with few fields which had revision log message and revert link as its fields. When you revert a revision entry, the log message shows the message with date inside tag. I have attached the screenshot.
revision_text

Steps to reproduce

Create a Node with some revisions
Revert one of the revisions
Create a Content revision view that contains the Revision log message field
Notice revision log from reverted revision is rendered as plain text that contains HTML (em tags)

Proposed resolution

Remove placeholder markup from revision log messages, these are by design plain text strings and should not contain HTML

Remaining tasks

Review
Commit

Drupal Usability Meeting 2025-05-16

$
0
0

This meeting takes place every Friday at 14:00 UTC (currently 6:00am PT, 9:00am ET). See Time.is to see what that is in your timezone.

The meetings are held using Zoom, and a link is posted in the #ux Slack channel 10 minutes before the meeting. Agenda is first come, first serve and set by attendees. Use the Needs usability review issue tag for issues that need review and/or suggest issues in comments here.

List of Slack users to ping 10 minutes before the meeting:
@worldlinemine, @lauriii, @AaronMcHale, @anmolgoyal74, @Ravi, @shaal, @ckrina, @simohell, @Quynh, @yoroy, @andrei.zvonkov, @Regu.pl

This list gets copied to the issue for the next meeting. If that has already happened, then go to that issue to add/remove yourself to/from the list.

Recording of this week's meeting: https://youtu.be/QC5ER5OmOx8

Rough transcript of this week's meeting: Drupal Usability Meeting - 2025-05-16.txt

We discussed the following issue:

NR and RTBC issues marked Needs usability review.

The group is actively tracking progress on these issues:

Remaining tasks

  1. Add issue credits for the participants.
  2. Add the issue(s) we discussed to the issue summary and as related issues.
  3. Add a rough transcript.
  4. Add a link to the recording on YouTube.
  5. Comment on the issue(s) we discussed.

ContentEntityForm::addRevisionableFormFields contain invalid access checks

$
0
0

Problem/Motivation

ContentEntityForm::addRevisionableFormFields contains access checks that do nothing.

Both the details element and revision checks contain #access entries that check ->access('update') which is not a valid field access operation (it should be edit)

Since the operation is invalid, this access check always returns TRUE.

The details element also checked $new_revision_default, but we cannot keep that as it would hide the revision information if Create new revision was unchecked.

Proposed resolution

Remove the access checks entirely.

See #12 and #14 for reasoning.

MediaTypeForm descriptions will be fixed in #3364973: Make Add content/media default publishing option descriptions consistent

Remaining tasks

Do it.

Original report

Problem/Motivation

Node Type form says "Users with sufficient access rights will be able to override these options." and Media Type form says "Users with the "Administer media" permission will be able to override this option.". If I create a user that can edit media and nodes without the administer permissions, the option remains overridable. 🤔 I'm not sure what would be required to not have "sufficient access rights" for the Node use case, but at least the Media use case is clearly not working the way the UI makes you believe.

Steps to reproduce

  1. Install Standard
  2. Enable Media module
  3. Confirm on /admin/structure/media/manage/image that "Create new revision" is checked
  4. Give the "Content Editor" role following permissions: "Image: Create new media", "Image: Edit any media", "Access media overview", "View all media revisions", "View media", "View own unpublished media"
  5. Log in as a content editor
  6. Go to /media/add/image to create new image media entity
  7. After creating the media entity, confirm that "Create new revision" is visible, can be unchecked, and content can be saved without creating new revision

Layout builder cannot recover on missing layout

$
0
0

Problem/Motivation

After renaming a layout, or after switching to a branch where a given layout does not exist, any attempt to fix the layout configuration will fail.

Steps to reproduce

Create a custom layout.
Create a layout builder configuration using that custom layout.
Remove or rename the custom layout.
Attempt to edit the layout builder configuration form, OR try to use "drush cim" to revert to a configuration where this layout was not used.

Expected: Layout builder config can be repaired.
Actual: Error.

The "layout_xyz" plugin does not exist. Valid plugin IDs for Drupal\Core\Layout\LayoutPluginManager are: ...

Proposed resolution

Use try/catch in strategic places to recover from this.

Remaining tasks

See tags

User interface changes

API changes

Data model changes

Release notes snippet

Prefer to replace some of obj && obj.prop in multi-lines with optional chaining if possible

$
0
0

Problem/Motivation

This issue is almost similar to #3492582: Replace some of obj && obj.prop with optional chaining.
In #3492582, some of obj && obj.prop in a single line was replaced with optional chaining but in multi-lines were partially. There is replaceable obj && obj.prop exist.
For example, checks object and its prop existence with below code in the /core/modules/big_pipe/js/big_pipe.js.

node.nodeType === Node.ELEMENT_NODE &&
  node.nodeName === 'SCRIPT'&&
  node.dataset &&
  node.dataset.bigPipeReplacementForPlaceholderWithId &&
  typeof drupalSettings.bigPipePlaceholderIds[
    node.dataset.bigPipeReplacementForPlaceholderWithId
  ] !== 'undefined',

If uses optional chaining expression, this code can makes code more shorter like below.

node.nodeType === Node.ELEMENT_NODE &&
  node.nodeName === 'SCRIPT'&&
  node.dataset?.bigPipeReplacementForPlaceholderWithId &&
  typeof drupalSettings.bigPipePlaceholderIds[
    node.dataset.bigPipeReplacementForPlaceholderWithId
  ] !== 'undefined',

Proposed resolution

Use optional chaining same as #3492582.

Remaining tasks

TBD

User interface changes

API changes

Data model changes

Release notes snippet

Clean up unserialize() in the migration modules

$
0
0

Background information

This was originally logged as a private issue to the security team, but was cleared to be moved to the public queue

Problem/Motivation

There are several calls to unserialize() in the migration modules (migrate, migrate_drupal, and migrate_drupal_ui). We should add the optional $options parameter to most or all of these, setting allowed_classes.

Proposed resolution

Remaining tasks

User interface changes

None

Introduced terminology

None

API changes

None

Data model changes

None

Release notes snippet

N/A


Implement a Result type in Drupal Core

$
0
0

Problem/Motivation

As we start doing more things asynchronously we'll have more batched work that can succeed and fail. In those kinds of scenario's an exception would cancel out the entire batch, even though it's often desirable to have a single item in a batch file while the rest of the batch continues.

Other (functional) languages solve this by providing a Result type that can be Ok or Error. By making clever use of the type-system this allows communicating that something can fail and forces the calling code to either deal with the success and error case (making sure not to forget one) or to propagate the result (optionally transforming the Ok or Error case).

PHP does not have a type like this itself so some custom code is needed. It's a capability that we will want to use in Drupal Core (e.g. for asynchronously processing BigPipe or rendering tasks where item-errors don't stop the entire process) and where contrib will want to standardise on a shared type for interoperability.

Steps to reproduce

Proposed resolution

Implement a Drupal/Core/Result (or should it be Drupal/Component/Result?) type that uses PHPStan types to implement the same logic as is available in functional programming languages (on Error you'll get the Error Type and on Ok you get the Ok Type).

An example implementation exists in https://phpstan.org/r/e9c7213e-b7ad-47f8-93b4-ec19e479b688 which is waiting for a small bit of PHPStan support and not quite ready for implementation in Drupal.

Remaining tasks

  • Agree on the namespace of the new class
  • Fix the existing PHPStan error (which is detected at Level 3 and above)
  • Create MR
  • Add PHPUnit tests for the methods on the Result object, these PHPUnit tests should help PHPStan demonstrate the types are correct and working
  • Write release notes snippet

User interface changes

API changes

Drupal introduces a new Result type which can be used to communicate that the result of an action can be successful or failure and that such a failure is not an exceptional circumstance (i.e. does not warrant an Exception). The Result class is typed in such a way that calling code can get type-hints of the types produced for either case.

Data model changes

Release notes snippet

[meta] DateTime Module Improvements

$
0
0

After all of the work that was done to get the DateTime into core, for various reasons, improvements to the module didn't progress at the same rate as the rest of 8.0.x. As a result, there are some very old issues in the queue (I have triaged a lot of them), and there is some work that needs to be done both on the module and on date handling in core in general. Thankfully, I don't think there is anything that can be considered a release blocker (though we do have some bugs that can be addressed outside this issue).

The purpose of this issue is to (1) discuss what needs to / should be done in 8.0.x, (2) discuss future plans that need to be deferred to 8.1.x, and (3) discuss/track this in one place as a lot of it is interrelated and we can create child issues.

Core Features

Developer Experience (DX)

#2489476: [PP-1] Base fields miss out on Views data from hook_field_views_data() (probably dependent on #2337515: Allow @FieldType to customize views data)

Investigate using Symfony 2.8+ Clock Mocking in tests.

User Experience (UX)

#2567815: Add week, date, and year-month Views argument plugins

Documentation

XXX

Testing

#2498619: Unit tests should use a default timezone other that UTC

#2497585: Simpletest should set a system timezone in setUp

The "search_form_block" block plugin was not found

$
0
0

Problem/Motivation

For some reason we started getting this notice on all admin page views being logged as a system notice in dblog: The "search_form_block" block plugin was not found

Steps to reproduce

Not entirely sure, best guess would be instal Drupal and set Claro as the admin theme then install search_api and remove/uninstall if it is installed core search.

I tracked it down to a claro configuration: block.block.claro_help_search.yml which is:

langcode: en
status: true
dependencies:
  module:
    - search
    - system
  theme:
    - claro
  enforced:
    config:
      - search.page.help_search
id: claro_help_search
theme: claro
region: help
weight: -4
provider: null
plugin: search_form_block
settings:
  id: search_form_block
  label: 'Search help'
  label_display: visible
  provider: search
  page_id: help_search
visibility:
  request_path:
    id: request_path
    negate: false
    context_mapping: {  }
    pages: /admin/help

..which as you can see uses "plugin: search_form_block"

I'm not sure why this started happening in the last week (I'm assuming the last core update caused it) but every admin page visited caused the dblog system notice. Either that or I never noticed it before, which is unlikely as this site has been using search_api and solr for several months now.

With drush: drush config-delete block.block.claro_help_search I was able to delete the config and the notice has stopped.

I would guess something would need to be done to make a config for claro_help_search that works with the search_api when it is used instead of core search module as it is always recommended on Drupal admin status page to disable core search when using the search_api.

Here are full drupal site details for good measure:
Drupal 10.4.6, Apache 2.4.62 Debian, MySQL 8.4.3, PHP 8.3.15
- Core search is disabled and the site this occurred on uses search_api, search_api_solr, search_api_autocomplete and search_api_solr_autocomplete (Solr latest version 9 and zookeeper version 3.9)

[PP-1] Add unit test for Drupal\layout_builder\Plugin\ConfigAction\Deriver\AddComponentDeriver

$
0
0

Problem/Motivation

Drupal\layout_builder\Plugin\ConfigAction\Deriver\AddComponentDeriver has no test coverage.
Implement a unit test.

#3475115: Provide a Config Action to add a component in a layout was committed without it for 11.2-alpha.

Proposed resolution

Add unit test verifying that only SectionListInterface implementations are generating a derivative of the addComponentToLayout config action.

Remaining tasks

Add unit test.

User interface changes

None.

Introduced terminology

None.

API changes

None.

Data model changes

None.

Release notes snippet

None.

Remove remaining IE11 support from Olivero

$
0
0

Problem/Motivation

We no longer support IE11 but Olivero's CSS still has several references to IE11 that likely need some rules to be removed, in the following files:

core/themes/olivero/css/components/button.pcss.css
core/themes/olivero/css/components/header-search-narrow.pcss.css
core/themes/olivero/css/components/header-search-wide.pcss.css
core/themes/olivero/css/components/navigation/nav-primary-no-js.pcss.css
core/themes/olivero/css/components/navigation/nav-primary-wide.pcss.css
core/themes/olivero/css/components/node.pcss.css
core/themes/olivero/css/components/search-results.pcss.css

Steps to reproduce

TBC

Proposed resolution

Remove the references to IE11 and any IE11 specific rules.

Remaining tasks

Code review & Define test instructions.

User interface changes

Button
Header search
Nav primary
Node
Search Results

Introduced terminology

NA

API changes

NA

Data model changes

NA

Release notes snippet

TBC

Viewing all 297157 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>