I have a number of Unix Shell scripts that logon to SQLPLUS in a batch environment. In order to logon to SQLPLUS the user and password are currently available to the shell script in plain text from a text file. Not Good ! I need to change this so that the password is protected and possibly encrypted, but the shell script can pick up the password and decrpyt to use. I'm not really sure how I would go about achieving my objectives, other than I presume I need to write some shell script code that can be in a library and pulled into all my shell scripts as required. Any suggestions would be welcome.
Probably not what you want to hear.
Encrypting or otherwise obfuscating the password in your shell script does not provide any real security: only "security by obscurity" which isn't actually secure. This is a good reading about passwords in plaintext.
So in my opinion it would be best, that as less people as possible have access to the shell script.
IMHO best possible solution in this case something like HashiCorp Vault Vault
You are setting up Vault server in secure/audited network/host and store your password there (vault will encrypt it for you). Then you generating vault access token with rights to read db password. With Vault you have http(s) API which will give your secret if you have correct token (curl inside shell script). Examples: api documentation
It is not best solution but with this you centralizing your secrets storage, everything encrypted, you can audit and revoke access to your secrets. This is way better than db passwords in plaintext all over your infrastructure.
Related
Hi I'm using makefile to do lots of compiling and remote works.
In many occasion I would need to type in username and password for remote connection, VPN, code upload and other stuffs.
May it be possible to use makefile to auto type in the credential information?
Thanks a lot!
It is not the role of make to do this kind of thing. So there is no special support in a Makefile for handling credentials.
However, if you can get a shell script to do the "auto-typing" or provide the required credentials some other way, then you should be able to use the same approach in a Makefile.
We can't advise you on how the script would work, because you have given no actual details of the commands etc that you are using for remote access.
But if you are using ssh from a Linux box, you could use public key authentication and ssh-agent and avoid the problem entirely. This would be a lot more secure than:
using user / password auth at all, and
embedding passwords in your makefiles ... for someone else to find when they steal your laptop or whatever.
I'm writing a bash script that needs login credentials (username and password) to make an API call. The script will eventually become a cron job, so it's not feasible to prompt the user for login credentials. What is the best way to hide the credentials in a bash script?
If you can't set up restricted read permissions on the bash script itself (e.g. only root can read it), the usual approach is to use a separate file, with said restrictions (only root or a dedicated user can read it (chmod 400 filename)).
This is how you store your ssh keys in ~/.ssh/, as well.
If you are worried about someone having full access to your drive, e.g. someone stealing it, try cryptsetup/luks.
If you are worried about someone reading the unencrypted raw device, you might try breaking up the password, and assemble it in memory when needed...
SSHPASS=$_pass sshpass -e ssh -o StrictHostKeyChecking=no $_host
I use this bit for instance and prompt user input to a restricted file, a bit more security not actually passing the variable during SSH session, but instead defining as an env variable. Haven't had many concerns from my work place Security Engineers. You can always do as others stated and have that file already containing creds rather than prompting and do the same here.
I want to create two external tools, one for encrypt using gpg and the other for decrypt. I will encrypt using simetric AES, so I should prompt the password.
I want to prompt the password only one time because if I want to encrypt or decrypt more than one time each time the password will be prompt all times that I do this operation.
So I want to store the password to a variable.
So, one external tool will be set password using:
#!/bin/sh
PASSWD="$(zenity --password --title=Authentication)\n"
And then the external tools one for encrypt and the other for decrypt.
My question if I can share the stored variable PASSWD between the other tools, and if it is secure way to do it. Where it will be stored.
If I use:
export $PASSWD
When this variable will be erased? Everybody could acces to it?
Thanks!
I wrote a helper script in Ruby to handle my file synchronization through some servers. It was used only in my intranet and authentication was made by SSH keys. But now I want to use it where I can't use SSH keys and I want to store the passwords in a config file.
I know, there are some encryption libraries like bcrypt or OpenSSL, but I have a problem with that:
I start my script and enter my passphrase and it is stored in a variable to decrypt my passwords.
My code is open source.
So everybody, who has access with my user to my computer (which would be the first barrier, which I'd like to extend) and looks into the memory (where my passphrase is stored) can decrypt my password file. How is that handled in applications which are relevant to security?
Edith says as a reply to DevDude (but here, because I want to keep my specifications in my question):
But then this configuration file would be plain text and not encrypted. And when I encrypt this file there are two more issues in my opinion:
The super_secret_pwd would be stored in a variable, so when I would search in the memory of the computer, I would find it, wouldnt I?
The master password for encryption would be in the memory as plain text, too.
So the big question is: Is it possible to read plain text variables from the memory? As I know it is possible in C and a big security issue.
What you are looking for is to use a YAML file with the password/API keys. and never check this file into your repo.
Then you can reference this file on your initializers, and maybe make the password a global variable or x, use configatron, etc.
This is basically how production applications work, they read their important settings from a YAML file stored on the server itself.
This is what I use:
#c = configatron
# Per environment settings
app_settings = YAML.load_file('config/secret_stuff.yml')
#c.password = app_settings['super_secret_pwd']
Do not use ENVIRONMENT variables because they have all sort of security issues. They are an antipattern.
in my ruby script I need to pass user name and
password as a plain text in a form in order to log in. Both user name and password are currently stored in my script.
I have no control over the server I log in from the script. The script is localy working fine and in the future I want to move to onto my
webhosting provider and run it from there (I have ssh access)
using cron. Is there any way/method how to
protect the password in case somebody gets access to this script by any chance?
The more I think about this, the more I think you must trust your hosting service. I would make sure the hosting service has "skin in the game": That is, that they host enough "high profile" accounts that being found untrustworthy would be very costly to them (in lost accounts and sales).
And whether or not you think the hosting service is trustworthy, you ought have a plan in case the target account is compromised. Who will you notify, how will you get that account deactivated, etc.
The only technological solution I can think of--you log on manually, capture the cookie, and provide that cookie to the script--protects the password, but presumably a hostile host could use that cookie to do any damage he wanted on the target system using whatever privileges are attached to that cookie, including changing your password. So it's no solution at all.
Oh, speaking of privileges: Can the task you need to automate be accomplished with a target account that has lowered privileges, such as a read-only account, or one that cannot make any changes to its profile? Having only your low-privilege credentials on the hosting service would lower your risk (or "exposure," as the polysyllabic crowd likes to say).
Prior answer, found to be unworkable, below the line.
You can encrypt the user id and password using yet another password. In order to run, the script has to be provided with it's password. It uses that password to decrypt the web service's user name and password. Make sure that the script's password doesn't get stored anywhere, but only held in memory and only for long enough to decrypt the ultimate user id and password.
If it really matters, make sure your connection to run the script is crypto (ssh, ssl, etc.), and make sure the script only uses https to log on.
That doesn't make you invulnerable to someone with root privileges on the box (at some point, the plaintext user-id and password will be in memory, and therefore vulnerable), but it does make it take more work for them to be able to get the user-id/password.
Updated: The requirement that this be automated makes the above solution no good.
If an automated script needs to run something with a password, then you either have to have it readable by the script (which opens up the possibility of someone else reading it) or else not provide it in automation.
The trick is to bypass the "Automation" part by having a one time startup: run the script as a small continual process that will wake up periodically and run. Have the process ask for the password on startup or via some other kind of API request (not on the command line!).
If the server reboots, the password is lost until you log in and enter the password again. This way, the password is only in memory, not on the file system.
You might want a cron job to check on the process and alert you if it is not running.
If you need to pass the password onwards to a form that you presumably can't alter to use a more secure scheme, there's little you can do besides obfuscate the password so that it's not immediately obvious. However, anyone with access to the script itself can simply find where it is passed to to the form and insert a command to print the password there — it needs to be “decrypted” at that point for you to pass it on, no matter what.
To protect it from non-programmers, you could XOR it with something or rotate the letters by some amount, but I wouldn't spend too much time on this as it will be futile against pretty much anyone with a rudimentary understanding of programming. Instead, protect the script itself from other users (set file access rights properly, don't put it in a web-visible directory, etc). And if you do not trust the server's administration, do not upload it there!
You should store a hashed version of the password in your database. A hash is a one way encryption, so it is impossible to use logic to guess the password from the hashed password.
Create a method to hash the password, and do something like this:
require "digest/sha1"
class User
attr_accessor :password
def initialize(password)
#password = hash_password(password)
end
def hash_password(password)
Digest::SHA1.hexdigest(password)
end
def valid_password?(password)
#password == hash_password(password)
end
end
u = User.new("12345")
p u.password # => "8cb2237d0679ca88db6464eac60da96345513964"
p u.valid_password?("not valid") # => false
p u.valid_password?("12345") # => true
When you get the plain text password from the form, you pass it to your valid_password? method. This will do the same one-way encryption as it did when the password was stored. So the one way encrypted passwords are compared. This means that you never store a reference to the actual password anywhere, which is a big win.