[security] SSO with SAML: Locking down the direct login option

It could very well be that this is a known config option and that I have just searched with all the wrong terms, in that case please forgive me.

I just more or less finished setting up a test install of nextcloud with SAML (SSO) and LDAP, while configuring this the configuration dialog constantly reminds you that if you somehow broke your settings you can always bypass the broken configuration with login?direct=1 which is great.

Now that I have actually finished setting up SAML I would like to lock down the bypass option since it does not use 2FA from the IdP thus providing for a less secure authentication avenue, if impossible to lock down I would like to at least limit access to be only from localhost or something along those lines.

Is that at all possible?

@wwe thanks for the edit, I’m not sure though should this really be classified as SSO with SAML under apps?

The login page that I seek to restrict access to is part of nextcloud core as far as I understand things.

The option to override SSO login with login?direct=1 is common for all SSO applications. I choose to focus on SAML because of your question and because of possible details specific for this app/protocol.

I didn’t add this before as i didn’t complete my thinking… but once we write:

I don’t remember any internal way to block this URL. Maybe your security requirements are met by setiing random passwords and enforcing 2FA on NC level? Don’t forget this is the only way you can access you NC if the IdP login fails for any reason. If you still want to block the URL I would suggest blocking ot on the edge e.g. reverse proxy.

When using SAML + LDAP (where SAML is only allowed for accounts that exist in LDAP) the bypass login page allows password only login for LDAP accounts as far as I can tell (I will double check that after enabling 2FA on nextcloud), a situation which for obvious reasons is very undesirable.

I understand that this is an important backup way of accessing the system but it would seem to me that should I need emergency access I should be able to enable/disable this with the occ tool from command line and thus lock down the system when no emergency access is needed.

Blocking with a reverse proxy would also be a royal pain in the rear since the request is for /login?direct=1 while /login and /login?lots=of&other&get&params play a critical role in the login process thus you would need to filter for only direct=1.

Just checked with 2FA enabled -

  1. The initial account I created when setting up nextcloud (and only “native” account) was forced to use 2FA.
  2. LDAP accounts were not forced to use 2FA even though I expressly did include their group.

So that is not a solution.

A different option might be to somehow disable direct login for LDAP accounts while still allowing NC to use the LDAP backend to get contacts and account information.

if the user is replicated from LDAP Nextcloud does not know the password of the user. It forwards login request to LDAP server which in turn performs the authentication. likely you can disable LDAP auth (maybe unchecking everything on LDAP “login tab” in LDAP config…

In order to control which LDAP users can login to your Nextcloud server use the Login Attributes tab. Those LDAP users who have access but are not listed as users (if there are any) will be hidden users.

my expectation would be if there is no attribute to login through LDAP login?direct=1 stops working for this users…

Blocking with a reverse proxy would also be a royal pain

Not particularly, at least with nginx. I’m personally using this method: https://github.com/nextcloud/user_saml/issues/284#issuecomment-450362632 Note I dropped the index.php as I have that hidden on my setup.

Nginx config:

    error_page 418 = @blockAccess;
    location /login {
        proxy_pass     http://nextcloud_backend_server/login;
        # ...
        # other nextcloud specific header-options
        # ...
        if ($args ~ '(&|^)direct([&=]|$)' ) {
            return 418;
        }
    }
    location @blockAccess {
        deny all;
    }
1 Like

That just breaks LDAP login/queries which also break SAML since it is set to limit to only those users who are also available via LDAP (which is how I limit to specific group membership).

I’m going to try implementing that directly on the apache that hosts it later, really don’t feel like adding a reverse proxy into the mix at this stage.

My worry was actually more along the line of needless loss of performance when the http server needs to also parse the GET vars as if it is some kind of security appliance protecting a buggy web application.

after reading the referenced github issues I think this might do a trick:

use a filter like thisAttributeDoesNotExist=%uid for login.

That does the trick :slight_smile: