Adding Generic Oauth2 app and set empty scope then cause system crash

Created on 25 February 2022, almost 3 years ago
Updated 29 March 2023, almost 2 years ago

Problem/Motivation

Steps to reproduce

1. /admin/config/people/openid-connect/add/generic
2. clear Scopes
3. Save and edit again.

TypeError: implode(): Argument #2 ($array) must be of type ?array, string given in implode() (line 98 of /opt/drupal/web/modules/contrib/openid_connect/src/Plugin/OpenIDConnectClient/OpenIDConnectGenericClient.php)
#0 /opt/drupal/web/modules/contrib/openid_connect/src/Plugin/OpenIDConnectClient/OpenIDConnectGenericClient.php(98): implode()
#1 /opt/drupal/web/modules/contrib/openid_connect/src/Form/OpenIDConnectClientFormBase.php(105): Drupal\openid_connect\Plugin\OpenIDConnectClient\OpenIDConnectGenericClient->buildConfigurationForm()
#2 [internal function]: Drupal\openid_connect\Form\OpenIDConnectClientFormBase->buildForm()
#3 /opt/drupal/web/core/lib/Drupal/Core/Form/FormBuilder.php(531): call_user_func_array()
#4 /opt/drupal/web/core/lib/Drupal/Core/Form/FormBuilder.php(278): Drupal\Core\Form\FormBuilder->retrieveForm()
#5 /opt/drupal/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm()
#6 [internal function]: Drupal\Core\Controller\FormController->getContentResult()
#7 /opt/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
#8 /opt/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(564): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#9 /opt/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext()
#10 /opt/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
#11 /opt/drupal/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#12 /opt/drupal/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
#13 /opt/drupal/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle()
#14 /opt/drupal/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
#15 /opt/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#16 /opt/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
#17 /opt/drupal/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
#18 /opt/drupal/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#19 /opt/drupal/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#20 /opt/drupal/web/core/lib/Drupal/Core/DrupalKernel.php(708): Stack\StackedHttpKernel->handle()
#21 /opt/drupal/web/index.php(19): Drupal\Core\DrupalKernel->handle()
#22 {main}

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Needs work

Version

2.0

Component

Code

Created by

πŸ‡¨πŸ‡³China dravenk

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¨πŸ‡³China dravenk

    The #3 just a use case. The description provides the simply steps to reproduce. There are only two steps then you get the result of the system crashing.

  • Status changed to Needs review almost 2 years ago
  • Status changed to RTBC almost 2 years ago
  • πŸ‡΅πŸ‡­Philippines clarkssquared

    Hi dravenk,

    I confirmed the issue was resolved when I applied MR!43 to the "OpenID Connect / OAuth client" module against Version 3.x-dev in my local.

    Please see the screenshots attached for your reference.

    For your review.
    Thank you.

  • First commit to issue fork.
  • πŸ‡ΊπŸ‡ΈUnited States pfrilling Minster, OH

    I was able to write a functional test to confirm this fix is working. During the automated testing, I discovered that the schema for empty scopes is incorrectly storing a string instead of an empty array. I updated the submit configuration form to properly save an array to configuration, but left the other fixes in place for backwards compatibility.

    I'm going to create a followup issue for the other provided clients to get those saving the configuration correctly.

    If someone has time to review my changes, that'd be great!

  • πŸ‡ΊπŸ‡ΈUnited States dcam

    It took me a while to review this, but I think I've unraveled everything. Unfortunately, I disagree with most of the fix in the MR. I think it will be easiest for me to write out my thoughts here rather than to only leave comments on the code. For what it's worth, I didn't really even look at the test. I just tried to figure out a plan for the fix.

    I verified the bug and what you said the actual problem is. You're right: the scopes is set as a string in the configuration. This is what breaks implode() when loading the form.

    What that tells me is that there may be bugged configuration out in the wild. So from my perspective the appropriate fix is to release an update function to fix any bugged config along with the change to the submit function. Instead, the proposed fix just works around bugged config, dealing with it at run time. This just builds technical debt and sounds fragile to me. It would be better to fix the source of the bug.

    So my proposal is to create an update function. It should load the config for any generic and okta plugin instances, repair any string scopes, and resave. As far as testing goes, you should be able to add examples of these bugged configs to the fixture that was committed earlier in the week. I don't think this bug needs to be tested in isolation from other updates.

    I'm not entirely sure what to tell you about the deprecation of the getClientScopes() return type. I was kind of confused by it, partly because the deprecation notice was added to a specific plugin instance. But if you're intent on doing this, then what you really need to do is deprecate the function at the interface. From what I can tell, deprecating a return type hint like this is very uncommon, possibly frowned upon. The deprecation policy β†’ has this to say:

    Generally a return value of method should not changed.

    If it really needs to happen, then I don't know how to do it properly. Deprecation notices usually inform the code that calls the function. That isn't really a concern in this case. You control the code that calls the function. The things that really need to be informed are other plugins that implement the interface. The only other example in the deprecation policy about doing something like this so that implementing classes are notified is from the section on Interface and base/abstract class method signature changes β†’ . You aren't doing exactly the same thing, but it's close.

    I would consider whether or not the deprecation is even necessary. After all, OpenIDConnectClaims::getScopes() is the only thing that calls getClientScopes(). While it would build technical debt, you could just let getScopes() deal with NULL values, comment it thoroughly, and forget about it.

    If you proceed with the deprecation, then I'd do that in a separate issue.

  • πŸ‡ΊπŸ‡ΈUnited States dcam

    dcam β†’ changed the visibility of the branch 3.x to hidden.

  • πŸ‡ΊπŸ‡ΈUnited States dcam

    Since I proposed almost entirely changing the approach I'll put my money where my mouth is and write a new MR.

  • Merge request !132Resolve #3266452 "Update config" β†’ (Open) created by dcam
  • Pipeline finished with Failed
    21 days ago
    Total: 192s
    #385222
  • πŸ‡ΊπŸ‡ΈUnited States dcam

    The current test failure is due to externalauth not being enabled in the fixture. But even when it's enabled the updates fail with an error that I couldn't figure out. I'll work on it more later.

  • Pipeline finished with Success
    18 days ago
    Total: 206s
    #387479
  • πŸ‡ΊπŸ‡ΈUnited States dcam

    I stripped the wrong things out of the fixture additions.

    Anyway, please take a look at MR 132 and let me know what you think. If you like that solution, then I figure that you may want to integrate the GenericClientTest from MR 43. There's no reason to let that work go to waste. I just wanted to test my solution to the issue in isolation.

  • πŸ‡ΊπŸ‡ΈUnited States dcam
Production build 0.71.5 2024