Even the best developers cannot account for all security vulnerabilities. No application is 100% secure, no matter how much you might like it to be. Python applications are no exceptions. You can even find security flaws in the standard library documentation. However, that does not mean you should stop trying to write secure software. Read on to learn key best practices for securing python apps.

1. Upgrade to Python 3

Python 3 was released in 2008, but companies and developers still use Python 2 versions in production.

On January 1, 2020, the Python Software Foundation stopped supporting Python 2. This means they will not fix and update any security issues in Python 2 and related open source libraries. To stay secure, you should upgrade to Python 3 as soon as possible.

For example, the latest Django version is suitable for Python 2. This version will be supported at least until May 2020. However, there will not be any security support after that date. Before transitioning to Python 3, make sure that your legacy codebase is ready for the upgrade. In addition, your dependencies should be suitable for Python 3.

2. Manage Dependencies with Pipenv

Pipenv is a Python packaging tool that solves some typical workflow problems like using virtualenv or pip. In addition, Pipenv simplifies the development process to a single command-line tool.

When working on projects that use third-party packages, like Flask, you need to make sure that the local environment is similar to production. This helps other developers and automated systems run your applications.

A common way of doing it is to use the pip freeze command on your machine, then copy the resulting package list to the requirements.txt file. Then use this file to configure the production environment.

When using pip freeze, you expose your project to new vulnerabilities that you did not know about. Pipenv constantly updates and protects the environment. This tool manages virtual environments and installations, checks for known vulnerabilities in your dependencies, and displays the dependency tree.

3. Import Statements Vulnerabilities

Python import statements are flexible, but that flexibility can result in security issues.

Python imports can be relative or absolute:

  • Absolute imports—use the full path of the imported module. This includes the path of the root directory. An error occurs if the imported module is not found at the specified location. When using absolute imports, you know exactly what module you are importing.
  • Relative imports—include only a partial path of the current module. Relative import types include implicit and explicit imports. An explicit relative import indicates the exact location of the imported module. For instance, _from .. import module_1_.

Implicit imports do not specify the exact location of the module. As a result, Python imports any module that includes the partial path in the system path. Hackers can create malicious modules with names similar to other popular modules, and then include them in any open-source library.

Avoid using implicit relative imports in Python 2. Python 3 does not support implicit relative imports. However, you still have to be careful with import statements in Python 3 since the import statement executes the code inside the module.

4. Verify SSL Certificates

Python usually handles HTTP requests with the requests library. This library uses the Certifi package to validate the integrity of SSL certificate authorities. For this reason, you have to keep the most updated version of Certifi.

Sometimes developers prefer to bypass SSL certificate verification. Make sure to always verify SSL certificates by using the following syntax:

requests.get(https://mywebsite.com, verify=True).

5. Downloading Packages Carefully

Developers usually use pip — the standard package installer for Python — to install packages. Python packages are shared and distributed in the Python Package Index (PyPI). However, sometimes PyPI may include malicious packages.

Before downloading, you should research packages and make sure the name of the package is spelled correctly. Hackers often use misspellings as a technique to trick developers to download malicious packages.

PyPI provides an option to report security concerns in potentially malicious packages. However, PyPI does not proactively review packages. This expectation is not realistic since volunteers maintain PyPI.

6. String Formatting

Python has four various approaches to format strings. The string formatting process is very flexible. However, flexible string formatting syntax like the f-strings can be vulnerable to exploits. This is why Python developers should carefully format user-generated strings.

To overcome this problem, use the Python built-in string module. This string module is based on the template class. You can use this class to create template strings. For example, the following code asks users to enter their name and then display the name on a screen:

The end result will be a string of “Hello, my name is John”. The string module is not as flexible as f-string. As a result, the string module is a good choice for handling user input.

from string import Template
welcome = name_template.substitute(name=John)
name_template = Template(Hello, my name is $name.)

7. Python Object Serialization

The Python pickle module enables you to deserialize and serialize an object structure.

Deserialization is the process of transforming a Python object into a stream of bytes that you can store in a database, or transport over the network. You can then serialize the byte stream to recreate the original object.

Using pickle deserialization can be dangerous since there is no way to verify the stream of bytes. Hackers can exploit this vulnerability to insert malicious code into the stream and then execute the malicious code in the system. The most common use case of this exploit is when attackers access and change byte stream stores in file systems, or databases.

Make sure to use the pickle module only with trusted clients and servers. In addition, always transfer deserialization streams on an encrypted network connection to prevent lateral movement attacks.

Conclusion

Learning a new programming language usually does not involve learning secure coding practices. You just learn how to use the language. Python is no exception, and you can even find bad practices for writing applications in the standard Python library. Many developers are not aware of the security risks in using standard libraries. Make sure to follow the security best practices mentioned above to make your Python applications secure.