Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: openid-connect: Logout not working using Firefox Version >= 128.0 #11492

Open
markusmueller opened this issue Aug 8, 2024 · 6 comments
Open
Labels
bug Something isn't working dependencies Pull requests that update a dependency file

Comments

@markusmueller
Copy link
Contributor

Current Behavior

Using Firefox version >= 128.0 the /logout path provided by the openid-connect plugin is not redirecting to the configured IDP for logout but instead returning a 1x1 pixel image.

Root Cause:
Firefox Version 128.0 changed the network.http.accept default value also adding image/png.

This is causing lua-resty-openidc used by the openid-connect plugin to return the image.

There is already a discussion on lua-resty-openidc.

Once the issue is resolved upstream the dependency should be updated.

A possible workaround in the meantime is patching the openid-connect plugin and overwriting the Accept header for the /logout path in openid-connect.lua:

ngx.req.set_header("Accept", "text/html")

Expected Behavior

Using Firefox v 128.0 the path /logout will redirect to the configured IDP for logout.

Error Logs

No response

Steps to Reproduce

Configure Apisix openid-connect plugin with logout and hit /logout using Firefox version >= 128.0.

Environment

  • APISIX version (run apisix version):
  • Operating system (run uname -a):
  • OpenResty / Nginx version (run openresty -V or nginx -V):
  • etcd version, if relevant (run curl http://127.0.0.1:9090/v1/server_info):
  • APISIX Dashboard version, if relevant:
  • Plugin runner version, for issues related to plugin runners:
  • LuaRocks version, for installation issues (run luarocks --version):
Copy link

dosubot bot commented Aug 8, 2024

Hey @markusmueller! 👋 I'm here to help you with any bugs, questions, or contributions you have regarding our repository.

To address the issue with the /logout path not redirecting correctly in Firefox version 128.0 or higher, you can patch the APISIX openid-connect plugin to overwrite the Accept header. Here is how you can do it:

  1. Modify the Plugin Code:
    Add a function to handle the /logout path and set the Accept header to text/html.

    local function handle_logout_request()
        local uri = ngx.var.uri
        if uri == "/logout" then
            ngx.req.set_header("Accept", "text/html")
        end
    end
  2. Integrate the Function:
    Call this function in the main handler function of the plugin. The main handler function in the openid-connect plugin is the rewrite function.

    function _M.rewrite(plugin_conf, ctx)
        local conf = core.table.clone(plugin_conf)
    
        -- Previously, we multiply conf.timeout before storing it in etcd.
        -- If the timeout is too large, we should not multiply it again.
        if not (conf.timeout >= 1000 and conf.timeout % 1000 == 0) then
            conf.timeout = conf.timeout * 1000
        end
    
        local path = ctx.var.request_uri
    
        -- Call the function to handle the logout request
        handle_logout_request()
    
        -- Continue with the rest of the plugin logic
    end
  3. Test the Patch:
    Ensure that the logout request is properly handled in the plugin's test cases. You can add a test case to verify that the Accept header is set correctly during the logout process.

    local http = require "resty.http"
    local httpc = http.new()
    local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/logout"
    local res, err = httpc:request_uri(uri, {method = "GET"})
    ngx.status = res.status
    local location = res.headers['Location']
    if location and string.find(location, 'https://iresty.com') ~= -1 and
        string.find(location, 'post_logout_redirect_uri=https://iresty.com') ~= -1 then
        ngx.say(true)
    end

This patch ensures that when the /logout path is accessed, the Accept header is set to text/html, which should resolve the redirection issue in Firefox version 128.0 or higher [1][2][3].

To continue talking to Dosu, mention @dosu.

@dosubot dosubot bot added bug Something isn't working dependencies Pull requests that update a dependency file labels Aug 8, 2024
@francescodedomenico
Copy link

francescodedomenico commented Aug 12, 2024

@dosu I tried modifying the original openid-connect plugin, however I get the following error when trying:
2024-08-12 20:20:40 2024/08/12 18:20:40 [error] 40#40: *48955 [lua] config_yaml.lua:269: failed to fetch data from local file /usr/local/apisix/conf/apisix.yaml: /usr/local/apisix/apisix/plugins/openid-connect.lua:310: attempt to call field 'check_https' (a nil value), apisix.yaml key: plugin_configs, context: ngx.timer

the original plugin works correctly with the same configuration.

Update

I have personally solved following a different approach, I have written a patched openidc.lua that has the lines:

-- if header and header:find("image/png") then
  --   ngx.header["Cache-Control"] = "no-cache, no-store"
  --   ngx.header["Pragma"] = "no-cache"
  --   ngx.header["P3P"] = "CAO PSA OUR"
  --   ngx.header["Expires"] = "0"
  --   ngx.header["X-Frame-Options"] = "DENY"
  --   ngx.header.content_type = "image/png"
  --   ngx.print(openidc_transparent_pixel)
  --   ngx.exit(ngx.OK)
  --   return

commented (lines from 1314 to 1323)
and I have replaced the original one shipped with apisix: /usr/local/apisix/deps/share/lua/5.1/resty/openidc.lua

Works perfectly for me

@francescodedomenico
Copy link

@markusmueller the issue is due to the decision of lua-resty-openidc to support a peculiar Single Logout implemented by PingFederate, so it's nothing apisix can do unless forking the library and removing this custom PF logout support.
I did perform the investigation here if you're interested: zmartzone/lua-resty-openidc#521 (comment)

@markusmueller
Copy link
Contributor Author

Interesting to see where the PNG based logout originated, thanks for the update @francescodedomenico!

@remydewa
Copy link

What I did as quick win for the moment: Using the serverless-pre-function plugin and apply a part of the code mentioned here: #11492 (comment)

"serverless-pre-function": {
  "functions": [
    "return function(conf, ctx)\n\n local ngx = ngx \n local uri = ngx.var.uri \n if uri == '/users/logout' then \n ngx.req.set_header('Accept', 'text/html') \n end \n end"
  ],
  "phase": "rewrite"
}

@amaino
Copy link

amaino commented Oct 28, 2024

The bug is fixed in the lua-resty-openidc now. Was this code included in the last release? zmartzone/lua-resty-openidc#525

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working dependencies Pull requests that update a dependency file
Projects
Status: 📋 Backlog
Development

No branches or pull requests

4 participants