Lignes directrices

Injection de commande

Pour l'instant, nous allons nous intéresser à l'injection de commande en tant que telle. Nous allons surtout nous concentrer sur quelques exemples différents pour qu'il soit plus facile de voir à quoi cela ressemble en action. Pour rappel, les vulnérabilités liées à l'injection de commandes se produisent lorsque l'utilisateur utilise une partie d'une commande du système d'exploitation, comme la fonction suivante :

let ip = request.params.ipAddress ;

system("ping " + ip) ;

Si un utilisateur fournit l'adresse IP, nous utiliserons `8.8.8.8` comme exemple, la commande qui sera exécutée sera `ping 8.8.8.8`, ce qui fait exactement ce à quoi on s'attendrait. Cependant, si l'utilisateur fournit `8.8.8.8 && ls /etc/`, cette commande ne fera pas que pinger l'IP 8.8.8.8, mais elle exécutera aussi `ls` sur le dossier `/etc/. 

Atténuation

Compte tenu de la gravité d'une attaque par injection de commande, vous devez d'abord vous poser certaines questions importantes lorsque vous travaillez avec des commandes système :

  • Avez-vous vraiment besoin d'invoquer cette commande ? La meilleure défense est de ne jamais invoquer les commandes du système
  • Existe-t-il des bibliothèques ou des liens qui vous permettent d'obtenir le même effet sans utiliser de commande système ?
  • Pouvez-vous transmettre des données au processus par l'intermédiaire de Standard In, au lieu de la commande elle-même ? 

Si cela n'est pas possible, le paramétrage est important.

Exemples

Voici quelques exemples dans différentes langues pour vous aider à comprendre comment cela se passe dans la pratique. 

Sans l'utilisation de la paramétrisation, il est vulnérable à l'injection de commande.

string folder = "/tmp/ && ifconfig" ;
string cmd = "\"ls " + folder + "\"" ;

// INSECURE : Exécute à la fois la commande `ls` et `ifconfig`
System.Diagnostics.Process.Start("bash", "-c " + cmd) ;

C# - sécurisé

En fournissant la commande sous la forme d'une liste de paramètres, la commande est paramétrée et protégée contre l'injection de commande.

string folder = "/tmp/ && ifconfig";
List<string> arguments = new List<string>() {"-c", "ls", folder}; 

// SECURE: Does not execute ifconfig command
System.Diagnostics.Process.Start("bash", arguments);

Java - Insécurisé

Sans l'utilisation de la paramétrisation, il est vulnérable à l'injection de commande.

String folder = "/tmp/ && ifconfig" ;

// INSECURE : Exécute à la fois la commande `ls` et `ifconfig`
ProcessBuilder b = new ProcessBuilder("bash -c ls " + folder) ;

Process p = pb.start() ;

Java - Sécurisé

En fournissant la commande sous la forme d'une liste de paramètres, la commande est paramétrée et protégée contre l'injection de commande.

String folder = "/tmp/ && ifconfig" ;

// SECURE : N'exécute pas la commande ifconfig
ProcessBuilder b = new ProcessBuilder("bash", "-c", "ls", folder) ;

Process p = pb.start() ;

Javascript - Insecure

Sans l'utilisation de la paramétrisation, il est vulnérable à l'injection de commande.

const { exec } = require("child_process");

const folder = "/tmp/ && ifconfig";

// INSECURE: Executes both the `ls` and `ifconfig` command 
const ls = exec("bash -c ls " + folder, (error, stdout, stderr) => {
     console.log(`stdout: ${stdout}`);
});

Javascript - Sécurisé

const { spawn } = require("child_process");

const folder = "/tmp/ && ifconfig";

// SECURE: Does not execute ifconfig command
const ls = spawn("bash", ["-c", "ls", folder]);

ls.stdout.on("data", data => {
    console.log(`stdout: ${data}`);
});

Python - Insécurisé

En l'absence de paramétrage, ce système est vulnérable à l'injection de commande.‍

import subprocess

folder = "/tmp/ && ifconfig"

# INSECURE : Exécute à la fois la commande `ls` et `ifconfig`
subprocess.run("bash -c ls " + folder, shell=True)

Python - Sécurisé

En fournissant la commande sous forme de liste de paramètres, la commande est paramétrée et protégée contre l'injection de commande.

import subprocess

folder = "/tmp/ && ifconfig"

# SECURE : N'exécute pas la commande ifconfig
subprocess.run(["bash", "-c", "ls", folder])