WeakCipher Validator¶
Checks that the connection negotiated a cipher suite on your allow-list. The built-in allow-list contains modern AEAD suites for TLS 1.2 plus three TLS 1.3 suites, so legacy or weak ciphers (RC4, 3DES, CBC-mode, anything with MD5) fail.
Opt-in
Enable via enabled_validators=["weak_cipher", ...] or ENABLED_VALIDATORS.
Try it¶
from certmonitor import CertMonitor
with CertMonitor("example.com", enabled_validators=["weak_cipher"]) as monitor:
monitor.get_cert_info()
print(monitor.validate()["weak_cipher"])
A strong negotiated suite passes:
These examples show selected fields from illustrative scans. validate() also adds status and code, described in the result contract.
A suite outside the allow-list fails with a reason:
{
"is_valid": false,
"cipher_suite": "RC4-MD5",
"reason": "Cipher suite RC4-MD5 is not allowed. Please update your allowed cipher suites or negotiate a supported cipher."
}
Customizing the allow-list¶
The built-in set is a library policy, not a live feed of external recommendations. Override it per call with the allowed_cipher_suites argument, passed through validator_args:
from certmonitor import CertMonitor
with CertMonitor("example.com", enabled_validators=["weak_cipher"]) as monitor:
monitor.get_cert_info()
result = monitor.validate(
validator_args={
"weak_cipher": {
"allowed_cipher_suites": ["TLS_AES_256_GCM_SHA384", "ECDHE-RSA-AES256-GCM-SHA384"]
}
}
)
print(result["weak_cipher"])
TLS 1.2 and TLS 1.3 name suites differently
TLS 1.2 uses OpenSSL-style names (ECDHE-RSA-AES256-GCM-SHA384); TLS 1.3 uses IANA names (TLS_AES_256_GCM_SHA384). The default allow-list includes both families, so TLS 1.3 connections (the modern default) pass on their standard suites. If you supply a custom set, remember to include the TLS 1.3 names you expect to see.
This checks the connection CertMonitor negotiated. It does not enumerate every protocol or cipher the server would accept from a different client.
Reference¶
certmonitor.validators.weak_cipher.WeakCipherValidator ¶
Bases: BaseCipherValidator
Validates that the negotiated cipher suite is in the allowed list.
The built-in allowed set contains modern AEAD suites. It is a library
policy, not a live feed of external recommendations.
Override it per call with the allowed_cipher_suites argument.
validate ¶
validate(cipher_info: dict[str, Any], host: str, port: int, *, allowed_cipher_suites: list[str] | None = None) -> WeakCipherResult
Validates that the negotiated cipher suite is in the allowed list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cipher_info
|
dict
|
The cipher information. |
required |
host
|
str
|
The hostname. |
required |
port
|
int
|
The port number. |
required |
allowed_cipher_suites
|
list
|
Override the default
allowed cipher suites. When |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
WeakCipherResult
|
A dictionary containing the validation results, including whether the cipher suite is allowed. |
Examples:
Example output (success): This example shows a connection using a strong cipher suite, so validation passes.
```json
{
"is_valid": true,
"cipher_suite": "ECDHE-RSA-AES128-GCM-SHA256"
}
```
Example output (failure): This example shows a connection using a weak cipher suite, so validation fails.
```json
{
"is_valid": false,
"cipher_suite": "TLS_RSA_WITH_RC4_128_MD5",
"reason": "Cipher suite TLS_RSA_WITH_RC4_128_MD5 is not allowed. Please update your allowed cipher suites or negotiate a supported cipher."
}
```