Web App that Compares User Credentials to /etc/shadow - security

I want to securely allow a web application to verify user credentials by checking the users entered info with /etc/shadow (unless there is some other solution). Is there any safe way to do this? It wouldn't be too hard to get it to run as root and then have it check the file and run the designated hash algorithm and salt string but this is eliminating the whole reason for having the salt value in the hash and severely reduces the security of the system.
So is there any utility or better way to try and have a web application verify my unix credentials or safe way to access /etc/shadow?

Normally, the authentication would be handled by the web server (container managed authentication). For example, in Tomcat, this would authenticate against an active directory:
<Realm className="org.apache.catalina.realm.JNDIRealm"
debug="99"
connectionName="CN=Our Users,OU=Accounts,DC=domainds,DC=com"
connectionPassword="S0mePassWord"
connectionURL="ldap://192.168.1.0:389"
alternateURL="ldap://192.168.1.1:389"
referrals="follow"
userBase="OU=User Accounts,DC=domainds,DC=com"
userSearch="(sAMAccountName={0})"
userSubtree="true"
roleBase="OU=User Roles,DC=domainds,DC=com"
roleName="cn"
roleSearch="(member={0})"
roleSubtree="true"
/>
To do what you ask is not impossible, but be careful not to pass an unencrypted password as a parameter because those might be visible on some forms of the "ps" command.
For a script (probably you would need more than one) to do what you ask, it might expose you to security issues, especially if you are not aware of all the intricacies of code injection into scripts. (Same idea a SQL injection, except it's for scripts.)

Related

Let an app sign documents, but don't let it see the keys

I want to digitally sign documents and messages on a Linux server. How do I securely store the private key and a passphrase if any?
The problem is, if an application gets compromised, keys would also become compromised. If I could somehow let an app sign something, but don't let it touch actual keys, that wouldn't completely solve my problem (as an attacker would still be able to sign anything for some time), but reduce the impact (like, we won't have to revoke the keys).
For example, in case of SSL servers there's no such problem because usually there's no practical need for an application to access the keys. Hence, they can be semi-securely stored in a separate location. E.g. a webserver (like nginx) would be able to read the keys, but not the application.
Am I overthinking it? Is it even worthy thinking of?
Create a separate, lightweight signing application that listens on an UNIX socket and runs as a separate user from the main app; when your app wants to sign something it throws the file and any additional info down that socket, and gets back the signed file.
If the application ever gets compromised the attacker will still be able to sign files as long as he is still on the server, but unless he uses a privilege escalation exploit to get root privileges and copy the signing app's key, he won't he able to steal the key and then sign at will without being connected to the server.
You can replace the UNIX socket with a standard TCP socket and put the signing app on a separate server for extra security; make sure to implement some basic access control on the signing app and of course use proper firewall rules to make sure the signing server is never exposed to the internet, or simplify things a bit by using a "setuid" binary for signing that gets invoked by your app, in that case the signing binary will run as a different user with additional privileges to access the keys, while the webapp itself doesn't have such privileges.
Basically you should implement a rudimentary software HSM.
If you have very high security needs you could consider moving the keys to a completely independent server, or better yet a hardware security module (but those are expensive). Like you mention it can help prevent the loss of keys, but if the app is compromised the attacker could still sign whatever they wanted.
The main reason to go through the trouble then is auditing. That is if you have your signing server or device keep logs of everything it signs, then if only your app is compromised you will be better able to assess the extent of the damage (assuming you're signing server has not been compromised).
So yes there are benefits, but your first focus should be on securing your main application properly, because once that's compromised you're already having a very bad no good day, even if you have moved your keys to a sperate service.

Security web login architecture?

I've implemented an login on a site (didnt use asp.net default). When a user logged in I save his ip in the db. If he doesnt doing anything in X min his ip get deleted. Whenever a user trying to enter a page that is restricted I check if his ip is on the db. If so he can continue.
The problem is that if the logged on user is on a wifi network or any other shared network, all the other users will have the same ip, and thats not good. How can I overcome this problem? Is cookies the best answer?
How is the user logging in? Username/Password? I'm assuming the password is stored as a salted hash in the database, so why not pass a cookie back with the user's username and hashed password? Whenever they try and access a restricted area check that username/password hash against your database. Make sure to sanatize the cookie values before checking them against your database to prevent injection. Or, depending on the language this is in, you could use session tracking.
I'm assuming by the tags that you're using WebLogic Server for your solution, although your comment about ASP.net makes me wonder. (although no ASP tags set for the question?)
The short answer is that you're making life harder than it needs to be - if I understand your problem correctly - that you want an idle user's session to be timed out after a certain period of inactivity for security reasons - then you can do this via application configuration with the session-timeout parameter:
http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webapp/web_xml.html#1017275
Wherever possible when security's involved, I always prefer to avoid rolling my own solution. Just not smart enough to trust it. :-)
Apologies if I'm off in my understanding here.

How can we store password other than plain text?

I've found numerous posts on stackoverflow on how to store user passwords. However, I need to know what is the best way to store a password that my application needs to communicate with another application via the web? Currently, our web app needs to transmit data to a remote website. To upload the data, our web app reads the password from a text file and creates the header with payloads and submits via https.
This password in plain text on the file system is the issue. Is there any way to store the password more securely?
This is a linux os and the application is written in python and is not compiled.
Further clarification:
There are no users involved in this process at all. The password stored in the file system is used by the other web app to authenticate the web app that is making the request. To put it in the words of a commenter below:
"In this case, the application is the client to another remote application."
From the question it seems you need to store password in such a way, that it can be read and used in an automated transaction with another site. You could encrypt the password and store it encrypted in the file, then decrypt it using a key stored elsewhere in your system before using it. This makes difficulties to someone that gets access to the file from using the password, as they now have to find the key and encryption algorithm used, so they can decrypt it.
As defense, more lesser defense is always better than one strong defense that fails when breached. Moreover, I would also secure the file containing the password, rather than the password itself. Configure your webserver to disable possibility to serve the file containing the password, and try to set the process needing the file to run under a separate account, so you can restrict the access to the file to account running the process and admin accounts only.
I don't think you will find a foolproof way to do this. I would suggest a combination of things to achieve 'security by obscurity':
store the password file on a different computer than the one which will use it
store the file path in a separate config file on the app nachine
use permissions to limit access to the config and password files to your process only
audit file access if your system allows it (keep a log of who touched the files)
give the folders and files innocuous names (/usr/joe/kittens.txt?)
block physical access to the computer(s) (offsite hosting, or locked closet, or something)
You can use a two-way key encryption algorithms like RSA,
The password is stored encrypted (by a key, which is stored in the user's brain) on the filesystem, but to decode the password, the user must enter the key.
At the very least you should use permissions (if you are on a filesystem which supports them) to ensure that you are the only one able to read the file.
In addition, if your app is compiled, it would not be too difficult to encrypt the password with a hard-coded passphrase. If the code is not compiled this method wouldn't really be helpful, as a would-be attacker could just read the source and determine the encryption.
You can store it as a result of hash algorithm, this is one way algorithm (eg. MD5 or SHA). On authentication you calc MD5 of password typed by user and checking equality with your stored MD5 password hash for this user. If is equal password is ok.
For more information about hasing algorithms you can visit:
http://en.wikipedia.org/wiki/Secure_Hash_Algorithm
http://en.wikipedia.org/wiki/MD5
Is your web application hosted on a farm? If not then a technology such as DPAPI will allow you to encrypt the password so that it can only be decrypted on the machine it was encrypted on.
From memory there can be problems with using it on a web farm though, as you need to go and re-encrypt the value for each server.
If it is a web farm then you probably want to use some form of RSA encryption as has been suggested in other answers.
EDIT: DPAPI is only good if you are hosting on windows of course...
Protecting the Automatic Logon Password
The LsaStorePrivateData function can be used by server applications to store client and machine passwords.
Windows only
I don't think you are understanding the answers provided. You don't ever store a plain-text password anywhere, nor do you transmit it to another device.
You wrote: Sorry, but the issue is storing a
password on the file system... This
password is needed to authenticate by
the other web app.
You can't count on file system protections to keep plain-text safe which is why others have responded that you need SHA or similar. If you think that a hashed password can't be sufficient for authentication, you don't understand the relevant algorithm:
get password P from user
store encrypted (e.g. salted hash)
password Q someplace relatively
secure
forget P (even clear the buffer you
used to read it)
send Q to remote host H
H gets password P' from user when
needed
H computes Q' from P', compares Q'
to Q for equality

How to verify an application is the application it says it is?

Here's the situation: we have a common library which can retrieve database connection details from a central configuration store that we have setup. Each application uses this library when working with a database.
Basically, it will call a stored procedure and say "I am {xyz} application, I need to connect o " and it will return the connection details for that applications primary database (server, instance, database, user, and password).
How would one go about locking that down so that only application {xyz} can retrieve the passwords for {xyz} databases (there is a list of database details for each application... i just need to secure the passwords)?
The usual way is to have a different config store per app and give each app a different user/password to connect to the config store.
That doesn't prevent anyone from changing the app and replacing the user/password for app X with the values from app Y but it's a bit more secure, especially when you compile this data in instead of supplying it via a config file.
If you want to be really secure, you must first create a secure connection to the store (so you need a DB drivers that supports this). This connection must be created using a secure key that is unique per application and which can be verified (so no one can just copy them around). You will need to secure the executable with hashes (the app will calculate its own hash somehow and send that to the server who will have a list of valid hashes for each app).
All in all, it's not something trivial which you can just turn on with an obscure option. You will need to learn a lot about security and secure data exchange, first. You'll need a way to safely install your app in an insecure place, verify its integrity, protect the code against debuggers that can be attached at runtime and against it running in the virtual machine, etc.
Off the top of my head, try PKI.
Are you trying to protected yourself from malicous programs, and is this a central database that these applications are connecting to? If so you should probably consider a middle layer between your database and application.
I'm not sure this applies to your case, depending on how what your answers to the abovementioned would be, but by the comments it sounds like you are having a similar case to what this question is about.
Securing your Data Layer in a C# Application
The simplest/most straightforward way would be to store the passwords in encrypted format (storing passwords in plaintext is just plain bad anyhow, as recently demonstrated over at PerlMonks) and make each application responsible for doing its own password encryption/decryption. It would then not matter whether an app retrieved another app's passwords, as it would still be unable to decrypt them.
One possibility is to keep the passwords in the database in an encrypted form, and convey the encryption key to the allowed application(s) in a secure connection.Then, only the application with the encryption key can actually get the passwords and not others.

Obscuring network proxy password in plain text files on Linux/UNIX-likes

Typically in a large network a computer needs to operate behind an authenticated proxy - any connections to the outside world require a username/password which is often the password a user uses to log into email, workstation etc.
This means having to put the network password in the apt.conf file as well as typically the http_proxy, ftp_proxy and https_proxy environment variables defined in ~/.profile
I realise that with apt.conf that you could set chmod 600 (which it isn't by default on Ubuntu/Debian!) but on our system there are people who need root priveleges .
I also realise that it is technically impossible to secure a password from someone who has root access, however I was wondering if there was a way of obscuring the password to prevent accidental discovery. Windows operates with users as admins yet somehow stores network passwords (probably stored deep in the registry obscured in some way) so that in typical use you won't stumble across it in plain text
I only ask since the other day, I entirely by accident discovered somebody elses password in this way when comparing configuration files across systems.
#monjardin - Public key authentication is not an alternative on this network I'm afraid. Plus I doubt it is supported amongst the majority of commandline tools.
#Neall - I don't mind the other users having web access, they can use my credentials to access the web, I just don't want them to happen across my password in plain text.
With the following approach you never have to save your proxy password in plain text. You just have to type in a password interactively as soon as you need http/https/ftp access:
Use openssl to encrypt your plain text proxy password into a file, with e.g. AES256 encryption:
openssl enc -aes-256-cbc -in pw.txt -out pw.bin
Use a (different) password for protecting the encoded file
Remove plain text pw.txt
Create an alias in e.g. ~/.alias to set your http_proxy/https_proxy/ftp_proxy environment variables (set appropriate values for $USER/proxy/$PORT)
alias myproxy='PW=`openssl aes-256-cbc -d -in pw.bin`; PROXY="http://$USER:$PW#proxy:$PORT"; export http_proxy=$PROXY; export https_proxy=$PROXY; export ftp_proxy=$PROXY'
you should source this file into your normal shell environment (on some systems this is done automatically)
type 'myproxy' and enter your openssl password you used for encrypting the file
done.
Note: the password is available (and readable) inside the users environment for the duration of the shell session. If you want to clean it from the environment after usage you can use another alias:
alias clearproxy='export http_proxy=; export https_proxy=; export
ftp_proxy='
I did a modified solution:
edit /etc/bash.bashrc and add following lines:
alias myproxy='read -p "Username: " USER;read -s -p "Password: " PW
PROXY="$USER:$PW#proxy.com:80";
export http_proxy=http://$PROXY;export Proxy=$http_proxy;export https_proxy=https://$PROXY;export ftp_proxy=ftp://$PROXY'
From next logon enter myproxy and input your user/password combination! Now work with sudo -E
-E, --preserve-env
Indicates to the security policy that the user wishes to reserve their
existing environment variables.
e.g. sudo -E apt-get update
Remark: proxy settings only valid during shell session
There are lots of ways to obscure a password: you could store the credentials in rot13 format, or BASE64, or use the same password-scrambling algorithm that CVS uses. The real trick though is making your applications aware of the scrambling algorithm.
For the environment variables in ~/.profile you could store them encoded and then decode them before setting the variables, e.g.:
encodedcreds="sbbone:cnffjbeq"
creds=`echo "$encodedcreds" | tr n-za-mN-ZA-M a-zA-Z`
That will set creds to foobar:password, which you can then embed in http_proxy etc.
I assume you know this, but it bears repeating: this doesn't add any security. It just protects against inadvertently seeing another user's password.
Prefer applications that integrate with Gnome Keyring. Another possibility is to use an SSH tunnel to an external machine and run apps through that. Take a look at the -D option for creating a local SOCKS proxy interface, rather than single-serving -L forwards.
Unless the specific tools you are using allow an obfuscated format, or you can create some sort of workflow to go from obfuscated to plain on demand, you are probably out of luck.
One thing I've seen in cases like this is creating per-server, per-user, or per-server/per-user dedicated credentials that only have access to the proxy from a specific IP. It doesn't solve your core obfuscation problem but it mitigates the effects of someone seeing the password because it's worth so little.
Regarding the latter option, we came up with a "reverse crypt" password encoding at work that we use for stuff like this. It's only obfuscation because all the data needed to decode the pw is stored in the encoded string, but it prevents people from accidentally seeing passwords in plain text. So you might, for instance, store one of the above passwords in this format, and then write a wrapper for apt that builds apt.conf dynamically, calls the real apt, and at exit deletes apt.conf. You still end up with the pw in plaintext for a little while, but it minimizes the window.
Is public key authentication a valid alternative for you?
As long as all three of these things are true, you're out of luck:
Server needs web access
Users need absolute control over server (root)
You don't want users to have server's web access
If you can't remove #2 or #3, your only choice is to remove #1. Set up an internal server that hosts all the software updates. Keep that one locked down from your other users and don't allow other servers to have web access.
Anything else you try to do is just fooling yourself.
we solved this problem by not asking for proxy passwords on rpm, apt or other similar updates (virus databases, windows stuff etc)
That's a small whitelist of known repositories to add to the proxy.
I suppose you could create a local proxy, point these tools through that, and then have the local proxy interactively ask the user for the external proxy password which it would then apply. It could optionally remember this for a few minutes in obfuscated internal storage.
An obvious attack vector would be for a privileged user to modify this local proxy to do something else with the entered password (as they could with anything else such as an email client that requests it or the windowing system itself), but at least you'd be safe from inadvertent viewing.

Resources