One key to interactive software is user inputs and the reaction of the software to it. But however useful, those inputs can be highly dangerous, as they can lead to possible injection attacks. One of the most common and simple injection attacks is SQL injection.
SQL injection is a vulnerability in which an attacker influences the queries that software makes to the database. By inserting a relatively simple command, one can, for example, turn an authorization check into administrative access to a web portal. Some web platforms limit the special characters that can be included in usernames and passwords to prevent the use of those characters in a SQL injection attack. Unfortunately, this makes the creation of strong passwords more difficult. Therefore, it’s best to sanitize the inputs—that is, check every input and create rules defining valid inputs, acceptable character sequences, and which combinations to allow. This helps prevent injection attacks while still allowing strong passwords.
Use prepared statements
To further improve security, make sure your database supports prepared statements. Databases like MySQL, MS SQL Server, and PostgreSQL support this functionality because it can protect against vulnerabilities like SQL injection—and in some cases, it even results in performance improvements in your application, especially if you run SQL statements repeatedly. And in Python, you can use prepared statements even if your database doesn’t support them. Python supports this functionality in its standard libraries and will emulate it on the client side if needed. The biggest security benefit of using prepared statements is the separation of SQL statements and user-provided data. This ensures that user-provided data cannot be abused to modify SQL statements, and will be used literally in the precompiled statement that logic will not change.
Check your spelling
Malicious actors often create misspelled domains to catch people who have misspelled their URL. The same can happen when fetching libraries from PyPI. A malicious package with a name similar to a legitimate one could be placed in a repository to trick someone into fetching it by mistake.
Avoid implicit relative import
In absolute imports, you specify the full path to the package you want to use. In relative imports, you import a package relative to the location of the project where you made the import statement. There are two types of relative imports.
- The explicit relative import requires you to specify the exact path of the module relative to the current module
- The implicit relative import doesn’t specify the resource path at all
The danger of implicit relative imports is that a poisoned package could find its way into another part of your project (via an import of another library) and then could mistakenly be used instead of the library you intended. Due to the unspecified path and the potential for confusion, the implicit relative import was removed from Python 3.x. However, if you are still using older versions of Python, remove the implicit relative imports and use either the absolute or explicit relative import types.