Insecure Network Communication
This page currently covers:
Securing TLS configuration
About Insecure TLS Configuration
Insecure SSL/TLS protocol version
This rule detects usages of insecure SSL/TLS protocol versions in the Python SSL Module and pyOpenSSL. Specifically, protocol versions that are not:
- TLSv1.2
- TLSv1.3
- DTLSv1.2
- DTLSv1.3
Several highly publicized and exploitable flaws exist in all versions, except the ones listed above.
Option A: Use a secure TLS protocol version
It is recommended to enforce TLS 1.2 as the minimum protocol version. Avoid downgrading attacks by disabling insecure versions such as SSL 3.0.
Go through the issues that GuardRails identified in the PR/MR.
Replace insecure SSL/TLS protocol versions with TLSv1.2 or TLSv1.3.
context = SSL.Context(SSL.TLS_SERVER_METHOD)
#Insecure example
context.set_min_proto_version(SSL.TLS1_1_VERSION)context = SSL.Context(SSL.TLS_SERVER_METHOD)
#Secure example
context.set_min_proto_version(SSL.TLS1_2_VERSION)Test it
Ship it 🚢 and relax 🌴
Fixing Certificate Validation
About Certificate Validation
Certificate verification disabled (HTTPX)
Not verifying the SSL/TLS certificate can result in attackers intercepting the connection and having full control of the network traffic.
Rule-specific references:
Option A: Enable Certificate Verification (HTTPX)
Enable the certificate verification.
- Replace
verify=False
withverify=True
- Test it
- Ship it 🚢 and relax 🌴
Certificate verification disabled (Requests)
Not verifying the SSL/TLS certificate can result in attackers intercepting the connection and having full control of the network traffic.
Rule-specific references:
Option A: Enable Certificate Verification (Requests)
Go through the issues that GuardRails identified in the PR/MR
Replace the following code sample which has
verify=False
in it:import requests
# this is the vulnerable line
requests.get('https://www.openstack.org/', verify=False)with the following:
import requests
# Ensure that you have a valid certificate.
# get free certificates at https://letsencrypt.org/
requests.get('https://www.openstack.org/', verify=CONF.ca_file)Test it
Ship it 🚢 and relax 🌴
Deprecated SSL Socket Wrapper
The function 'ssl.wrap_socket()' is deprecated since Python 3.7. It creates an insecure SSL socket without server name indication or hostname matching.
Rule-specific references:
Option A: Use SSLContext.wrap_socket()
Since Python 3.2 and 2.7.9, it is recommended to use the SSLContext.wrap_socket()
instead of ssl.wrap_socket()
.
Look for instances of
ssl.wrap_socket()
Replace them with
ssl.SSLContext.wrap_socket()
import ssl
sock = socket.socket(
socket.AF_INET,
socket.SOCK_STREAM | socket.SOCK_NONBLOCK))
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_default_certs()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com')
ssl_sock.connect(('www.verisign.com', 443))Test it
Ship it 🚢 and relax 🌴
Insecure HTTPSConnection version
Rule-specific references:
Option A: Confirm the use of the secure version for HTTPSConnection
The HTTPSConnection API has changed often even in minor Python releases.
Python versions before 2.7.9
and 3.4.3
don't verify SSL certificates by default.
Go through the issues that GuardRails identified in the PR/MR
Verify that HTTPSConnection is used:
# Three possible patterns are:
httplib.HTTPSConnection(...)
http.client.HTTPSConnection(...)
six.moves.http_client .HTTPSConnection(...)Confirm that you are using a Python version greater than
2.7.9
and3.4.3
, otherwise use secure alternatives such ascreate_default_context()
Test it
Ship it 🚢 and relax 🌴
Host key verification disabled (Paramiko SSH)
Using AutoAddPolicy
and WarningPolicy
in set_missing_host_key_policy
would allow malicious actors to intercept communication between the SSH client and the SSH server.
Specific References:
Option A: Use RejectPolicy
Use RejectPolicy
instead of AutoAddPolicy
and WarningPolicy
in set_missing_host_key_policy
function.
Locate the vulnerability:
set_missing_host_key_policy(paramiko.client.AutoAddPolicy)
and/orset_missing_host_key_policy(paramiko.client.WarningPolicy)
.from paramiko import client
ssh_client = client.SSHClient()
ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
ssh_client.connect(hostname=HOST, port=PORT, username=USER)Replace
paramiko.client.AutoAddPolicy
and/orparamiko.client.WarningPolicy
withparamiko.client.RejectPolicy
from paramiko import client
ssh_client = client.SSHClient()
ssh_client.set_missing_host_key_policy(client.RejectPolicy)
ssh_client.connect(hostname=HOST, port=PORT, username=USER)Test it
Ship it 🚢 and relax 🌴
Fixing Cleartext Transmission
About Cleartext Transmission
Plaintext protocols
Plaintext protocols provide no encryption and protection against MITM attacks.
Option A: Don't use insecure protocols
- Go through the issues that GuardRails identified in the PR/MR
- Identify affected lines contain a reference to FTP, or Telnet
- Replace them with secure alternatives such as SSH instead of Telnet
- Test it
- Ship it 🚢 and relax 🌴
Plaintext FTP connection (ftplib)
The File transfer protocol (FTP) does not provide encryption for its communications.
Rule-specific references:
Option A: Use SSH File Transfer Protocol (SFTP)
SSH file transfer protocol (SFTP) runs over SSH, providing the confidentiality and authentication that SSH offers.
- import the
pysftp
module - Use
pysftp.Connection(host, username, password=password)
instead offtplib.FTP(host, username, password).login()
- Refactor the
ftplib
commands to the accordingpysftp
commands. - Test it
- Ship it 🚢 and relax 🌴
Option B: Use of TLS Context
Use of TLS with FTP provides sufficient confidentiality and authentication.
- import the
ssl
module - Replace instances of
ftplib.FTP(host, username, password)
withftplib.FTP_TLS(host, username, password, context=ssl.create_default_context())
- Test it
- Ship it 🚢 and relax 🌴
Plaintext SNMP connection (pysnmp)
The Simple Network Management Protocol (SNMP) may send network traffic in plaintext.
Using it with noAuthNoPriv
and authNoPriv
is insecure.
Rule-specific references:
Option A: Encrypt SNMP traffic
Use SNMP with the right parameters to encrypt the network traffic.
Explicitly set the parameter
authKey
andprivKey
of theUsmUserData
functionsecure = pysnmp.hlapi.UsmUserData(user, authKey=authKey, privKey=privKey)
Test it
Ship it 🚢 and relax 🌴
Insecure SNMP version (pysnmp)
SNMP version v1 and v2c community strings are unencrypted and sent in clear text which is insecure for public and internet-facing devices.
Rule-specific references:
Option A: Do not use version v1 and v2c
Use SNMP v3 instead of v1 and v2c.
- Replace
CommunityData(...)
withUsmUserData(...)
with the appropriate parameters. - Test it
- Ship it 🚢 and relax 🌴