CVE-2023-31143 (Python, published 2023-05-09T15:15Z)
Description: value: mage-ai is an open-source data pipeline tool for transforming and integrating data. Those who use Mage starting in version 0.8.34 and prior to 0.8.72 with user authentication enabled may be affected by a vulnerability. The terminal could be accessed by users who are not signed in or do not have editor permissions. Version 0.8.72 contains a fix for this issue.
Severity: nan (CVSS v3 base score: 9.8)
Weakness: CWE-306 \u2014 Missing Authentication for Critical Function
The product does not perform any authentication for functionality that requires a provable user identity or consumes a significant amount of resources.
Repository: https://github.com/mage-ai/mage-ai
Files changed:
mage_ai/frontend/components/Terminal/index.tsx
mage_ai/server/terminal_server.py
Commit message: [dy] Fix terminal user authentication (#2586)

* [dy] Update terminal user authentication

* [dy] Update auth

Vulnerable code:
    sendMessage(JSON.stringify([
      'stdin', cmd,
    ]));
    sendMessage(JSON.stringify([
      'stdin', '\r',
    ]));
            sendMessage(JSON.stringify([
              'stdin', command,
            ]));
            sendMessage(JSON.stringify([
              'stdin', '\x03',
            ]));
from mage_ai.api.utils import authenticate_client_and_token
from mage_ai.settings import REQUIRE_USER_AUTHENTICATION
                else:
                    raise Exception('Invalid token')

Fixed code:
import AuthToken from '@api/utils/AuthToken';
import { OAUTH2_APPLICATION_CLIENT_ID } from '@api/constants';
  const token = useMemo(() => new AuthToken(), []);
  const oauthWebsocketData = useMemo(() => ({
    api_key: OAUTH2_APPLICATION_CLIENT_ID,
    token: token.decodedToken.token,
  }), [
    token,
  ]);

    sendMessage(JSON.stringify({
      ...oauthWebsocketData,
      command: ['stdin', cmd + '\r'],
    }));
            sendMessage(JSON.stringify({
              ...oauthWebsocketData,
              command: ['stdin', command],
            }));
            sendMessage(JSON.stringify({
              ...oauthWebsocketData,
              command: ['stdin', '\x03'],
            }));
from mage_ai.api.utils import (
    authenticate_client_and_token,
    has_at_least_editor_role,
)
from mage_ai.settings import (
    is_disable_pipeline_edit_access,
    REQUIRE_USER_AUTHENTICATION,
)
from tornado import gen
import json
    @gen.coroutine
    def on_message(self, raw_message):
        message = json.loads(raw_message)

        api_key = message.get('api_key')
        token = message.get('token')
        command = message.get('command')

        if REQUIRE_USER_AUTHENTICATION or is_disable_pipeline_edit_access():
            valid = False

            if api_key and token:
                oauth_client = Oauth2Application.query.filter(
                    Oauth2Application.client_id == api_key,
                ).first()
                if oauth_client:
                    oauth_token, valid = authenticate_client_and_token(oauth_client.id, token)
                    valid = valid and \
                        oauth_token and \
                        oauth_token.user and \
                        has_at_least_editor_role(oauth_token.user)
            if not valid or is_disable_pipeline_edit_access():
                return self.send_json_message(
                    ['stdout', f'{command[1]}\nUnauthorized access to the terminal.'])

        super().on_message(json.dumps(command))