Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-23929: Merge pull request from GHSA-4w59-c3gc-rrhp · vantage6/vantage6@48ebfca

vantage6 is a privacy preserving federated learning infrastructure for secure insight exchange. Currently, the refresh token is valid indefinitely. The refresh token should get a validity of 24-48 hours. A fix was released in version 3.8.0.

CVE
#auth

@@ -36,13 +36,15 @@ from vantage6.server.permission import RuleNeed, PermissionManager from vantage6.server.globals import ( APPNAME, JWT_ACCESS_TOKEN_EXPIRES, ACCESS_TOKEN_EXPIRES_HOURS, JWT_TEST_ACCESS_TOKEN_EXPIRES, RESOURCES, SUPER_USER_INFO, REFRESH_TOKENS_EXPIRE, REFRESH_TOKENS_EXPIRE_HOURS, DEFAULT_SUPPORT_EMAIL_ADDRESS, MAX_RESPONSE_TIME_PING MAX_RESPONSE_TIME_PING, MIN_TOKEN_VALIDITY_SECONDS, MIN_REFRESH_TOKEN_EXPIRY_DELTA, ) from vantage6.server.resource.common.swagger_templates import swagger_template from vantage6.server._version import __version__ @@ -145,7 +147,7 @@ def setup_socket_connection(self):
@staticmethod def configure_logging(): “""Turn 3rd party loggers off.""” “""Set third party loggers to a warning level""”
# Prevent logging from urllib3 logging.getLogger(“urllib3”).setLevel(logging.WARNING) @@ -165,9 +167,6 @@ def configure_flask(self): # patch where to obtain token self.app.config[‘JWT_AUTH_URL_RULE’] = ‘/api/token’
# False means refresh tokens never expire self.app.config[‘JWT_REFRESH_TOKEN_EXPIRES’] = REFRESH_TOKENS_EXPIRE
# If no secret is set in the config file, one is generated. This # implies that all (even refresh) tokens will be invalidated on restart self.app.config[‘JWT_SECRET_KEY’] = self.ctx.config.get( @@ -176,7 +175,20 @@ def configure_flask(self): )
# Default expiration time self.app.config[‘JWT_ACCESS_TOKEN_EXPIRES’] = JWT_ACCESS_TOKEN_EXPIRES token_expiry_seconds = self._get_jwt_expiration_seconds( config_key=’token_expires_hours’, default_hours=ACCESS_TOKEN_EXPIRES_HOURS ) self.app.config[‘JWT_ACCESS_TOKEN_EXPIRES’] = token_expiry_seconds
# Set refresh token expiration time self.app.config[‘JWT_REFRESH_TOKEN_EXPIRES’] = \ self._get_jwt_expiration_seconds( config_key=’refresh_token_expires_hours’, default_hours=REFRESH_TOKENS_EXPIRE_HOURS, longer_than=token_expiry_seconds + MIN_REFRESH_TOKEN_EXPIRY_DELTA, is_refresh=True )
# Set an extra long expiration time on access tokens for testing # TODO: this does not seem needed… @@ -284,6 +296,64 @@ def static_from_root(): return send_from_directory(self.app.static_folder, request.path[1:])

def _get_jwt_expiration_seconds( self, config_key: str, default_hours: int, longer_than: int = MIN_TOKEN_VALIDITY_SECONDS, is_refresh: bool = False ) -> int: “"” Return the expiration time for JWT tokens. This time may be specified in the config file. If it is not, the default value is returned. Parameters ---------- config_key: str The config key to look for that sets the expiration time default_hours: int The default expiration time in hours longer_than: int The minimum expiration time in hours. is_refresh: bool If True, the expiration time is for a refresh token. If False, it is for an access token. Returns ------- int: The JWT token expiration time in seconds “"” hours_expire = self.ctx.config.get(config_key) if hours_expire is None: # No value is present in the config file, use default refresh_expire = int(float(default_hours) * 3600) elif isinstance(hours_expire, (int, float)) or \ hours_expire.is_numeric(): # Numeric value is present in the config file refresh_expire = int(float(hours_expire) * 3600) if refresh_expire < longer_than: log.warning( f"Invalid value for '{config_key}’: {hours_expire}. Tokens" f" must be valid for at least {longer_than} seconds. Using" f" default value: {REFRESH_TOKENS_EXPIRE_HOURS} hours") if is_refresh: log.warning(“Note that refresh tokens should be valid at " f"least {MIN_REFRESH_TOKEN_EXPIRY_DELTA} " “seconds longer than access tokens.”) refresh_expire = int(float(REFRESH_TOKENS_EXPIRE_HOURS) * 3600) else: # Non-numeric value is present in the config file. Warn and use # default log.warning(“Invalid value for 'refresh_token_expires_hours’:” f” {hours_expire}. Using default value: " f"{REFRESH_TOKENS_EXPIRE_HOURS} hours") refresh_expire = int(float(REFRESH_TOKENS_EXPIRE_HOURS) * 3600)
return refresh_expire

def configure_api(self): “"""Define global API output.""”

Related news

GHSA-4w59-c3gc-rrhp: vantage6 refresh tokens do not expire

From issue: Problem description Currently, the refresh token is valid indefinitely. This is bad security practice. Desired solution The refresh token should get a validity of 24-48 hours. Additional context When implementing this, also check that the refresh token returns a new refresh token When implementing this, also adapt the UI so that it logs out if refresh token is no longer valid. When implementing this, ensure that nodes refresh their token periodically so that they do not have to be restarted manually. ### Impact ### Patches None available ### Workarounds None available

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907