Problem/Motivation

Visiting the approval URL for a comment that is already published gives a 403 response. Access denied is not really correct, the user has access, it's just already published.

Steps to reproduce

  1. Install Drupal
  2. Add an article
  3. Post a comment and make sure it is unpublished
  4. Copy the URL to approve the comment
  5. Publish/approve the comment
  6. Visit the approve URL again
  7. Get 'Access Denied' message

Proposed resolution

#16 suggests allowing access to the URL but showing a message, e.g., "This comment is published."

Remaining tasks

  1. Agree on the ideal behaviour
  2. Write a patch with tests
  3. Review

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A

Original issue summary

This was pointed out by @webchick somewhere and passed along through several issues - see e.g. #66264-29: Remove CSRF vulnerability from comment module.

The bug is a relatively minor one, but if you try to approve a comment that is already published (by visiting the appropriate comment/%/approve URL directly), you are not prevented from doing so - instead you get a "Comment approved" message on the screen.

We should at least change the message in that case, if not prevent it via the access callback completely (the latter because if anyone tries to use this link as anything other than a menu callback, they presumably don't want the "approve" link to show up in places where it doesn't make sense).

Issue fork drupal-748996

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

sun’s picture

I'd expect a redirect back to where I came from + proper message "The comment is already published.".

lyricnz’s picture

Status: Active » Needs review
StatusFileSize
new792 bytes

Patch that changes the message attached.

sun’s picture

Version: 7.x-dev » 8.x-dev
lyricnz’s picture

Patch works fine on D8 too.

marvil07’s picture

StatusFileSize
new794 bytes

Minor re-roll for core/ directory change.

This works as expected.

Status: Needs review » Needs work

The last submitted patch, comment-reapprove-748996-5.patch, failed testing.

marvil07’s picture

Status: Needs work » Needs review

Un-related error:

Failed: Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[HY000]: General error: 1114 The table 'simpletest841577field_revision_taxonomy_vocabulary_3_2' is full: ALTER TABLE {field_revision_taxonomy_vocabulary_3_2} ADD PRIMARY KEY (`entity_type`, `entity_id`, `revision_id`, `deleted`, `delta`, `langcode`); Array ( ) in Drupal\Core\Database\Connection->query() (line 532 of /var/lib/drupaltestbot/sites/default/files/checkout/core/lib/Drupal/Core/Database/Connection.php).

karthid’s picture

Assigned: Unassigned » karthid
Category: bug » task
Status: Needs review » Needs work

The patch no longer applies. Because drupal 8.x folder structure has been changed now.

karthid’s picture

Status: Needs work » Needs review
StatusFileSize
new794 bytes

Re-roll for core/ directory change.

This works as expected.

marvil07’s picture

Status: Needs review » Reviewed & tested by the community

Yep, last two patches are exactly equal ;-)

This is trivial, so hopefully it's OK to move it to RTBC.

marvil07’s picture

Category: task » bug

BTW, this is a bug.

marvil07’s picture

webchick’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Nice fix! Let's add an automated test to make sure we don't break it again. :)

Also, this is a nitpick, but

+++ b/core/modules/comment/comment.pages.inc
@@ -120,10 +120,14 @@ function comment_approve($cid) {
+      drupal_set_message(t('The comment is already published.'));
...
+      drupal_set_message(t('Comment approved.'));

Let's also shorten up that message so it's more inline with the approved one. Something like "Comment already published."

Does this need backport to D7 as well?

andypost’s picture

Version: 8.0.x-dev » 8.1.x-dev
Issue summary: View changes

\Drupal\comment\Controller\CommentController::commentApprove() now

andrey_zb’s picture

Status: Needs work » Needs review

I reviewed this issue and wonder if there is anything to do?
Having approve functionality in \Drupal\comment\Controller\CommentController::commentApprove() (#14) marks published comments as "approved".
May be there are any test cases, when the issue can be reproduced?

David_Rothstein’s picture

Version: 8.1.x-dev » 8.0.x-dev
Issue tags: +Needs backport to D7

Not sure why this was moved to 8.1.x. And yes, it needs backport to Drupal 7.

Testing this in Drupal 8 it looks like it may be fixed. There is nothing in \Drupal\comment\Controller\CommentController::commentApprove() itself to fix this, but I get access denied when I try to approve an already-approved comment. (This is one of the suggestions I made when filing this issue originally, although the patches since then were going in the other direction - i.e. keeping access to the URL but displaying a message instead.)

I guess tests would still be a good idea for this in Drupal 8, if they don't already exist.

andypost’s picture

minor bug with tests + UX could came in for 8.0

Usha Gavva’s picture

andypost’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests, +Needs backport to D7, +Needs beta evaluation, +Needs reroll

patch is totally wrong, keep tags!

andypost’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new1014 bytes

proper re-roll, still needs tests

marvil07’s picture

Revisiting this issue, the problems mentioned seems to be resolved.
First, _csrf_token prevents access directly to the link.
Second, as reiterated on comment #16, there is already a check for the published status in place after #2322949: Implement generic entity link view field handlers, i.e. see CommentAccessControlHandler::checkAccess(); which should prevent the bad message on a race condition, e.g. two users approving the content at the same time.

About tests, the csrf part already has tests on CommentAdminTest::testApprovalNodeInterface(), and the other part I think is not possible to be tested unless we can have in parallel to users in different screens.

The only possible improvement I see now may be to be able to return 400 (Bad Request) http status on the race condition case instead of the current 403, but I guess that could be another issue instead.

Pending: someone to confirm the position before closing this, and maybe open a new issue for the 403 to 400 change.

andypost’s picture

The reason behind the issue is UX, having 403/400 here is wrong, because user has permission to approve.
So in this case controller should properly report status of approval operation.

    if ($operation == 'approve') {
      return AccessResult::allowedIf($comment_admin && !$entity->isPublished())

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

pameeela’s picture

Title: Access callback for comment approval does not prevent approving a comment that is already published » Visiting the comment approval link for a published comment causes 403
Version: 8.9.x-dev » 9.3.x-dev
Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Bug Smash Initiative

Updated IS for current state.

mohit_aghera made their first commit to this issue’s fork.

mohit_aghera’s picture

Assigned: Unassigned » mohit_aghera
mohit_aghera’s picture

Assigned: mohit_aghera » Unassigned

mohit_aghera’s picture

Status: Needs work » Needs review

I have implemented the following changes:
- Re-roll the patch.
- Add a test case to validate the message.

For the test cases, I am bypassing CSRF token and other validation by adding a new route in comment_test module.
My main intention is to test the proper messages only.

I agree that 400/403 is somewhat confusing because the admin already has the permission to approve the comment.
As @andypost mentioned that it is validated in the below AccessController method.

    if ($operation == 'approve') {
      return AccessResult::allowedIf($comment_admin && !$entity->isPublished())
        ->cachePerPermissions()
        ->addCacheableDependency($entity);
    }

To get the proper message and response code, I think we can remove !$entity->isPublished() validation as we are already showing proper messages in controller method.

I haven't removed that as of now as it would be great if we have some inputs from the product owner or subsystem maintainers.

larowlan’s picture

I think it would be better to add a custom exception handler, check the route name, and if its this route, display a message and send them back to the commented entity via a redirect

e.g extend from HttpExceptionSubscriberBase and add a method `on403`

Inject the route match and messenger service, and if the route is the comment approval one, display the message and return a new redirect response (to the comment canonical path)

For testing, fetch the page that has the approve link then publish the comment via the api (e.g. $comment->status = 1; $comment->save())

Then click the link and assert the message is output and the redirect occurs.

larowlan’s picture

alternatively we could probably remove the published check from the route and handle it in the controller instead, with a redirect from there

might be better than having a custom exception handler in memory in the event dispatcher on every page

mohit_aghera’s picture

Implemented the following changes:
- Removed !$entity->isPublished()) from the checkAccess() in AccessController
- Update test cases to validate that accordingly.
- Remove additional changes added in previous commit.

paulocs made their first commit to this issue’s fork.

paulocs’s picture

Issue tags: -Needs tests

Small fix to remove the t() calls in the test file. See: https://www.drupal.org/docs/automated-testing/phpunit-in-drupal/phpunit-browser-test-tutorial#t
Except for that, the merge request looks good.

larowlan’s picture

Hiding patch files

larowlan’s picture

Left a minor readability suggestion, but this looks good to me

joachim’s picture

Status: Needs review » Reviewed & tested by the community

LGTM.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review

There are at least two contrib projects checking the 'approve' permission http://grep.xnddx.ru/search?text=-%3Eaccess%28%27approve&filename=

Can we just confirm that there's no security impact of this change

mohit_aghera’s picture

@andypost @larowlan
I did a quick review of all the MR/issues mentioned in the above comment.

In our case, primarily we are changing "approve" operation access.
I think https://www.drupal.org/project/drupal/issues/2879087 might have significant conflicts.

IMO, can we revisit later after the https://www.drupal.org/project/drupal/issues/2879087 is merged?

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work

Can we update MR to 10.1 please.

rpayanm made their first commit to this issue’s fork.

rpayanm’s picture

Status: Needs work » Needs review

Please review.

lyricnz’s picture

I can't believe this issue is still open! :)

smustgrave’s picture

Status: Needs review » Needs work

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

Seems the D10 MR 3384 has some failures.

@andypost and @larowlan does #47 answer your comments about security?

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.