Disable existing applications from any Connections does not work for Organizations

It looks like that is possible to access organization from disabled application which is not enabled for a particular connection (but it is potentially be enabled for a user, but not for particular organization).

It means that organization can be accessed via disabled application which is potential security issue.

Steps to reproduce:

  1. Create a new application eg. Single Page Web Application with test-app name;
  2. Create a new connection eg. Database Connections with test-basic name;
  3. Disable all applications for test-basic connection including test-app one;
  4. Crate a new Organization with test-org name and enable test-basic connection;
  5. Try to sign in into test-org by using test-basic connection and test-app application.

Workaround:

  1. Create a new Actions to fix that issue.
const https = require('https');

function request(opts, data) {
  return new Promise((resolve, reject) => {
    const req = https.request(opts, (res) => {
      if (res.statusCode < 200 || res.statusCode >= 300) {
        return reject(new Error(res.statusCode.toString()));
      }
      const body = [];
      res.setEncoding('utf8');
      res.on('data', (chunk) => {
        body.push(Buffer.from(chunk));
      });
      res.on('end', () => {
        try {
          const data = JSON.parse(Buffer.concat(body).toString());
          resolve(data);
        } catch (e) {
          reject(e);
        }
      });
      res.on('error', (err) => {
        reject(err);
      });
    });
    if (data) {
      req.write(Buffer.from(data));
    }
    req.end();
  });
}

/**
 * Handler that will be called during the execution of a PostLogin flow.
 *
 * @param {Event} event - Details about the user and the context in which they are logging in.
 * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
 */
exports.onExecutePostLogin = async (event, api) => {
  const tokenData = JSON.stringify({
    grant_type: 'client_credentials',
    client_id: event.secrets.AUTH0_CLIENT_ID,
    client_secret: event.secrets.AUTH0_CLIENT_SECRET,
    audience: `https://${event.secrets.AUTH0_DOMAIN}/api/v2/`,
  });
  const token = await request(
    {
      hostname: event.secrets.AUTH0_DOMAIN,
      path: '/oauth/token',
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(tokenData),
      },
    },
    tokenData
  );
  const connection = await request({
    hostname: event.secrets.AUTH0_DOMAIN,
    path: `/api/v2/connections/${event.connection.id}?fields=enabled_clients&include_fields=true`,
    method: 'GET',
    headers: {
      Authorization: `${token.token_type} ${token.access_token}`,
      'Content-Type': 'application/json',
    },
  });
  const clientId = event.client.client_id;
  const appName = event.client.metadata.name ?? event.client.name;
  const orgName =
    event.organization?.metadata.name ?? event.organization?.display_name;
  const isEnabled = connection.enabled_clients.includes(clientId);
  if (!isEnabled) {
    api.access.deny(
      `"${appName}" application is not allowed for "${orgName}" organization.`
    );
  }
};

/**
 * Handler that will be invoked when this action is resuming after an external redirect. If your
 * onExecutePostLogin function does not perform a redirect, this function can be safely ignored.
 *
 * @param {Event} event - Details about the user and the context in which they are logging in.
 * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
 */
exports.onContinuePostLogin = async () => {};

Hi @maratd

Welcome to the Auth0 Community!

When you enable an organisation against a client the system looks for a connection against that organisation. The connections against the client do not come into play, so if the connection against the client is disabled or enabled it doesn’t really matter (providing an organisation is enabled against the client).

If you navigate to the client and click on the connections tab, you should get a message to say something like this client is configured to use organisation connections and the rest of the screen will be disabled.

I hope this clarifies the issue.
Regards