Slashdot Mirror


Keeping Passwords Embedded In Code Secure?

JPyObjC Dude asks: "When designing any system that requires automated privileged access to databases or services, developers often rely on hard coding (embedding) passwords within the source code. This is obviously a bad practice as the password is then made available to anybody who has access to the source code (eg. software source control). Putting the passwords in configuration files is another practice, but it is still quite insecure as cracking hashed passwords from a text file is a trivial exercise. What do you do to manage your application passwords so that your system can run completely automated and yet make it difficult for hackers to get their hands on this precious information?"

5 of 130 comments (clear)

  1. Wrong Question by eric.t.f.bat · · Score: 4, Interesting

    First: only an idiot would put a password into source code. That's what configuration files are for. What, you want to have to edit a script every time the password changes? Second, there's no point encoding, encrypting or otherwise "securing" the configuration file. If a user has access to your configuration files, he has access to everything else, and all your security is useless. So really the question is: I don't want the neighbours to see me naked. What should I tattoo on my butt-cheeks to make me safe?

    --
    I have discovered a truly remarkable .sig block which this margin is too small to conta
  2. Re:You don't even need the source code by mark-t · · Score: 3, Interesting

    As a developer who has hardcoded passwords into applications before, I can safely say that using 'strings' would NOT have worked, as I never actually create d a string for such a password -- rather, I would implement a backdoor password as an FSM, with each state having its own separate case code that compares a character in the string entered to a single character from the actual password. Any deviance from the path for the FSM would fall through to the normal password handling facility, using the characters entered so far as the string entered. The passwords in such a case were non-trivial, between 20 and 40 characters, including combinations of letters, numbers, punctuation, and blanks, so the likelihood of stumbling across them accidently was remote to the extreme. Changing the password was only possible with access to the source code, and was done in a way that was simple to maintain, but in the over 10 years of use that these programs received in the companies that they were written for, the security of these hard-coded passwords were never compromised (because of the industry we were in, if it had been, we would have heard about it because the way we wrote it, it would have caused a panic).

    It's probably not something I'd ever do these days, but back in the 80's and early 90's, it worked very well.

  3. Re:No answer by theshowmecanuck · · Score: 3, Interesting

    Someone mod parent up more. As stated, DB access usually happens over an internal network (99% of the time) and only the outside interface of the web server is open to the public (assuming it is an app that is accessible to the world and not an internal app anyway). On bigger apps, only the model components on the backing app server(s) should be doing the DB access etc. and that should definitely be behind the firewall along with the DB. In all cases if the firewalled internal network is compromised, you are really screwed anyway, so what does encryption etc. matter? Unless you don't trust the people who administer your apps and can wreck you business more easily by not doing backups and using a baseball bat on the hard drives or something equally brutal.

    --
    -- I ignore anonymous replies to my comments and postings.
  4. Encrypted File System and other tricks by Midnight+Warrior · · Score: 2, Interesting

    Encrypted file systems have a similar problem. They need to decrypt the filesystem for authorized boots or mounts, but need to stay encrypted otherwise. One common trick here is to only make the decryption key available once, at start up, after which it is put into memory, preferable with a small amount of obfuscation to slow down memory walkers. You could then use something like FUSE to mount the encrypted filesystem with your plaintext password.

    As other folks have wisely pointed out though, the best posture is to use mandatory access control and restrict access to the configuration file. If you have the privileges, another good practices involves removing all compilers from the machine, firewalling all FTP traffic in or out, firewalling egress (outbound) HTTP traffic (pull in files to process), restrict SSH traffic to pre-defined nodes and enforcing that with a firewall ruleset. Preferably, you'd make all the firewall stuff occur on a separate box. What this does is restrict what tools will be available to an attacker. You can also remove fun programs like strings, ldd, od, *hexedit, and so on. "But I need to modify these tools!" you say. Leave SVN or CVS clients on the node, check your changes into SVN/CVS on your test bed machine, and then just check out the latest stable branch on your exposed machine. Then you get good protection and good configuration management all in one swoop.

    Other tricks involve establishing a proxy process or strict limiting what can be done with the compromised username/password. A proxy process might be a setuid C program that only does one thing and accepts no user input. If you must accept user input, be extremely strict (use sscanf on all inputs and limit the size of the buffer accepted) and then have an experienced C developer review your code for improper bounds handling. This proxy process might do things like move files to a read-only directory structure (static web pages in a DMZ), or it might be a CGI script that updates rows in a database. We've actually used the CGI script idea because it a) it a cross-platform way of talking to the database, b) is a good decoupler of otherwise complex code, and c) strongly limits what can be done as an attack. Be careful of the venerable SQL injection attack there though.

    A good use of a proxy process might be the transparent mounting/unmounting of an external USB drive, perhaps against a hidden partition on the stick. The drive would have your key. Sure it's obfuscation, but it's complicated enough to decode that it will slow somebody down for a while.

    The last trick is to limit what can be accomplished with the username/password that is obtained. We have some processes whose job is to inject data into the database for the backend to all of our tools. That database user is limited to select, insert, and update operations. With Oracle, I could even restrict which specific tables get which privileges.

    The best thing to do is to write a document that some folks call the Security Design Document to define your security posture, what you are known to protect against, and where you are vulnerable. Assign a risk mitigation matrix (vulnerability, threat, countermeasure, residual risk) row to each vulnerability. Be honest and then let your manager understand the position you've left them in and try to assign a cost to each countermeasure/mitigation so they can make a decision on what to close or leave open.

    You are always going to have vulnerabilities. Everyone does, even the best systems. What makes the difference is those who analyze, understand, and counter that risk in a way that is appropriate to the situation. Direct exposure to the Internet is a situation that should warrant better risk analysis, but rarely does.

  5. No really good solutions by rlp · · Score: 2, Interesting

    You've got a machine A on the interior LAN, that needs credentials to access a DB on machine B on the interior LAN. You've got two choices:

    1) You can store the credentials somewhere on machine A.
    2) The service (typically a Web server) on machine A can run with an account that's either has privileges to access the DB or has privileges to access credentials stored somewhere else to access the DB.

    If an intruder gets access to machine A and gets root / admin privileges - then they can gain access to the DB. Obviously, you're first priority is to make sure that this does not happen! Use good firewalls and firewall rules. Make proper use of a DMZ. Check your application for security problems (buffer overflow, SQL injection, etc). Keep up to date on patches. Your second line of defense, is to:

    1) Try to insure that an intruder is detected.
    2) Make them work for it (access to DB)
    3) Have a good audit trail
    4) Monitor your network and application

    I'll address item #2. Assume that you put the credentials in the configuration file or a separate file on machine A. You should encrypt the credentials (using an encryption application NOT kept on machine A). The key can be hard-coded in the (web) application. If you want, you can use layers of keys(Encrypted key b decodes key in config file. Encrypted key c decodes key b, Encrypted key d ...), but this quickly reaches a point of diminishing returns and can become a maintenance nightmare. You can obfuscate the key or even build it on the fly to make it more difficult to extract it from the application (for binary apps - it helps to strip the symbol table). Use the OS permissions to restrict access to the config / key file and the (web) application. This won't stop a determined intruder, but they'll have to work for access, and it will slow them down.

    --
    [Insert pithy quote here]