Bash script to replace string in database

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












How secure is my script?



#!/usr/bin/env bash

echo "Input database name"
read databaseName
echo "The database name is set to $databaseName"

echo "Input database host"
read databaseHost
echo "The database host is set to $databaseHost"

echo "Input database user"
read user
echo "The database user is set to $user"

stty -echo
echo "Input database user password"
read password
stty echo

echo "Input url to search for"
read searchUrl
echo "The search url is set to $searchUrl"

echo "Input url to replace with the searched url"
read replaceUrl
echo "The replace url is set to $replaceUrl"

mysql --user="$user" --password="$password" --host="$databaseHost" --database="$databaseName" -e "UPDATE messages SET message = REPLACE(message, '$searchUrl', '$replaceUrl')"


Is it bad practise to get the user his password like this? Or is there anything I can improve?







share|improve this question



























    up vote
    4
    down vote

    favorite












    How secure is my script?



    #!/usr/bin/env bash

    echo "Input database name"
    read databaseName
    echo "The database name is set to $databaseName"

    echo "Input database host"
    read databaseHost
    echo "The database host is set to $databaseHost"

    echo "Input database user"
    read user
    echo "The database user is set to $user"

    stty -echo
    echo "Input database user password"
    read password
    stty echo

    echo "Input url to search for"
    read searchUrl
    echo "The search url is set to $searchUrl"

    echo "Input url to replace with the searched url"
    read replaceUrl
    echo "The replace url is set to $replaceUrl"

    mysql --user="$user" --password="$password" --host="$databaseHost" --database="$databaseName" -e "UPDATE messages SET message = REPLACE(message, '$searchUrl', '$replaceUrl')"


    Is it bad practise to get the user his password like this? Or is there anything I can improve?







    share|improve this question























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      How secure is my script?



      #!/usr/bin/env bash

      echo "Input database name"
      read databaseName
      echo "The database name is set to $databaseName"

      echo "Input database host"
      read databaseHost
      echo "The database host is set to $databaseHost"

      echo "Input database user"
      read user
      echo "The database user is set to $user"

      stty -echo
      echo "Input database user password"
      read password
      stty echo

      echo "Input url to search for"
      read searchUrl
      echo "The search url is set to $searchUrl"

      echo "Input url to replace with the searched url"
      read replaceUrl
      echo "The replace url is set to $replaceUrl"

      mysql --user="$user" --password="$password" --host="$databaseHost" --database="$databaseName" -e "UPDATE messages SET message = REPLACE(message, '$searchUrl', '$replaceUrl')"


      Is it bad practise to get the user his password like this? Or is there anything I can improve?







      share|improve this question













      How secure is my script?



      #!/usr/bin/env bash

      echo "Input database name"
      read databaseName
      echo "The database name is set to $databaseName"

      echo "Input database host"
      read databaseHost
      echo "The database host is set to $databaseHost"

      echo "Input database user"
      read user
      echo "The database user is set to $user"

      stty -echo
      echo "Input database user password"
      read password
      stty echo

      echo "Input url to search for"
      read searchUrl
      echo "The search url is set to $searchUrl"

      echo "Input url to replace with the searched url"
      read replaceUrl
      echo "The replace url is set to $replaceUrl"

      mysql --user="$user" --password="$password" --host="$databaseHost" --database="$databaseName" -e "UPDATE messages SET message = REPLACE(message, '$searchUrl', '$replaceUrl')"


      Is it bad practise to get the user his password like this? Or is there anything I can improve?









      share|improve this question












      share|improve this question




      share|improve this question








      edited Apr 16 at 16:37









      200_success

      123k14142399




      123k14142399









      asked Apr 16 at 9:27









      Frank Groot

      1214




      1214




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          6
          down vote













          You can make Bash's read built emit a prompt by using its -p option:



          read -p "Database name: " databaseName


          and you can make it turn off echoing with -s:



          read -s -p "Database password for $user: " password


          Avoid writing "$password" into the mysql command line like that - as the man page says:




          Specifying a password on the command line should be considered insecure. See Section 6.1.2.1, “End-User Guidelines for Password Security”. You can use an option file to avoid giving the password on the command line.




          It also says




          If you omit the password value following the --password or -p option on the command line, mysql prompts for one.




          So I'd recommend not reading the password in this script, but passing --password to tell mysql to do its own prompting.



          The other thing that's dangerous is using user input to construct the SQL query string - even if your users are trusted (and you know they have permission to connect and execute this command), it's worth validating the strings to prevent accidents. An alternative could be to use Bash to quote the arguments:



          command=$(printf 'UPDATE messages SET message = REPLACE(message, %q, %q') 
          "$searchUrl", "$replaceUrl")

          mysql --user="$user" --password
          --host="$databaseHost" --database="$databaseName"
          -e "$command"


          It may be worth writing the script in a different language (or passing these variables to a sub-script in the different language), to enable the use of prepared statements. I thought there might be a way to define variables for the mysql command like you can for Awk, and then use them in statements, but I couldn't find any provision for that, unfortunately.



          An enhancement I would make is to ask for confirmation after reading all the interactive inputs. Right now, if I make a mistake in replaceUrl (e.g. I manage to press and Enter together), then I don't get a chance to interrupt the update. At the very least sleep 2 && mysql so I can Control+C before it's too late.






          share|improve this answer























          • I've tried to use the -p and -s flags but they give me an error :s That's why I didn't make use of it..
            – Frank Groot
            Apr 16 at 13:58






          • 1




            @TobySpeight You’re right about SQL Injection. I know all about Bobby Tables. My error was to forget that -e executes everything in site, so, while the UPDATE statement was save, the EXECUTE was not. I’m beginning to think that it’s not possible using a BASH script. I have deleted my answer. Thanks.
            – Manngo
            Apr 16 at 23:59











          • @TobySpeight GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
            – Frank Groot
            Apr 17 at 8:21










          • read -p 'Foo: ' -s foo works for me with GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu), so I don't understand why it doesn't for you.
            – Toby Speight
            Apr 17 at 9:43










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192180%2fbash-script-to-replace-string-in-database%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          6
          down vote













          You can make Bash's read built emit a prompt by using its -p option:



          read -p "Database name: " databaseName


          and you can make it turn off echoing with -s:



          read -s -p "Database password for $user: " password


          Avoid writing "$password" into the mysql command line like that - as the man page says:




          Specifying a password on the command line should be considered insecure. See Section 6.1.2.1, “End-User Guidelines for Password Security”. You can use an option file to avoid giving the password on the command line.




          It also says




          If you omit the password value following the --password or -p option on the command line, mysql prompts for one.




          So I'd recommend not reading the password in this script, but passing --password to tell mysql to do its own prompting.



          The other thing that's dangerous is using user input to construct the SQL query string - even if your users are trusted (and you know they have permission to connect and execute this command), it's worth validating the strings to prevent accidents. An alternative could be to use Bash to quote the arguments:



          command=$(printf 'UPDATE messages SET message = REPLACE(message, %q, %q') 
          "$searchUrl", "$replaceUrl")

          mysql --user="$user" --password
          --host="$databaseHost" --database="$databaseName"
          -e "$command"


          It may be worth writing the script in a different language (or passing these variables to a sub-script in the different language), to enable the use of prepared statements. I thought there might be a way to define variables for the mysql command like you can for Awk, and then use them in statements, but I couldn't find any provision for that, unfortunately.



          An enhancement I would make is to ask for confirmation after reading all the interactive inputs. Right now, if I make a mistake in replaceUrl (e.g. I manage to press and Enter together), then I don't get a chance to interrupt the update. At the very least sleep 2 && mysql so I can Control+C before it's too late.






          share|improve this answer























          • I've tried to use the -p and -s flags but they give me an error :s That's why I didn't make use of it..
            – Frank Groot
            Apr 16 at 13:58






          • 1




            @TobySpeight You’re right about SQL Injection. I know all about Bobby Tables. My error was to forget that -e executes everything in site, so, while the UPDATE statement was save, the EXECUTE was not. I’m beginning to think that it’s not possible using a BASH script. I have deleted my answer. Thanks.
            – Manngo
            Apr 16 at 23:59











          • @TobySpeight GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
            – Frank Groot
            Apr 17 at 8:21










          • read -p 'Foo: ' -s foo works for me with GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu), so I don't understand why it doesn't for you.
            – Toby Speight
            Apr 17 at 9:43














          up vote
          6
          down vote













          You can make Bash's read built emit a prompt by using its -p option:



          read -p "Database name: " databaseName


          and you can make it turn off echoing with -s:



          read -s -p "Database password for $user: " password


          Avoid writing "$password" into the mysql command line like that - as the man page says:




          Specifying a password on the command line should be considered insecure. See Section 6.1.2.1, “End-User Guidelines for Password Security”. You can use an option file to avoid giving the password on the command line.




          It also says




          If you omit the password value following the --password or -p option on the command line, mysql prompts for one.




          So I'd recommend not reading the password in this script, but passing --password to tell mysql to do its own prompting.



          The other thing that's dangerous is using user input to construct the SQL query string - even if your users are trusted (and you know they have permission to connect and execute this command), it's worth validating the strings to prevent accidents. An alternative could be to use Bash to quote the arguments:



          command=$(printf 'UPDATE messages SET message = REPLACE(message, %q, %q') 
          "$searchUrl", "$replaceUrl")

          mysql --user="$user" --password
          --host="$databaseHost" --database="$databaseName"
          -e "$command"


          It may be worth writing the script in a different language (or passing these variables to a sub-script in the different language), to enable the use of prepared statements. I thought there might be a way to define variables for the mysql command like you can for Awk, and then use them in statements, but I couldn't find any provision for that, unfortunately.



          An enhancement I would make is to ask for confirmation after reading all the interactive inputs. Right now, if I make a mistake in replaceUrl (e.g. I manage to press and Enter together), then I don't get a chance to interrupt the update. At the very least sleep 2 && mysql so I can Control+C before it's too late.






          share|improve this answer























          • I've tried to use the -p and -s flags but they give me an error :s That's why I didn't make use of it..
            – Frank Groot
            Apr 16 at 13:58






          • 1




            @TobySpeight You’re right about SQL Injection. I know all about Bobby Tables. My error was to forget that -e executes everything in site, so, while the UPDATE statement was save, the EXECUTE was not. I’m beginning to think that it’s not possible using a BASH script. I have deleted my answer. Thanks.
            – Manngo
            Apr 16 at 23:59











          • @TobySpeight GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
            – Frank Groot
            Apr 17 at 8:21










          • read -p 'Foo: ' -s foo works for me with GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu), so I don't understand why it doesn't for you.
            – Toby Speight
            Apr 17 at 9:43












          up vote
          6
          down vote










          up vote
          6
          down vote









          You can make Bash's read built emit a prompt by using its -p option:



          read -p "Database name: " databaseName


          and you can make it turn off echoing with -s:



          read -s -p "Database password for $user: " password


          Avoid writing "$password" into the mysql command line like that - as the man page says:




          Specifying a password on the command line should be considered insecure. See Section 6.1.2.1, “End-User Guidelines for Password Security”. You can use an option file to avoid giving the password on the command line.




          It also says




          If you omit the password value following the --password or -p option on the command line, mysql prompts for one.




          So I'd recommend not reading the password in this script, but passing --password to tell mysql to do its own prompting.



          The other thing that's dangerous is using user input to construct the SQL query string - even if your users are trusted (and you know they have permission to connect and execute this command), it's worth validating the strings to prevent accidents. An alternative could be to use Bash to quote the arguments:



          command=$(printf 'UPDATE messages SET message = REPLACE(message, %q, %q') 
          "$searchUrl", "$replaceUrl")

          mysql --user="$user" --password
          --host="$databaseHost" --database="$databaseName"
          -e "$command"


          It may be worth writing the script in a different language (or passing these variables to a sub-script in the different language), to enable the use of prepared statements. I thought there might be a way to define variables for the mysql command like you can for Awk, and then use them in statements, but I couldn't find any provision for that, unfortunately.



          An enhancement I would make is to ask for confirmation after reading all the interactive inputs. Right now, if I make a mistake in replaceUrl (e.g. I manage to press and Enter together), then I don't get a chance to interrupt the update. At the very least sleep 2 && mysql so I can Control+C before it's too late.






          share|improve this answer















          You can make Bash's read built emit a prompt by using its -p option:



          read -p "Database name: " databaseName


          and you can make it turn off echoing with -s:



          read -s -p "Database password for $user: " password


          Avoid writing "$password" into the mysql command line like that - as the man page says:




          Specifying a password on the command line should be considered insecure. See Section 6.1.2.1, “End-User Guidelines for Password Security”. You can use an option file to avoid giving the password on the command line.




          It also says




          If you omit the password value following the --password or -p option on the command line, mysql prompts for one.




          So I'd recommend not reading the password in this script, but passing --password to tell mysql to do its own prompting.



          The other thing that's dangerous is using user input to construct the SQL query string - even if your users are trusted (and you know they have permission to connect and execute this command), it's worth validating the strings to prevent accidents. An alternative could be to use Bash to quote the arguments:



          command=$(printf 'UPDATE messages SET message = REPLACE(message, %q, %q') 
          "$searchUrl", "$replaceUrl")

          mysql --user="$user" --password
          --host="$databaseHost" --database="$databaseName"
          -e "$command"


          It may be worth writing the script in a different language (or passing these variables to a sub-script in the different language), to enable the use of prepared statements. I thought there might be a way to define variables for the mysql command like you can for Awk, and then use them in statements, but I couldn't find any provision for that, unfortunately.



          An enhancement I would make is to ask for confirmation after reading all the interactive inputs. Right now, if I make a mistake in replaceUrl (e.g. I manage to press and Enter together), then I don't get a chance to interrupt the update. At the very least sleep 2 && mysql so I can Control+C before it's too late.







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Apr 16 at 17:00


























          answered Apr 16 at 10:55









          Toby Speight

          17.5k13489




          17.5k13489











          • I've tried to use the -p and -s flags but they give me an error :s That's why I didn't make use of it..
            – Frank Groot
            Apr 16 at 13:58






          • 1




            @TobySpeight You’re right about SQL Injection. I know all about Bobby Tables. My error was to forget that -e executes everything in site, so, while the UPDATE statement was save, the EXECUTE was not. I’m beginning to think that it’s not possible using a BASH script. I have deleted my answer. Thanks.
            – Manngo
            Apr 16 at 23:59











          • @TobySpeight GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
            – Frank Groot
            Apr 17 at 8:21










          • read -p 'Foo: ' -s foo works for me with GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu), so I don't understand why it doesn't for you.
            – Toby Speight
            Apr 17 at 9:43
















          • I've tried to use the -p and -s flags but they give me an error :s That's why I didn't make use of it..
            – Frank Groot
            Apr 16 at 13:58






          • 1




            @TobySpeight You’re right about SQL Injection. I know all about Bobby Tables. My error was to forget that -e executes everything in site, so, while the UPDATE statement was save, the EXECUTE was not. I’m beginning to think that it’s not possible using a BASH script. I have deleted my answer. Thanks.
            – Manngo
            Apr 16 at 23:59











          • @TobySpeight GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
            – Frank Groot
            Apr 17 at 8:21










          • read -p 'Foo: ' -s foo works for me with GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu), so I don't understand why it doesn't for you.
            – Toby Speight
            Apr 17 at 9:43















          I've tried to use the -p and -s flags but they give me an error :s That's why I didn't make use of it..
          – Frank Groot
          Apr 16 at 13:58




          I've tried to use the -p and -s flags but they give me an error :s That's why I didn't make use of it..
          – Frank Groot
          Apr 16 at 13:58




          1




          1




          @TobySpeight You’re right about SQL Injection. I know all about Bobby Tables. My error was to forget that -e executes everything in site, so, while the UPDATE statement was save, the EXECUTE was not. I’m beginning to think that it’s not possible using a BASH script. I have deleted my answer. Thanks.
          – Manngo
          Apr 16 at 23:59





          @TobySpeight You’re right about SQL Injection. I know all about Bobby Tables. My error was to forget that -e executes everything in site, so, while the UPDATE statement was save, the EXECUTE was not. I’m beginning to think that it’s not possible using a BASH script. I have deleted my answer. Thanks.
          – Manngo
          Apr 16 at 23:59













          @TobySpeight GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
          – Frank Groot
          Apr 17 at 8:21




          @TobySpeight GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
          – Frank Groot
          Apr 17 at 8:21












          read -p 'Foo: ' -s foo works for me with GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu), so I don't understand why it doesn't for you.
          – Toby Speight
          Apr 17 at 9:43




          read -p 'Foo: ' -s foo works for me with GNU bash, version 4.2.8(1)-release (i686-pc-linux-gnu), so I don't understand why it doesn't for you.
          – Toby Speight
          Apr 17 at 9:43












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192180%2fbash-script-to-replace-string-in-database%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation