enhancement
major
major
critical
#29784
OpenAPI server: basic authentication of a technical user accepts an empty password when the configured password is empty (e.g. unset environment variable)
Scenario
An application protects an OpenAPI server operation with basic authentication of a technical user. The credentials come from aliases resolved from the environment, as is usual for deployments:
{{{#!xml <entry name="%API_USER%" value="${env:api_user:service}" /> <entry name="%API_PASSWD%" value="${env:api_passwd}" /> }}} {{{#!xml <basic-auth-server-secret domain="Api"> <login user="%API_USER%" password="%API_PASSWD%"/> </basic-auth-server-secret> }}}
In a deployment where api_passwd is not set, the application starts without an error, and the operation accepts requests with user service and an empty password.
Found while reviewing the TopLogic release notes application, whose CMS management API can rewrite the public website. Analysed in the source of tl-engine 8.0.0-alpha9 / master.
Analysis
- DefaultAliasManager.replaceWithEnvironment resolves an unset ${env:...} without a default to the empty string and only logs an info message ("Using empty alias").
- EncodingConfigurationValueProvider.getValue passes an empty value through unchanged; only a non-empty value is decrypted. So LoginCredentials#getPassword() is "". @Mandatory does not reject it, because the property is set.
- BasicTechnicalAuthenticator.authenticateUser accepts a request whenever the sent LoginCredentials (user, password) is contained in the configured set (equality by value). The empty password sent by the client equals the empty configured password.
The silent fallback thus turns a missing secret into an open endpoint.
The API key authentication has the same defect: an api-key-server-secret whose api-key resolves to the empty string accepts a request that sends an empty key (empty header, query parameter or cookie), as technical user or as the account named by user-id.
Expected
A technical user with an empty password is a configuration error:
- The server secret refuses an empty password, so the application fails to start or the operation is disabled with an error in the log.
- At the latest, the authenticator never accepts an empty password.
Lösung
- Basic-Authentifizierung (technischer Benutzer) und API-Key-Authentifizierung des OpenAPI-Servers ignorieren ein Secret mit leerem Passwort bzw. leerem API-Key und schreiben einen Fehler ins Log, der die Domain und den Benutzer bzw. Parameter nennt. Bleibt für die Domain kein gültiges Secret übrig, ist die Operation wie bei einem fehlenden Secret nicht authentifizierbar (Antwort 500, Fehlende-Secret-Meldung). Die Anwendung startet weiterhin.
- Zusätzlich weisen beide Authentifizierungen einen Request mit leerem Passwort bzw. leerem API-Key immer ab, unabhängig von der Konfiguration.
- Der OpenAPI-Client (Zugangsdaten für den Aufruf fremder Dienste) ist nicht betroffen und bleibt unverändert.