2017-01-16 1 views
1

J'ai cette fonction plpgsql:Faire preuve d'injection SQL dans PL/pgSQL

CREATE OR REPLACE function login_v(em varchar, passwd varchar) 
    RETURNS users AS $$ 
DECLARE 
    cu users; 
BEGIN 
    SELECT * into cu 
    FROM users where email = em 
    AND encrypted_password = crypt(passwd, encrypted_password); 

    return cu; 
END 
$$ LANGUAGE plpgsql; 

Quand je fournir une entrée comme ceci: select login_v('[email protected]'' OR 1=1;--','la la la');, je pense que ma méthode doit renvoyer l'utilisateur email [email protected]. Qu'est-ce que je fais mal?

Effectuer une injection SQL est nécessaire ici pour démontrer le concept d'un exercice, mais je suis une injection SQL et un boob plpgsql. : |

Répondre

3

Les requêtes SQL dans PL/pgSQL sont planifiées comme des instructions préparées. Tant que vous ne passez que valeurs comme vous le faites, l'injection SQL est généralement impossible. Détails:

Utiliser SQL dynamique avec EXECUTE et sans paramètre approprié de manipulation pour démontrer effectivement l'injection SQL.

Comme (c'est ainsi pas pour le faire!):

CREATE OR REPLACE FUNCTION login_v(em varchar, passwd varchar) 
    RETURNS SETOF users AS 
$func$ 
BEGIN 
    RETURN QUERY EXECUTE 
     'SELECT * 
     FROM users 
     WHERE email = $1 
     AND encrypted_password = crypt(''' || passwd || ''', encrypted_password)' 
    USING em; 
END 
$func$ LANGUAGE plpgsql; 

La première variable em est bien passé avec la clause USING comme valeur et ne peuvent donc pas être abusé pour Injection SQL.

Mais la deuxième variable passwd est mal concaténée sans s'échapper correctement. Ainsi, l'entrée utilisateur peut être convertie en code SQL. Injection SQL.

Ne l'utilisez jamais! Sauf pour montrer comment ne pas le faire.

Une erreur similaire est possible lors de la concaténation incorrecte de chaînes SQL dans le client.