Escaping MYSQL command lines via Bash Scripting

后端 未结 8 942
走了就别回头了
走了就别回头了 2020-12-06 01:09

PHP has mysql_real_escape_string() to correctly escape any characters that might cause problems. What is the best way to mimic this functionality for BASH?

相关标签:
8条回答
  • 2020-12-06 01:33

    This seems like a classic case of using the wrong tool for the job.

    You've got a lot of work ahead of you to implement the escaping done by mysql_real_escape_string() in bash. Note that mysql_real_escape_string() actually delegates the escaping to the MySQL library which takes into account the connection and database character sets. It's called "real" because its predecessor mysql_escape_string() did not take the character set into consideration, and could be tricked into injecting SQL.

    I'd suggest using a scripting language that has a MySQL library, such as Ruby, Python, or PHP.

    If you insist on bash, then use the MySQL Prepared Statements syntax.

    0 讨论(0)
  • 2020-12-06 01:36

    This will escape apostrophes

    a=$(echo "$1" | sed s/"'"/"\\\'"/g)
    

    Please note though that mysql_real_escape_string also escapes \x00, \n, \r, \, " and \x1a. Be sure to escape these for full security.

    To escape \x00 for example:

    a=$(echo "$1" | sed s/"\x00"/"\\\'"/g)
    

    With a bit of effort you can probably escape these using one sed command.

    0 讨论(0)
  • 2020-12-06 01:36

    Sure, why not just use the real thing?

    A script, anywhere, such as
    ~/scripts/mysqli_real_escape.php

    #!/bin/php
    <?php
    
    $std_input_data = '';
    $mysqli             = new mysqli('localhost', 'username', 'pass', 'database_name');
    
    if( ftell(STDIN) !== false  )       $std_input_data = stream_get_contents(STDIN);
    if( empty($std_input_data)  )       exit('No input piped in');
    if( mysqli_connect_errno( ) )       exit('Could not connect to database');
    
    fwrite  (   STDOUT, 
                $mysqli->real_escape_string($std_input_data) 
            );
    
    exit(0);
    
    ?>
    

    Next, run from bash terminal:

    chmod +x ~/script/mysqli_real_escape.php`
    ln -s ~/script/mysqli_real_escape.php /usr/bin/mysqli_real_escape
    

    All set! Now you can use mysqli_real_escape in your bash scripts!

    #!/bin/bash
    MyString="stringW@#)*special characters"
    MyString="$(printf "$MyString" | mysqli_real_escape )"
    

    Note: From what I understand, command substitution using "$(cmd ..."$var")" is preferred over using backticks. However, as no further nesting would be needed either should be fine.

    Further Note: When inside command substitution, "$(...)", a new quote context is created. This is why the quotes around variables do not screw up the string.

    0 讨论(0)
  • 2020-12-06 01:42

    This is how I did it, where my-file.txt contains spaces, new lines and quotes:

    IFS='' content=$(cat my-file.txt)
    mysql <flags> -e "update table set column = $(echo ${content@Q} | cut -c 2-) where something = 123"
    
    0 讨论(0)
  • 2020-12-06 01:44

    mysql_real_escape_string() of course only escapes a single string literal to be quoted, not a whole statement. You need to be clear what purpose the string will be used for in the statement. According to the MySQL manual section on string literals, for inserting into a string field you only need to escape single and double quotation marks, backslashes and NULs. However, a bash string cannot contain a NUL, so the following should suffice:

    #escape for MySQL single string
    PASSWORD=${PASSWORD//\\/\\\\}
    PASSWORD=${PASSWORD//\'/\\\'}
    PASSWORD=${PASSWORD//\"/\\\"}
    

    If you will be using the string after a LIKE, you will also probably want to escape % and _.

    Prepared statements are another possibility. And make sure you don't use echo -e in your bash.

    See also https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

    0 讨论(0)
  • 2020-12-06 01:48

    This will work:

    echo "John O'hara"  | php -R 'echo addslashes($argn);'
    

    To pass it to a variable:

    name=$(echo "John O'hara"  | php -R 'echo addslashes($argn);')
    
    0 讨论(0)
提交回复
热议问题