views:

288

answers:

4

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?

+1  A: 

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.

Wayne Conrad
@Wayne Conrad: Hi Wayne, I updated my question ...
Radek
@Radek, I've thought about this some more. Please see above the line.
Wayne Conrad
@Wayne Conrad: I have 'standard unix account' with my webservice provider. It seems to me that I will happily run the script manually from my local comp ;-) I wanted to know if there WAS any solution to that.
Radek
@Radek, That's what I'd do. Happy hacking!
Wayne Conrad
A: 

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.

August Lilleaas
@August Lilleaas: Hi August, I know the password, it is stored in my script and I need to pass it in the form in order to log in. My question is if I can protect such password, somehow.
Radek
+1  A: 

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.

DGM
Keeping it in memory is a good idea, although there's still the chance that someone gaining write access to the script could modify it to silently send them a copy of the password. But, yes, this would protect it from anyone gaining read-only access to the script, so well worth considering if running as a background process is not an issue!
Arkku
+1  A: 

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!

Arkku