Summary
I'm using keeper-commander behind a corporate firewall that performs SSL inspection. The environment variable KEEPER_SSL_CERT_FILE (used to control CA bundle/verification) is ignored for REST calls performed in rest_api.execute_rest(), causing SSL verification to always follow a boolean flag and resulting in errors like SELF_SIGNED_CERT_IN_CHAIN.
Reproduction
- In your shell: export KEEPER_SSL_CERT_FILE=none
- Run keeper-commander and attempt to login: login
- Expectation: with 'none' the client should disable certificate verification for requests.
Actual: requests.exceptions.SSLError: SELF_SIGNED_CERT_IN_CHAIN
Investigation
Impact
- Users can't disable SSL verification using KEEPER_SSL_CERT_FILE=none
- Users can't point Commander to a company CA bundle via KEEPER_SSL_CERT_FILE
- CLI operations that use execute_rest() (including login) fail under TLS-inspecting proxies/self-signed enterprise CAs
Proposed Fix
Preferred (Option A): Use the helper in utils and delegate verify handling to it.
Replace requests.post(...) in execute_rest() with a call to utils.ssl_aware_request('POST', ...), e.g.:
from . import utils
rs = utils.ssl_aware_request('POST', url, data=request_data, headers={'Content-Type': 'application/octet-stream'}, proxies=context.proxies, timeout=timeout or DEFAULT_TIMEOUT)
Alternative (Option B): Call utils.get_ssl_cert_file() and pass its result as the verify parameter to requests.post, translating False → False, path → path, default → None.
Notes
- context.certificate_check should retain its role for toggling InsecureRequestWarning suppression but should not be passed directly to requests' verify parameter.
- Consider introducing an explicit param (e.g., context.verify_path) or consistently using get_ssl_cert_file() throughout the codebase.
References
Summary
I'm using keeper-commander behind a corporate firewall that performs SSL inspection. The environment variable KEEPER_SSL_CERT_FILE (used to control CA bundle/verification) is ignored for REST calls performed in rest_api.execute_rest(), causing SSL verification to always follow a boolean flag and resulting in errors like SELF_SIGNED_CERT_IN_CHAIN.
Reproduction
Actual: requests.exceptions.SSLError: SELF_SIGNED_CERT_IN_CHAIN
Investigation
utils.get_ssl_cert_file() (keepercommander/utils.py) implements logic for KEEPER_SSL_CERT_FILE:
(see: https://github.com/Keeper-Security/Commander/blob/main/keepercommander/utils.py#L533-L582)
utils.ssl_aware_request() uses get_ssl_cert_file() to set requests' verify kwarg appropriately (False / path / default).
(see: https://github.com/Keeper-Security/Commander/blob/main/keepercommander/utils.py#L585-L599)
However, rest_api.execute_rest() performs requests.post(..., verify=context.certificate_check, ...)
(see: https://github.com/Keeper-Security/Commander/blob/main/keepercommander/rest_api.py#L201-L203)
Impact
Proposed Fix
Preferred (Option A): Use the helper in utils and delegate verify handling to it.
Replace requests.post(...) in execute_rest() with a call to utils.ssl_aware_request('POST', ...), e.g.:
from . import utils
rs = utils.ssl_aware_request('POST', url, data=request_data, headers={'Content-Type': 'application/octet-stream'}, proxies=context.proxies, timeout=timeout or DEFAULT_TIMEOUT)
Alternative (Option B): Call utils.get_ssl_cert_file() and pass its result as the verify parameter to requests.post, translating False → False, path → path, default → None.
Notes
References