views:

119

answers:

3

I am building a suite of batch jobs that require regular access to a database, running on a Solaris 10 machine. Because of (unchangable) design constraints, we are required use a certain program to connect to it. Said interface requires us to pass a plain-text password over a command line to connect to the database. This is a terrible security practice, but we are stuck with it.

I am trying to make sure things are properly secured on our end. Since the processing is automated (ie, we can't prompt for a password), and I can't store anything outside the disk, I need a strategy for storing our password securely.

Here are some basic rules

  1. The system has multiple users.
  2. We can assume that our permissions are properly enforced (ie, if a file with a is chmod'd to 600, it won't be publically readable)
  3. I don't mind anyone with superuser access looking at our stored password

Here is what i've got so far

  • Store password in password.txt
  • $chmod 600 password.txt
  • Process reads from password.txt when it's needed
  • Buffer overwritten with zeros when it's no longer needed

Although I'm sure there is a better way.

+3  A: 

This is not a solution for cryptography. No matter the cipher used, the key will be equally accessible to the attacker. Cyrpto doesn't solve all problems.

chmod 400 is best, this makes it read only. chmod 600 is read write, which may or may not be a requirement. Also make sure its chown'ed by the the process that needs it. This is really the best you can do. Even if you are sharing the machine with other users they shouldn't be able to access it. Hopefully this is a dedicated machine, in that case there isn't much of a threat. SELinux or AppArmor will help harden the system from cross process/cross user attacks.

Edit: Shread is the tool you need to securely delete files.

Edit: Based on Moron/Mike's comments the unix command ps aux will display all running processes and the command used to invoke them. For instance the following command will be exposed to all users on the system: wget ftp://user:password@someserver/somefile.ext. A secure alternative is to use the CURL library. You should also disable your shells history. In bash you can do this by setting an environment variable export HISTFILE=

Rook
@The Rook: Right, crypto won't guarantee security better than the filesystem, since the disk is the only resource. Of course, creating a process with the password on the command line would require changing ps too.
Moron
in this case, `ps` doesn't reveal the password. but there are still many issues
Mike
@Mike: Too bad, you are in this position. And sorry for adding noise earlier. I really need to read the question first!
Moron
sorry for assuming you were a troll. with a name like "moron" it seemed like a reasonable guess
Mike
@Mike good call I did not catch that, I have edited my post.
Rook
@Moron I have mixed thoughts on your comment, never the less i think you'll like my updates.
Rook
+1  A: 

You're not far from the best approach given your constraints. You have two issues to deal with. The first is password storage. The second is using the password securely.

Dealing with the second one first -- you have a huge issue in the use of the command line program. Using options to the 'ps' command, a user can see the arguments used in running the command line program. From what you've written, this would contain the password in plain text. You mention this is an unchangeable interface. Even so, as an ethical programmer, you should raise the issue. If this were a banking application handling financial transactions, you might consider finding another job rather than being part of an unethical solution.

Moving on to securely storing the password, you don't mention what language you are using for your batch files. If you are using a shell script, then you have little recourse than than to hard code the password within the shell script or read it in plain-text from a file. From your description of storing the password in a separate file, I'm hoping that you might be writing a program in a compiled language. If so, you can do a little better.

If using a compiled language, you can encrypt the password in the file and decrypt within your program. The key for decryption would reside in the program itself so it couldn't be read easily. Besides this, I would

  • chmod 400 the file to prevent other users from reading it
  • add a dot prefix ('.') to the file to hide it from normal directory listing
  • rename the file to make it less interesting to read.
  • be careful not to store the key in a simple string -- the 'strings' command will print all printable strings from a unix executable image.

Having done these things, the next steps would be to improve the key management. But I wouldn't go this far until the 'ps' issue is cleared up. There's little sense putting the third deadbolt on the front door when you plan to leave the window open.

gkchat
i did raise the `ps` issue a while ago. they came up with a half assed solution that results in it not being visible. but i think a script kiddie could easily get around it
Mike
Most of this is security though obscurity, including the use of encryption.
Rook
A: 

Don't fill the password buffer with zeros, this is pointless. The kernel can decide to swap it to an arbitrary location in the swap file or say after allocation of some memory the kernel will move the page tables around, resulting in other page tables containing the password while you only have access to the new copy.

You can prctl(2) with PR_SET_NAME to change the process name on the fly. Unfortunately I can't currently think of any other way than injecting some code into the running process via ptrace(2), which means enemy processes will race to read the process list before you get a chance to change the new processes name :/

Alternatively, you can grab the grsecurity kernel patches, and turn on CONFIG_GRKERNSEC_PROC_USER:

If you say Y here, non-root users will only be able to view their own processes, and restricts them from viewing network-related information, and viewing kernel symbol and module information.

This will stop ps from being able to view the running command, as ps reads from /proc/<pid>/cmdline

Said interface requires us to pass a plain-text password over a command line to connect to the database. This is a terrible security practice, but we are stuck with it.

It's only a bad security practice because of problems in the O/S architecture. Would you expect other users to be able to intercept your syscalls? I wouldn't blame a developer who fell into this trap.

Longpoke