Server Insecure Transport

ID

python.server_insecure_transport

Severity

high

Resource

Information Leak

Language

Python

Tags

CWE:319, NIST.SP.800-53, OWASP:2021:A4, PCI-DSS:6.5.4

Description

A web server is started without SSL/TLS support, which means that the server is not authenticated with the client, traffic is not encrypted, and data can be changed on transit.

Rationale

SSL/TLS (Secure Sockets Layer/Transport Layer Security) is crucial for securing online communications by encrypting data between a client’s browser and a server. This encryption ensures that sensitive information, such as passwords and credit card numbers, cannot be intercepted or read by unauthorized parties during transmission.

SSL/TLS also verifies the identity of websites, building trust with users and enhancing the credibility of online services. Furthermore, search engines like Google favor HTTPS-enabled sites in their rankings.

Without properly configuring SSL/TLS, a server is vulnerable to several risks:

  • Data Interception: Sensitive data can be easily intercepted and read by hackers, leading to identity theft and financial fraud.

  • Man-in-the-Middle Attacks: Threat actors can modify data during transmission, potentially injecting malware or altering transaction details.

  • SEO Penalties: Search engines may penalize non-HTTPS sites by ranking them lower, reducing visibility and traffic.

  • User Trust Issues: Users may be warned by browsers that the site is not secure, leading to a loss of trust and potential abandonment of the site.

The following example shows a basic Flask server running over HTTP:

from flask import Flask

app = Flask(__name__)

if __name__ == '__main__':
    app.run()       # FLAW

For FastAPI, an unsafe example would look like this:

import uvicorn
from fastapi import FastAPI

app = FastAPI()


if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000) # FLAW

Remediation

To fix the security issue, you can configure the server to use HTTPS by obtaining an SSL/TLS certificate and key. The certificate should be signed by a well-known and trusted certificate authority (CA).

Care must be taken to ensure that the private key is protected from unauthorized access and properly accessed when starting the server. The private key is usually encrypted and the password or key used to decrypt it should be protected from unauthorized access.

The following example shows a basic Flask server running over HTTPS:

from flask import Flask

from OpenSSL import SSL
context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file('server.key')
context.use_certificate_file('server.crt')

app = Flask(__name__)

if __name__ == '__main__':
    app.run(host='127.0.0.1', debug=True, ssl_context=context)

For FastAPI, an safe example would look like this:

import ssl
import uvicorn
from fastapi import FastAPI

app = FastAPI()

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain('/path/to/cert.pem', keyfile='/path/to/key.pem')

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, ssl=ssl_context)

References