No Code Attached Yet
avatar PhilETaylor
PhilETaylor
9 Jun 2020

Steps to reproduce the issue

Login to Joomla 4 admin
Grab the URL from one of the Ajax requests eg.

http://127.0.0.1/administrator/index.php?option=com_installer&view=update&task=update.ajax&9fdc9c94033edc73ec209fb91fced6b1=1&eid=212

Logout

Load http://127.0.0.1/administrator/index.php?option=com_installer&view=update&task=update.ajax&9fdc9c94033edc73ec209fb91fced6b1=1&eid=212

Expected result

401 Unauthorized
or
403 Forbidden
or
a redirect to /administrator/index.php (This one is probably better)

Actual result

200 OK

URL stays on http://127.0.0.1/administrator/index.php?option=com_installer&view=update&task=update.ajax&9fdc9c94033edc73ec209fb91fced6b1=1&eid=212

login page renders on the above url

avatar PhilETaylor PhilETaylor - open - 9 Jun 2020
avatar joomla-cms-bot joomla-cms-bot - change - 9 Jun 2020
Labels Added: ?
avatar joomla-cms-bot joomla-cms-bot - labeled - 9 Jun 2020
avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

easier to reproduce just by going direct to

http://127.0.0.1/administrator/index.php?option=com_installer

and you get the same thing. 200 OK and a login screen instead of access denied and a REDIRECT to /administrator/index.php to the login screen.

Joomla 3 does the same.

avatar PhilETaylor PhilETaylor - change - 9 Jun 2020
Title
[4.0] When access denied, login page loads, instead of a redirect to the login page
When access denied, login page loads, instead of a redirect to the login page
avatar PhilETaylor PhilETaylor - edited - 9 Jun 2020
avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

Merging #29528 to this one, as they are the same issue, but #29528 has NO BODY to the response when it should really give a JSON response.

avatar brianteeman
brianteeman - comment - 9 Jun 2020

Isn't this the intended behaviour so that when the user does login they go to the bookmarked link.

Trying to understand the problem that you want to solve

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

It is simply and flat out plainly wrong to return a 200 OK for a resource you cannot access.

At the moment every valid URL (I guess, not checked) in Joomla Admin, when logged out, produces a 200 OK response with a body of the login page.

Providing a 404/403 response is the correct response, however I understand that is hard on a visitor and very unhelpful.

Therefore the common way all web apps provide, is to 302 redirect to the login page and set the return param of some part the form params (or session) to the original URL attempted to access so AFTER login the user is returned to the bookmarked (in your example) URL.

This is what all other major platforms do.

WordPress Example

attempt to get to editing in admin when logged out:
https://example.com/wp-admin/edit.php?post_type=page

and you are redirected with a 302 Found to:

HTTP/1.1 302 Found
Cache-Control: no-cache, must-revalidate, max-age=0
Connection: keep-alive
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Jun 2020 16:30:32 GMT
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Location: https://example.com/wp-login.php?redirect_to=https%3A%2F%2Fexample.com%2Fwp-admin%2Fpost.php%3Fpost%3D635%26action%3Dedit&reauth=1

Amazon.co.uk example

Try to access your order summary without being logged in from a bookmarked page:

https://www.amazon.co.uk/gp/your-account/order-history

and get redirected with a 302 Moved Temporarily

HTTP/1.1 302 Moved Temporarily
Connection: close
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Jun 2020 16:31:42 GMT
Location: https://www.amazon.co.uk/ap/signin/260-0274356-3225221?_encoding=UTF8&accountStatusPolicy=P1&openid.assoc_handle=gbflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.co.uk%2Fgp%2Fyour-account%2Forder-history%2F260-0274356-3225221%3Fie%3DUTF8%26%252AVersion%252A%3D1%26%252Aentries%252A%3D0&pageId=webcs-yourorder&showRmrMe=1

Github Example

Attempt tp get to your settings page when logged out

https://github.com/settings/profile

results in a redirect with 302 Found

HTTP/1.1 302 Found
Content-Length: 146
<snip>
location: https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fsettings%2Fprofile
<snip>

Symfony example

Well in my symfony app the "bookmarked page" is stored in the session, and redirect 302 Found to the login page, before being redirected again after login.

avatar ReLater
ReLater - comment - 9 Jun 2020

I don't care about status codes but

a redirect to /administrator/index.php (This one is probably better)

is for sure the badest(!) solution for this issue. I'm happy if backend logged me out and brings me back after login to where I was after login (even if I have to reopen the edit views). That's more important in Joomla 4 with its strange navigation ways than it is in Joomla 3.

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

is for sure the badest(!) solution for this issue.

Actually this is what every other web app and platform does

I'm happy when backend logs me out and brings me back after login to where I was after login

Which is what I proposed and what every other web app and platform does

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

Currently Joomla has 100's of Login pages... on different URLS...

avatar ReLater
ReLater - comment - 9 Jun 2020

I'm happy when backend logs me out and brings me back after login to where I was after login

My bad english ;-)

To clarify:
I already said that I don't care about status codes in the backend. Use whichever you want! But don't redirect to administrator/index.php! That would be just pedantry.

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

But don't redirect to administrator/index.php

That is EXACTLY what I am saying SHOULD be done.

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

CraftCMS example

attempt to load settings page http://example.com/admin/settings

get redirected to login page:

HTTP/1.1 302 Found
Cache-Control: no-store, no-cache, must-revalidate
Connection: Keep-Alive
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Jun 2020 16:56:07 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive: timeout=5, max=100
Location: http://example.com/admin/login
Pragma: no-cache
Server: Apache/2.4.43 (Ubuntu)
Set-Cookie: CraftSessionId=p54plc7919l296gvdr9t9gge22; path=/; HttpOnly
Vary: User-Agent
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: Craft CMS
X-Robots-Tag: none
avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

OctoberCMS Example

attempt to load profile page http://example.com/profile

get redirected to login page:

HTTP/1.1 302 Found
Cache-Control: no-cache, private
Connection: keep-alive
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Jun 2020 16:59:20 GMT
Location: https://example.com/login
Server: nginx
Set-Cookie: XSRF-TOKEN=eyJpdiI6IkpadHd4MjNLNGU0K2EyMTFqaE15emc9PSIsInZhbHVlIjoiNXVhVDhlcitpQnRqaW5Bb2NCeVg5eHpDcFhMUkxYR0hRemppMzlxcUpaN2g5THVQSTBBbHdJYlhxdzd3WW55WiIsIm1hYyI6IjhhZmYyMmM3NjcxNzg0MTBmNmMzY2U1MjY5ZjZmNWE2MmQ3MTcwYjJiMjdiMGYzMjc1MTViNzZlZjEwM2RhMmUifQ%3D%3D; expires=Tue, 09-Jun-2020 18:59:20 GMT; Max-Age=7200; path=/
Set-Cookie: <snip>
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
avatar brianteeman
brianteeman - comment - 9 Jun 2020

I am sure if you feel so strongly about this then you will be submitting a PR to address it.

avatar brianteeman
brianteeman - comment - 9 Jun 2020

It's simple Phil, if you want to see that code then submit it. Otherwise you are just trolling again.

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

No, I'm not trolling...

...but now I am trolling you, Im now your only sponsor on Github. Enjoy a beer a month on me and lighten up and get off my case ...

Screenshot 2020-06-09 at 18 20 44

Screenshot 2020-06-09 at 18 25 29

avatar mbabker
mbabker - comment - 9 Jun 2020

But don't redirect to administrator/index.php! That would be just pedantry.

Phil's right on this one.

The browser should redirect from administrator/index.php?option=com_content to administrator/index.php?return=encoded-url or store the redirect URL in the session. It works this way on every Symfony and Laravel application I have deployed that supports authentication.

The important part is being able to take you to the place you wanted to go after you get authenticated. You don't have to serve the login page on 200 different URLs to achieve that.

avatar brianteeman
brianteeman - comment - 9 Jun 2020

Looking forward to testing the PR

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

Phil's right on this one.

Im never right. Lets not go that far ;-)

It works this way on every Symfony and Laravel application I have deployed that supports authentication.

I have provided clear examples of this in the comments.

The important part is being able to take you to the place you wanted to go after you get authenticated.

Which Joomla already has built in support for ;-)

avatar ReLater
ReLater - comment - 9 Jun 2020

How can you store something in a session that has been deleted during logout because of inactivity?

Maybe I understand it better if you tell us what the real problem is. Security issues?
Or just because "it works this way" here and there?

avatar PhilETaylor
PhilETaylor - comment - 9 Jun 2020

Maybe I understand it better if you tell us what the real problem is.

Its flat out wrong to do it the way Joomla is doing it. That is why no other system does it.

It becomes even more of an issue when you move to API language and you start sending API calls and getting 200 OK responses back when actually they should be 404 or 403 responses.

avatar mbabker
mbabker - comment - 9 Jun 2020

How can you store something in a session that has been deleted during logout because of inactivity?

Because it won't be the inactive session that the data gets stored in. It will be the new session that gets started by your next request that has the redirect info in it.

You time out while having administrator/index.php?option=com_content open, then click a link to an edit page. Your browser's going to navigate to administrator/index.php?option=com_content&task=article.edit&id=42 and Joomla will start a new session when it processes that request, you get redirected to administrator/index.php to log in again with the administrator/index.php?option=com_content&task=article.edit&id=42 URL stored in the session as the page to go back to after being authenticated.

Similar if you just hit refresh after your session times out. It's going to create a new request to the page you're reloading, which starts a new session.

My login pages on my Laravel and Symfony applications don't render on random URLs like /admin/events/635/edit or /tickets/105731/edit (no, I'm not putting the domains on blast here), they correctly redirect to each site's /login page and after authentication are redirected to their originally requested URI (assuming they have appropriate ACL otherwise the system's going to fire a 403 at them).

Maybe I understand it better if you tell us what the real problem is.

The long and short of this is the Joomla administrator application is serving a 200 response with the login page on any random URL if the user has not already authenticated, which is incorrect behavior. The correct behavior is to issue an appropriate redirect to the application's login page and optionally (though 99% of applications do this optional bit) return the user to the originally requested resource.

avatar PhilETaylor PhilETaylor - change - 7 Mar 2022
Status New Closed
Closed_Date 0000-00-00 00:00:00 2022-03-07 18:39:49
Closed_By PhilETaylor
Labels Added: No Code Attached Yet
Removed: ?
avatar PhilETaylor PhilETaylor - close - 7 Mar 2022

Add a Comment

Login with GitHub to post a comment