OS Command Injection From A Python/Django Perspective

OS Command Injection From A Python/Django Perspective

Welcome to the third article in the series ‘OWASP Top-10 From A Python/Django Perspective’. Please check out my previous two articles on SQL Injection and LDAP Injection if you have not yet. In this article, we will look into OS Command Injection.

What is OS Command Injection?

OS Command Injection is a vulnerability in which malicious data is injected into the application and sent to the Operating System. The OS then executes the malicious command leading to terrible consequences.

This kind of vulnerability may exist in applications which needs to execute OS Commands as part of its functionality. For example, an application that performs Server Monitoring and provides information such as CPU, Memory, Network and Disk utilization would need to execute OS commands on that server to get those results. An application that converts video files to another format would also need to execute commands (e.g. using FFmpeg).

Let’s consider a very simple application that performs a DNS lookup of a domain using the nslookup command. The application prompts for the domain name. When we enter the Domain Name, it returns the output of the DNS lookup containing the IP address. We will be using subprocess to execute the command.

No alt text provided for this image

Let’s run this small program and check the output.

No alt text provided for this image

When we entered rqsolutions.com it returned the associated IP Address as expected.

But, what if we entered rqsolutions.com ; ls -la ??

The command at the backend would be nslookup rqsolutions.com ; ls -la which is a valid UNIX command. Let’s try that as well.

No alt text provided for this image

You can see that the OS executed both nslookup and ls and returned the output.

What if instead of ls -la the command we entered was rm -rf *.* ?? It would delete all the files within the directory and wreak havoc. This is a simple example of OS Command Injection.

How to prevent?

Apart from validating the input, there are two ways to prevent this. The first option is to quote the input using shlex.quote() as shown below.

No alt text provided for this image

This will ensure that the input is quoted and the OS will not consider anything within the input as commands that needs to be executed. The command will now look like:

nslookup ‘rqsolutions.com ; ls -la’

Let’s input the same data and check the result.

No alt text provided for this image

The OS did not execute the command and the program returned an error preventing any malicious activity.

The second option is to split the command into a list of strings using shlex.split().

No alt text provided for this image

When we input the same data as above, the safe_command will look like:

['nslookup', 'rqsolutions.com', ';', 'ls', '-la']

This list of strings is then executed by subprocess. Let’s check the output for the same.

No alt text provided for this image

The OS did not execute the command and the program returned an error preventing any malicious activity.

Please note that the second option of using shlex.split() is recommended as shell=True is omitted in subprocess and is considered more safe. Additionally, avoid using the deprecated os module for executing commands.

How to detect?

OS Command injection can be detected in two ways:

  1. Performing Source Code Security Review
  2. Performing Web Application Vulnerability Scanning

Performing Source Code Security Review:

Source code security review is also known as Static Analysis Security Testing (SAST). Follow the process below:

  • Check if the deprecated os module is used
  • Check if subprocess is used with shell=True
  • If subprocess needs to be used with shell=True, then check if shlex.quote() is used as a prevention control
  • Check if shlex.split() is used as a prevention control

Performing Web Application Vulnerability Scanning

Web Application Vulnerability Scanners can identify OS Command injection vulnerability when the application is up and running. This kind of testing is also known as Dynamic Application Security Testing (DAST).

Good article, would have been nice if you talked about Static Analysis tools for Python. Once can configure tool like: https://github.com/python-security/pyt to run as pre-commit hook. This way every-time you did a "git commit" it would let you know if there are any vulnerability detected in the code.

Like
Reply

To view or add a comment, sign in

More articles by Jerin Jose

  • XXE Attacks In Python / Django Applications

    Hello World, welcome to my next article on XML eXternal Entity (XXE) Attacks In Python/Django Applications. First…

    2 Comments
  • Encryption & Hashing In Django

    Hello World, welcome to my next article in the series ‘OWASP Top 10 From A Django Perspective’. I was out of action for…

    15 Comments
  • Session Hijacking & Fixation In Django

    Hello World, welcome to my next article in the series ‘OWASP Top 10 From A Django Perspective’. In this article we will…

  • Protecting A Django App From Password Guessing Attacks

    Welcome to my fourth article in the series ‘OWASP Top-10 From A Python/Django Perspective’. My previous three articles…

    2 Comments
  • LDAP Injection in Django

    Hello All! Welcome to my second article in a series which I call “OWASP Top 10 From A Django Perspective”. This article…

    2 Comments
  • SQL Injection in Django Applications

    Django is a popular web application framework based on Python. Django’s unique selling point is that applications can…

    6 Comments
  • AWS IAM Security Best Practices

    AWS IAM is a service for centrally managing users and their credentials. Following are some of the security best…

Others also viewed

Explore content categories