VYPR
Moderate severityNVD Advisory· Published Mar 14, 2024· Updated Aug 1, 2024

CORS settings overly permissive in vantage6

CVE-2024-23823

Description

vantage6 is an open source framework built to enable, manage and deploy privacy enhancing technologies like Federated Learning and Multi-Party Computation. The vantage6 server has no restrictions on CORS settings. It should be possible for people to set the allowed origins of the server. The impact is limited because v6 does not use session cookies. This issue has been addressed in commit 70bb4e1d8 and is expected to ship in subsequent releases. Users are advised to upgrade as soon as a new release is available. There are no known workarounds for this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
vantage6PyPI
< 4.3.04.3.0

Affected products

1

Patches

1
70bb4e1d8892

Merge pull request from GHSA-4946-85pr-fvxh

https://github.com/vantage6/vantage6Bart van BeusekomMar 7, 2024via ghsa
2 files changed · +59 15
  • docs/server/yaml/server_config.yaml+16 10 modified
    @@ -43,29 +43,28 @@ jwt_secret_key: super-secret-key! # recommended but optional
     
     # Settings for the logger
     logging:
    -
       # Controls the logging output level. Could be one of the following
       # levels: CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET
    -  level:        DEBUG
    +  level: DEBUG
     
       # Filename of the log-file, used by RotatingFileHandler
    -  file:         test.log
    +  file: test.log
     
       # Whether the output is shown in the console or not
    -  use_console:  True
    +  use_console: True
     
       # The number of log files that are kept, used by RotatingFileHandler
       backup_count: 5
     
       # Size in kB of a single log file, used by RotatingFileHandler
    -  max_size:     1024
    +  max_size: 1024
     
       # format: input for logging.Formatter,
    -  format:       "%(asctime)s - %(name)-14s - %(levelname)-8s - %(message)s"
    -  datefmt:      "%Y-%m-%d %H:%M:%S"
    +  format: "%(asctime)s - %(name)-14s - %(levelname)-8s - %(message)s"
    +  datefmt: "%Y-%m-%d %H:%M:%S"
     
    -# (optional) set the individual log levels per logger name, for example
    -# mute some loggers that are too verbose.
    +  # (optional) set the individual log levels per logger name, for example
    +  # mute some loggers that are too verbose.
       loggers:
         - name: urllib3
           level: warning
    @@ -82,7 +81,6 @@ logging:
     
     # Additional debug flags
     debug:
    -
       # Set to `true` to enable debug mode for the socketio server
       socketio: false
     
    @@ -171,3 +169,11 @@ password_policy:
       # number of minutes to wait between emails that alert a user that someone is
       # trying to log in to their account. Default is 60.
       between_email_blocked_login_minutes: 60
    +
    +# set up with which origins the server should allow CORS requests. The default
    +# is to allow all origins. If you want to restrict this, you can specify a list
    +# of origins here. Below are examples to allow requests from the Cotopaxi UI, and
    +#  port 3456 on localhost
    +cors_allowed_origins:
    +  - https://portal.cotopaxi.vantage6.ai
    +  - http://localhost:3456
    
  • vantage6-server/vantage6/server/__init__.py+43 5 modified
    @@ -5,6 +5,7 @@
     through the API the server hosts. Finally, it also communicates with
     authenticated nodes and users via the socketIO server that is run here.
     """
    +
     # -*- coding: utf-8 -*-
     import os
     from gevent import monkey
    @@ -35,6 +36,7 @@
         Response,
     )
     from flask_cors import CORS
    +from flask_cors.core import probably_regex
     from flask_jwt_extended import JWTManager
     from flask_marshmallow import Marshmallow
     from flask_restful import Api
    @@ -108,8 +110,14 @@ def __init__(self, ctx: ServerContext) -> None:
             # Setup Principal, granular API access manegement
             self.principal = Principal(self.app, use_sessions=False)
     
    -        # Enable cross-origin resource sharing
    -        self.cors = CORS(self.app)
    +        # Enable cross-origin resource sharing. Note that Flask-CORS interprets
    +        # the origins as regular expressions.
    +        cors_allowed_origins = self.ctx.config.get("cors_allowed_origins", "*")
    +        self._warn_if_cors_regex(cors_allowed_origins)
    +        self.cors = CORS(
    +            self.app,
    +            resources={r"/*": {"origins": cors_allowed_origins}},
    +        )
     
             # SWAGGER documentation
             self.swagger = Swagger(self.app, template=swagger_template)
    @@ -138,6 +146,35 @@ def __init__(self, ctx: ServerContext) -> None:
     
             log.info("Initialization done")
     
    +    @staticmethod
    +    def _warn_if_cors_regex(origins: str | list[str]) -> None:
    +        """
    +        Give a warning if CORS origins are regular expressions. This will not work
    +        properly for socket events (Flask-SocketIO checks for string equality and does
    +        not use regex).
    +
    +        Note that we are using the `probably_regex` function from Flask-CORS to check
    +        if the origins are probably regular expressions - the Flask implementation for
    +        determining if it is a regex is a bit hacky (see
    +        https://github.com/corydolphin/flask-cors/blob/3.0.10/flask_cors/core.py#L275-L285)
    +        and Flask-CORS doesn't currently offer an opt out of regex's altogether.
    +
    +        Parameters
    +        ----------
    +        origins: str | list[str]
    +            The origins to check
    +        """
    +        if isinstance(origins, str):
    +            origins = [origins]
    +
    +        for origin in origins:
    +            if probably_regex(origin):
    +                log.warning(
    +                    "CORS origin '%s' is a regular expression. Socket events sent from "
    +                    "this origin will not be handled properly.",
    +                    origin,
    +                )
    +
         def setup_socket_connection(self) -> SocketIO:
             """
             Setup a socket connection. If a message queue is defined, connect the
    @@ -149,21 +186,22 @@ def setup_socket_connection(self) -> SocketIO:
             SocketIO
                 SocketIO object
             """
    -
             msg_queue = self.ctx.config.get("rabbitmq", {}).get("uri")
             if msg_queue:
                 log.debug(f"Connecting to msg queue: {msg_queue}")
     
             debug_mode = self.debug.get("socketio", False)
             if debug_mode:
                 log.debug("SocketIO debug mode enabled")
    +
    +        cors_settings = self.ctx.config.get("cors_allowed_origins", "*")
             try:
                 socketio = SocketIO(
                     self.app,
                     async_mode="gevent_uwsgi",
                     message_queue=msg_queue,
                     ping_timeout=60,
    -                cors_allowed_origins="*",
    +                cors_allowed_origins=cors_settings,
                     logger=debug_mode,
                     engineio_logger=debug_mode,
                 )
    @@ -179,7 +217,7 @@ def setup_socket_connection(self) -> SocketIO:
                     self.app,
                     message_queue=msg_queue,
                     ping_timeout=60,
    -                cors_allowed_origins="*",
    +                cors_allowed_origins=cors_settings,
                     logger=debug_mode,
                     engineio_logger=debug_mode,
                 )
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.