selfoss icon indicating copy to clipboard operation
selfoss copied to clipboard

Authentication with multiple instances on the same server

Open davidoskky opened this issue 1 year ago • 9 comments

Quite a niche problem, but I'll point it out. I have a few different selfoss instances installed on a server for testing purposes. These are simply placed in different folders and thus you can access them by changing folder in the url. Logging into one instance also gives you access to the other ones and logging out from one logs you out from all of them. This happens even if the credentials to access the instances are different.

davidoskky avatar Jan 26 '23 13:01 davidoskky

Right, we use the same session variable:

https://github.com/fossar/selfoss/blob/b4d6cf9a1e236bf8c92f1a8957acbc1362e49288/src/helpers/Authentication.php#L98

The session cookie can be limited to certain path. It applies to / by default but we should be setting it to a subdirectory so I would expect it to not be cross-contaminated:

https://github.com/fossar/selfoss/blob/b4d6cf9a1e236bf8c92f1a8957acbc1362e49288/src/helpers/Authentication.php#L41

If you set logger_level=DEBUG in your config.ini, what do you see in the log? There should be something like the following:

https://github.com/fossar/selfoss/blob/b4d6cf9a1e236bf8c92f1a8957acbc1362e49288/src/helpers/Authentication.php#L47

jtojnar avatar Jan 26 '23 14:01 jtojnar

Does this mean that anyone with write access on the webserver can fabricate a cookie to obtain access?

Logs: Logging in from another instance:

[2023-01-26 09:39:51] selfoss.DEBUG: set cookie on */selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 09:39:51] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 09:39:51] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/*/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 09:39:51] selfoss.DEBUG: Establishing SQLite database connection  
[2023-01-26 09:39:51] selfoss.DEBUG: set cookie on */selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 09:39:51] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 09:39:51] selfoss.DEBUG: set cookie on */selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 09:39:51] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 09:39:51] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/*/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 09:39:51] selfoss.DEBUG: Establishing SQLite database connection  

Logging in normally:

[2023-01-26 09:36:50] selfoss.DEBUG: set cookie on */selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 09:36:50] selfoss.DEBUG: logged in using valid session  
[2023-01-26 09:36:50] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 09:36:50] selfoss.DEBUG: set cookie on */selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 09:36:50] selfoss.DEBUG: logged in using valid session  
[2023-01-26 09:36:50] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/*/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 09:36:50] selfoss.DEBUG: Establishing SQLite database connection  

davidoskky avatar Jan 26 '23 14:01 davidoskky

I'll correct myself, access is not granted in any case. Logout always logs out from all instances. Log in instance 1, log out from instance 2, [instance 1 logged out], log in instance 2 -> access granted to instance 1 Log in instance 1, log out from instance 1, [instance 2 logged out], log in instance 2 -> access to instance 1 not granted

davidoskky avatar Jan 26 '23 14:01 davidoskky

Does this mean that anyone with write access on the webserver can fabricate a cookie to obtain access?

The cookie contains a session ID so to fabricate the cookie, you would need to obtain the session ID. The session storage directory should be only available to the user the PHP server is running under. Normally, you would use separate php-fpm service running under a different user for each web app so that should not be an issue.

So unless someone can run programs under the same PHP user as your selfoss instance you should be safe. If that was allowed, they could just access database credentials directly, anyway.

jtojnar avatar Jan 26 '23 15:01 jtojnar

I do not think anything have changed in this area but are you running latest snapshot or 2.19?

access is not granted in any case. Logout always logs out from all instances. Log in instance 1, log out from instance 2, [instance 1 logged out], log in instance 2 -> access granted to instance 1 Log in instance 1, log out from instance 1, [instance 2 logged out], log in instance 2 -> access to instance 1 not granted

Hmm, that does not make sense to me.

Just to confirm, the asterisk in your log is where you replaced the domain?

It is weird that both selfoss instances say “set cookie on */selfoss_test/”.

  1. What URLs do you use to access them? You can replace the domain with localhost or some other placeholder to anonymize it.
  2. What is the directory structure like? Is each instance in an independent subdirectory of the same root (e.g. /srv/http/my-domain) or is one instance nested inside the other?
  3. What web server do you use and how did you configure it? With Apache, do you use a single VirtualHost or multiple ones?

jtojnar avatar Jan 26 '23 15:01 jtojnar

Both instances are running 2.19 I replaced the domain with *. These logs were both from the same instance, I'm using Apache and these instances are in the same virtualhost each in an independent subdirectory of the same root folder.

I'll provide more logs performing the two sequences, I start by clearing the cookies, during the procedure I had two cookies most of the passages.

Instance 1
Log in instance 1
[2023-01-26 10:56:25] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 10:56:25] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 10:56:25] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 10:56:25] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 10:56:25] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 10:56:25] selfoss.DEBUG: logged in using valid session  
[2023-01-26 10:56:25] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 10:56:25] selfoss.DEBUG: Establishing SQLite database connection  

Log out of instance 2
[2023-01-26 10:57:52] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 10:57:52] selfoss.DEBUG: logged in using valid session  
[2023-01-26 10:57:52] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 10:57:52] selfoss.DEBUG: Establishing SQLite database connection  
[2023-01-26 10:57:52] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 10:57:52] selfoss.DEBUG: logged in using valid session  

Log in instance 2
[2023-01-26 10:59:26] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 10:59:26] selfoss.DEBUG: logged in using valid session  
[2023-01-26 10:59:26] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 10:59:26] selfoss.DEBUG: Establishing SQLite database connection  
[2023-01-26 10:59:27] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 10:59:27] selfoss.DEBUG: logged in using valid session  
[2023-01-26 10:59:27] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 10:59:27] selfoss.DEBUG: logged in using valid session  
[2023-01-26 10:59:27] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 10:59:27] selfoss.DEBUG: Establishing SQLite database connection  

Clear cookies and log in instance 1
[2023-01-26 11:02:45] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 11:02:45] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:02:45] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 11:02:45] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 11:02:45] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 11:02:45] selfoss.DEBUG: logged in using valid session  
[2023-01-26 11:02:45] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:02:45] selfoss.DEBUG: Establishing SQLite database connection   

Log out of instance 1
[2023-01-26 11:03:35] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 11:03:35] selfoss.DEBUG: logged in using valid session  
[2023-01-26 11:03:35] selfoss.DEBUG: logged out and destroyed session  

Log in instance 2
[2023-01-26 11:04:31] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 11:04:31] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:04:31] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:04:31] selfoss.DEBUG: Establishing SQLite database connection  
[2023-01-26 11:04:31] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 11:04:31] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:04:31] selfoss.DEBUG: set cookie on localhost/selfoss/ expiring in 2592000 seconds  
[2023-01-26 11:04:31] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:04:31] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:04:31] selfoss.DEBUG: Establishing SQLite database connection  
Instance 2
Log in instance 1
[2023-01-26 10:56:30] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 10:56:30] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 10:56:30] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 10:56:30] selfoss.DEBUG: Establishing SQLite database connection  
[2023-01-26 10:56:30] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 10:56:30] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 10:56:30] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 10:56:30] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 10:56:30] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 10:56:30] selfoss.DEBUG: Establishing SQLite database connection  

Log out of instance 2
[2023-01-26 10:57:48] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 10:57:48] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 10:57:48] selfoss.DEBUG: logged out and destroyed session  

Log in instance 2
[2023-01-26 10:59:22] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 10:59:22] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 10:59:22] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 10:59:22] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 10:59:22] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 10:59:22] selfoss.DEBUG: logged in using valid session  
[2023-01-26 10:59:22] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 10:59:22] selfoss.DEBUG: Establishing SQLite database connection  

Clear cookies and log in instance 1
[2023-01-26 11:02:57] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:02:57] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:02:57] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:02:57] selfoss.DEBUG: Establishing SQLite database connection  
[2023-01-26 11:02:57] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:02:57] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:02:57] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:02:57] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:02:57] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:02:57] selfoss.DEBUG: Establishing SQLite database connection  

Log out of instance 1
[2023-01-26 11:03:38] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:03:38] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:03:38] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:03:38] selfoss.DEBUG: Establishing SQLite database connection  
[2023-01-26 11:03:38] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:03:38] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:03:38] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:03:38] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:03:38] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:03:38] selfoss.DEBUG: Establishing SQLite database connection  

Log in instance 2
[2023-01-26 11:04:26] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:04:26] selfoss.DEBUG: session does not contain valid auth  
[2023-01-26 11:04:26] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 11:04:26] selfoss.DEBUG: logged in with supplied username and password  
[2023-01-26 11:04:26] selfoss.DEBUG: set cookie on localhost/selfoss_test/ expiring in 2592000 seconds  
[2023-01-26 11:04:26] selfoss.DEBUG: logged in using valid session  
[2023-01-26 11:04:26] selfoss.DEBUG: Creating database connection {"dsn":"sqlite:/home/ylxnfqev/domains/localhost/public_html/selfoss_test/src/helpers/../../data/sqlite/selfoss.db"} 
[2023-01-26 11:04:26] selfoss.DEBUG: Establishing SQLite database connection  

davidoskky avatar Jan 26 '23 16:01 davidoskky

Instance 2 has publicMode set to 1 if that could be relevant, didn't think about it earlier.

davidoskky avatar Jan 26 '23 16:01 davidoskky

Oh, that explains it then.

The authentication works fine on server-side but the JavaScript client remembers whether it is signed in (and stores it in localstorage, which probably is not segregated by path).

If you try to access non-public mode instance, the client will get 403 from the server and go to login screen. If you try to access public instance while the client still remembers being logged in, it will be none the wiser.

jtojnar avatar Jan 26 '23 16:01 jtojnar

I tried setting the scope to ./ in the web manifest but it does not seem to affect the Origin for the purpose of localStorage. Will need to come up with something else.

jtojnar avatar Jan 26 '23 16:01 jtojnar