this is a major show stopper for decoupled drupal 8 developers.

The following endpoint;
* /entity/taxonomy_vocabulary/{taxonomy_vocabulary} produces a 403 and {"error":""}

Example to reproduce:

curl --request GET -k -s -i --user username:password --header 'X-CSRF-Token: YourTokenHash' 'https://example.com/entity/taxonomy_vocabulary/tags?_format=hal_json'
HTTP/1.1 403 Forbidden
...
...
{"error":""}

(...and yes, i checked permissions, and i have enabled both:
Access GET on Taxonomy term resource
Access GET on Taxonomy vocabulary resource
...)

Comments

jacov created an issue. See original summary.

jacov’s picture

the workaround for GET is to create a REST Export View for taxonomy terms || vocabs.

haven't found a solution to POST taxonomy terms yet though...

jacov’s picture

a quick hack to get around this is to comment out AccessDeniedHttpException on line 45 of core/modules/rest/src/Plugin/rest/resource/EntityResource.php

public function get(EntityInterface $entity) {
    $entity_access = $entity->access('view', NULL, TRUE);
    if (!$entity_access->isAllowed()) {
      // JB Hack
      // throw new AccessDeniedHttpException();
    }

so looks like the $request is coming through and i see the values in the stack trace...but looks like isAllowed() is not being set for the taxonomy routes...
...still digging...

jacov’s picture

StatusFileSize
new221.02 KB
jacov’s picture

StatusFileSize
new130.46 KB
jacov’s picture

StatusFileSize
new65.2 KB
jacov’s picture

ok, found the issue...

the access control logic is incorrect.

the condition is to throw an AccessDeniedHttpException when $entity_access is anything other then isAllowed,
however the value returned from $entity_access = $entity->access('view', NULL, TRUE);
is "\Drupal\Core\Access\AccessResultNeutral"
which should be handled as isNeutral.

so the real fix hear, is to not run the logic on if (!$entity_access->isAllowed()) rather on isForbidden which is what a 403 Forbidden / AccessDeniedHttpException actually is.

actual code change would be on line 44 of core/modules/rest/src/Plugin/rest/resource/EntityResource.php

if ($entity_access->isForbidden()) {

working on generating a patch...

jacov’s picture

StatusFileSize
new621 bytes
jacov’s picture

Status: Active » Needs review
jacov’s picture

StatusFileSize
new658 bytes

adding patch for 8.2.x branch as well

jacov’s picture

StatusFileSize
new658 bytes

adding patch for 8.2.x branch as well

jacov’s picture

cilefen’s picture

Issue tags: +Needs tests
jacov’s picture

confirmed patch #8 fixes the 403 Forbidden 'error' for requests to 'entity/taxonomy_vocabulary/{id}'

the 403 & null 'message' issue on endpoint '/taxonomy/term/{taxonomy_term}' still remains, working on debugging that one too...

jacov’s picture

going to edit this issue description to ensure patch makes it, and filed #2772537: REST Views override existing REST GET routes to be addressed seperately

jacov’s picture

Title: REST endpoints for taxonomy not working. GET / POST on entity/taxonomy_vocabulary/{id} & /taxonomy/term/{taxonomy_term} 403 Forbidden with Error » REST GET fails on entity/taxonomy_vocabulary/{id} 403 Forbidden with error
Issue summary: View changes
jacov’s picture

Status: Needs review » Reviewed & tested by the community
jacov’s picture

Status: Reviewed & tested by the community » Patch (to be ported)
jacov’s picture

cilefen’s picture

Status: Patch (to be ported) » Needs review

Hi! Patches are peer-reviewed and this one lacks a test.

wim leers’s picture

Priority: Critical » Major
Status: Needs review » Needs work
  1. The analysis in #7 is wrong. HEAD is correct. You're making up your own interpretation of AccessResultInterface values. Read the code and its docs. And perhaps read the relevant change record (https://www.drupal.org/node/2337377).
  2. Because of this, the patch in this issue introduces an access bypass security vulnerability.
  3. Never self-RTBC patches, as @cilefen said in #20, you need peer review.
  4. Every bug fix needs a test to prove that it's actually fixing what's perceived as a bug.
  5. This is not remotely a critical bug. See https://www.drupal.org/core/issue-priority#critical-bug.

Are you perhaps new to open source?

wim leers’s picture

Status: Needs work » Postponed (maintainer needs more info)

Please post your rest.settings.yml.

wim leers’s picture

Also marked #2772537: REST Views override existing REST GET routes as a duplicate for now, because it's not yet clear that this issue is a bug, let alone that we need yet another, almost-duplicate issue.

dawehner’s picture

Thank you for your patch

+++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
@@ -90,7 +90,7 @@ public static function create(ContainerInterface $container, array $configuratio
-    if (!$entity_access->isAllowed()) {
+    if ($entity_access->isForbidden()) {

Note: \Drupal\Core\Access\AccessManager::check uses also isAllowed which is the canonical place for checking access on routes.

Let me also quote AccessResultInterface:

 * IMPORTANT NOTE: You have to call isAllowed() when you want to know whether
 * someone has access. Just using

. Given that I think the problem is rather the vocabulary access check.

If this is just about access checking on vocabularies, I also can't really believe this is critical, but feel free to disagree with it :)

jacov’s picture

thanks @dawehner && @wim-leers

if the access control logic is working as intended, then a neutral value should not be passed in the previous $entity_access line, as it will never work...

$entity_access = $entity->access('view', NULL, TRUE);

here is my settings...

rest.settings.yml

resources:
  'entity:node':
    GET:
      supported_formats:
        - hal_json
        - json
      supported_auth:
        - basic_auth
    POST:
      supported_formats:
        - hal_json
        - json
      supported_auth:
        - basic_auth
    DELETE:
      supported_formats:
        - hal_json
        - json
      supported_auth:
        - basic_auth
    PATCH:
      supported_formats:
        - hal_json
        - json
      supported_auth:
        - basic_auth
  'entity:taxonomy_vocabulary':
    GET:
      supported_formats:
        - hal_json
        - json
      supported_auth:
        - basic_auth
  'entity:taxonomy_term':
    GET:
      supported_formats:
        - hal_json
        - json
      supported_auth:
        - basic_auth
    POST:
      supported_formats:
        - hal_json
        - json
      supported_auth:
        - basic_auth
link_domain: null
_core:
  default_config_hash: E9VXRiWZNet4YVBv8j9WQmTlgb-rOjo0MiCSdgV0Guw

i marked this as critical because without the taxonomy endpoints working, the REST service is not ready for production.

wim leers’s picture

i marked this as critical because without the taxonomy endpoints working, the REST service is not ready for production.

That may very well be, but it still doesn't meet the "critical" definition.

 'entity:taxonomy_vocabulary':
  …

Okay, great. You have enabled the taxonomy vocabulary REST resource. Looking at \Drupal\Core\Entity\EntityAccessControlHandler::checkAccess(), you need the administer taxonomy permission to be allowed to GET Taxonomy Vocabulary config entities. So, does the user that's doing REST requests have that permission?

wim leers’s picture

Note that vocabularies are config entities. Config entity GET support was added in Drupal 8.2, in #2724823: EntityResource: read-only (GET) support for configuration entities. This is not supported in Drupal 8.1.

wim leers’s picture

Also note that you won't be able to PATCH/POST/DELETE vocabulary entities at all, for that we'll need #2300677: JSON:API POST/PATCH support for fully validatable config entities to happen first.

That being said, the error message you're seeing is extremely unhelpful. That's unacceptable. To fix that, we have #2681911: REST requests without X-CSRF-Token header: unhelpful response significantly hinders DX, should receive a 401 response and #2659070: REST requests without Content-Type header: unhelpful response significantly hinders DX, should receive a 415 response. But those only improve error messages for PATCH/POST/DELETE requests. I don't yet know what is causing this particular error. Investigating…

jacov’s picture

fyi...

after applying the patch, i can see the proper response & json as follows:

{
  "uuid": "2ed09cb3-d293-44cf-a9c1-a3bab4d0c17c",
  "langcode": "en",
  "status": true,
  "dependencies": [],
  "_core": {
    "default_config_hash": "lO5ziR5dVI1PpEeHZsSOfQ-Y7NWihSDKW8-MMf6uoms"
  },
  "name": "Tags",
  "vid": "tags",
  "description": "Use tags to group articles on similar topics into categories.",
  "hierarchy": 0,
  "weight": 0
}
jacov’s picture

Status: Postponed (maintainer needs more info) » Needs review
wim leers’s picture

Status: Needs review » Needs work

Cool, but the patch is definitely wrong. You'll need to debug this response, to figure out why it's getting a "neutral" access result and not an "allowed" one.

Enable xdebug and put a breakpoint in \Drupal\Core\Entity\EntityAccessControlHandler::checkAccess(), that should lead you to the root cause.

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.

wim leers’s picture

Status: Needs work » Postponed (maintainer needs more info)

Does this user have the administer taxonomy permission?

EDIT: to clarify: you say this in the IS:

Access GET on Taxonomy term resource
Access GET on Taxonomy vocabulary resource

But that's not enough. That's just the default 8.1.x way of allowing access to a REST resource in the first place (that's gone by default in 8.2). You then also need access to perform this operation on that entity: you need to be allowed to do this by $entity->access($operation) too!

jacov’s picture

no Wim, at the time the user did not have administer taxonomy permissions enabled.

only RESTful Web Services:
* Access GET on Taxonomy term resource
* Access GET on Taxonomy vocabulary resource

i later went in and enabled administer taxonomy permissions, so that i can GET and POST new terms, and that worked.

so yes, it looks like administer taxonomy permissions is required for GET to work, which is technically "dangerous" if you are looking to only open READ ONLY / GET access.

imho, the fix here should be to respect the RESTful Web Services permissions over the administer taxonomy permissions, because we may not want to necessarily allow full admin access to the api user.

wim leers’s picture

Category: Bug report » Support request
Priority: Major » Normal
Status: Postponed (maintainer needs more info) » Fixed

so yes, it looks like administer taxonomy permissions is required for GET to work, which is technically “dangerous” if you are looking to only open READ ONLY / GET access.

Yes it is. But the solution then is to add additional permissions for viewing/updating/… Vocabulary. For now, there is not a separate "view vocabulary" permission.

imho, the fix here should be to respect the RESTful Web Services permissions over the administer taxonomy permissions, because we may not want to necessarily allow full admin access to the api user.

This would be at least equally dangerous, because it means the Entity Access API would need to be bypassed. Furthermore, in Drupal 8.2 and beyond, the restful get <entity type> permission is no longer enabled by default (existing sites will continue to have that, and new sites can opt in to it). Precisely because it's very confusing that there's a separate permission on top of the Entity Access API that must already grant you access anyway.

So, two follow-ups must be solved:

  1. saner default access to Vocabulary entities: #2808217: To be able to view Vocabulary config entities via REST, one should not have to grant the 'administer taxonomy' permission (patch posted!)
  2. better error responses, that tell you why you're getting a 403: #2808233: REST 403 responses don't tell the user *why* access is not granted: requires deep Drupal understanding to figure out

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.