How to store user credentials for script - perl

I am required to utilize an old version of ClearQuest 7, and the only APIs that are enabled in our installation are for VBA (Excel) and RatlPERL. (The REST API isn't an option for us - although it suffers the same cleartext credential problem.)
I've written a ratlperl script that executes queries into the defect database, and produces csv output. Note that ratlperl requires cleartext user credentials for authentication.
ratlperl query.cqpl -u %userid% -p %password% -q "%query%" -c %outfile%
That script is called from a Windows Batch file. When run from the Windows command line with no parameters, the batch file requests user credentials, but they can also be provided as parameters.
query.bat %userid% %password%
I trigger daily queries, with the user credentials passed as parameters for the batch file.
This all works well, but I'd rather not store the cleartext password in this way. The registry would be one possibility, but anyone with access to the machine would have access to those credentials.
How can I store these credentials in a somewhat secure way?

There's two things to watch out for. One is having your process list "show up" the auth credentials.
Particularly on Unix - if you run ps it'll show you the arguments, which might include a username and password. The way of handling this is mostly 'read from a file, not the arg list'. On Unix, you can also amend $0 to change how you show in ps (but that doesn't help command history, and it's also not perfect as there'll be a short period before it's applied).
The other is - storing the data at rest.
This is a bit more difficult. Pretty fundamentally, there aren't many solution that let your script access the credentials that wouldn't allow a malicious user to do so.
After all, by the simple expedient of inserting a print $password into your script... they bypass pretty much any control you could put on it. Especially if they have admin access on your box, at which point... there's really nothing you can do.
Solutions I'd offer though:
Create a file with (plaintext) username and password. Set minimum permissions on it. Run the script as a user that has privileges, but don't let anyone else access that user account.
That way other people can 'see' your script (and may need to to run it) but can't copy it/hack it/run it themselves.
I would suggest sudo for this on Unix. For Windows, I'm not sure how much granularity you have over RunAs - that's worth a look, or alternatively have a scheduled task that runs as your service account, and picks up 'request files' for processing that can be generated by anyone.

As the level of security doesn't need to be so high, perhaps consider to create a simple exe? The password could possibly be read out of the memory somehow, but I guess this way creates a big enough barrier.
Or something like this could be helpful?
http://www.battoexeconverter.com/
HTH

Related

Windows 10 lock powershell file for reading and writing but not for executing

Is is possible to lock a powershell file for reading and writing but it can be still run with righ click --> Run with Powershell??
thank you
You can deny the write-access. But to execute a script you have to be able to read it.
Truly securing the credential information is only going to happen through some form of delegation as a layer between the read-able script and the credentials. There are a lot of resources out there for learning about how to securely store passwords for use in scripts.
Try reading about some of the recommendations here:
https://social.technet.microsoft.com/Forums/windows/en-US/8b14f492-88a2-4b25-9ae6-5278a1a8735d/hiding-password-in-the-script?forum=winserverpowershell
If privileged users are the only ones who can read the file, then perhaps you just want an example of obfuscation (relies on trust as it can still be used by those who can read the script):
http://blog.ctglobalservices.com/powershell/rja/store-encrypted-password-in-a-powershell-script/

Create Event Log source and write to it without administrative privileges

I'm running a Powershell logon script which sets users' Outlook signatures.
For debugging purposes, I'd like to log information in the client's Windows event log.
Using the New-Eventlog -LogName "Application" -Source $ParentScript command gives me a security error, "Access denied".
The users don't have administrative privileges so PowerShell is struggling to create a new source. I don't really understand this because most techy guides for the Event Log appear to indicate that any level of user can write to the Application log. Perhaps any user can write to this log, just not create a source within it?
I've looked online and one author appeared to suggest (unless I have misinterpreted) that creating an event log in registry could be an option: https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/00a043ae-9ea1-4a55-8b7c-d088a4b08f09/how-do-i-create-an-event-log-source-under-vista?forum=windowsgeneraldevelopmentissues
Unfortunately the code is not in PowerShell and I'm struggling to follow it.
My three-questions-in-one therefore are:
Can I create a new EventLog source in the registry using PowerShell?
If so, what commands should I be looking at and are permissions relevant (e.g. do I need to create a registry key then add perms to it?)
If so, can I write to this source in PowerShell without administrative privileges?
You can create a new Event Log souce with with the built-in cmelt New-EventLog something like there is a nice (even if somehow dated) post here
Full documentation for the cmdlet can be found here
Generally speaking yes you, well your user, should be able to write to the event log if memory serves a non local admin user should already be able to do so but I cannot test it right now anyhow you can red more here or read on server fault
Hope this can help a bit.

Require password to modify powershell script

I've been having issues with people modifying powershell scripts and causing mayhem. Is there a one liner that I can insert into a current script to require a password that I set in order to modify the script? I still need everyone to be able to run it.
The easiest and most straightforward way is to put the scripts somewhere that the problem users don't have write access to. There's nothing you can do in the language itself to prevent a user from modifying a file they have write access to.
If you can't do this for some reason (they are admins and have too much access), then you can do a few other things.
Signing
Apply a digital signature to your scripts.
For this to work, you need to be able to enforce an execution policy of AllSigned (or RemoteSigned if these scripts are executed directly off of a share). You might do this with Group Policy.
You also need to control access to the signing certificate and ensure that it's the only one that's trusted.
Note that these users can still copy the script locally, make modifications, run powershell.exe -ExecutionPolicy Bypass and still run their modified script.
The difference is that this is their copy and doesn't break it for anyone else. And if they overwrite the central script without signing it or signing it with an untrusted certificate then everyone will notice.
If the users are privileged enough they be able to override more of this.
Central Deployment
Put the scripts in a custom local repository and use the package management functions Find-Script / Install-Script so everyone is referring to the same ones, and have a well-thought out deployment process. This can be combined with signing.
But...
Ultimately if these users are privileged and they are acting in bad faith, this is a personnel problem and can't effectively be solved with technology. In that case, The Workplace may be able to help.

need perl script to connect to database, but don't want the password in plain text [duplicate]

When a PHP application makes a database connection it of course generally needs to pass a login and password. If I'm using a single, minimum-permission login for my application, then the PHP needs to know that login and password somewhere. What is the best way to secure that password? It seems like just writing it in the PHP code isn't a good idea.
Several people misread this as a question about how to store passwords in a database. That is wrong. It is about how to store the password that lets you get to the database.
The usual solution is to move the password out of source-code into a configuration file. Then leave administration and securing that configuration file up to your system administrators. That way developers do not need to know anything about the production passwords, and there is no record of the password in your source-control.
If you're hosting on someone else's server and don't have access outside your webroot, you can always put your password and/or database connection in a file and then lock the file using a .htaccess:
<files mypasswdfile>
order allow,deny
deny from all
</files>
The most secure way is to not have the information specified in your PHP code at all.
If you're using Apache that means to set the connection details in your httpd.conf or virtual hosts file file. If you do that you can call mysql_connect() with no parameters, which means PHP will never ever output your information.
This is how you specify these values in those files:
php_value mysql.default.user myusername
php_value mysql.default.password mypassword
php_value mysql.default.host server
Then you open your mysql connection like this:
<?php
$db = mysqli_connect();
Or like this:
<?php
$db = mysqli_connect(ini_get("mysql.default.user"),
ini_get("mysql.default.password"),
ini_get("mysql.default.host"));
Store them in a file outside web root.
For extremely secure systems we encrypt the database password in a configuration file (which itself is secured by the system administrator). On application/server startup the application then prompts the system administrator for the decryption key. The database password is then read from the config file, decrypted, and stored in memory for future use. Still not 100% secure since it is stored in memory decrypted, but you have to call it 'secure enough' at some point!
This solution is general, in that it is useful for both open and closed source applications.
Create an OS user for your application. See http://en.wikipedia.org/wiki/Principle_of_least_privilege
Create a (non-session) OS environment variable for that user, with the password
Run the application as that user
Advantages:
You won't check your passwords into source control by accident, because you can't
You won't accidentally screw up file permissions. Well, you might, but it won't affect this.
Can only be read by root or that user. Root can read all your files and encryption keys anyways.
If you use encryption, how are you storing the key securely?
Works x-platform
Be sure to not pass the envvar to untrusted child processes
This method is suggested by Heroku, who are very successful.
if it is possible to create the database connection in the same file where the credentials are stored. Inline the credentials in the connect statement.
mysql_connect("localhost", "me", "mypass");
Otherwise it is best to unset the credentials after the connect statement, because credentials that are not in memory, can't be read from memory ;)
include("/outside-webroot/db_settings.php");
mysql_connect("localhost", $db_user, $db_pass);
unset ($db_user, $db_pass);
If you are using PostgreSQL, then it looks in ~/.pgpass for passwords automatically. See the manual for more information.
Previously we stored DB user/pass in a configuration file, but have since hit paranoid mode -- adopting a policy of Defence in Depth.
If your application is compromised, the user will have read access to your configuration file and so there is potential for a cracker to read this information. Configuration files can also get caught up in version control, or copied around servers.
We have switched to storing user/pass in environment variables set in the Apache VirtualHost. This configuration is only readable by root -- hopefully your Apache user is not running as root.
The con with this is that now the password is in a Global PHP variable.
To mitigate this risk we have the following precautions:
The password is encrypted. We extend the PDO class to include logic for decrypting the password. If someone reads the code where we establish a connection, it won't be obvious that the connection is being established with an encrypted password and not the password itself.
The encrypted password is moved from the global variables into a private variable The application does this immediately to reduce the window that the value is available in the global space.
phpinfo() is disabled. PHPInfo is an easy target to get an overview of everything, including environment variables.
Your choices are kind of limited as as you say you need the password to access the database. One general approach is to store the username and password in a seperate configuration file rather than the main script. Then be sure to store that outside the main web tree. That was if there is a web configuration problem that leaves your php files being simply displayed as text rather than being executed you haven't exposed the password.
Other than that you are on the right lines with minimal access for the account being used. Add to that
Don't use the combination of username/password for anything else
Configure the database server to only accept connections from the web host for that user (localhost is even better if the DB is on the same machine) That way even if the credentials are exposed they are no use to anyone unless they have other access to the machine.
Obfuscate the password (even ROT13 will do) it won't put up much defense if some does get access to the file, but at least it will prevent casual viewing of it.
Peter
We have solved it in this way:
Use memcache on server, with open connection from other password server.
Save to memcache the password (or even all the password.php file encrypted) plus the decrypt key.
The web site, calls the memcache key holding the password file passphrase and decrypt in memory all the passwords.
The password server send a new encrypted password file every 5 minutes.
If you using encrypted password.php on your project, you put an audit, that check if this file was touched externally - or viewed. When this happens, you automatically can clean the memory, as well as close the server for access.
Put the database password in a file, make it read-only to the user serving the files.
Unless you have some means of only allowing the php server process to access the database, this is pretty much all you can do.
If you're talking about the database password, as opposed to the password coming from a browser, the standard practice seems to be to put the database password in a PHP config file on the server.
You just need to be sure that the php file containing the password has appropriate permissions on it. I.e. it should be readable only by the web server and by your user account.
An additional trick is to use a PHP separate configuration file that looks like that :
<?php exit() ?>
[...]
Plain text data including password
This does not prevent you from setting access rules properly. But in the case your web site is hacked, a "require" or an "include" will just exit the script at the first line so it's even harder to get the data.
Nevertheless, do not ever let configuration files in a directory that can be accessed through the web. You should have a "Web" folder containing your controler code, css, pictures and js. That's all. Anything else goes in offline folders.
Just putting it into a config file somewhere is the way it's usually done. Just make sure you:
disallow database access from any servers outside your network,
take care not to accidentally show the password to users (in an error message, or through PHP files accidentally being served as HTML, etcetera.)
Best way is to not store the password at all!
For instance, if you're on a Windows system, and connecting to SQL Server, you can use Integrated Authentication to connect to the database without a password, using the current process's identity.
If you do need to connect with a password, first encrypt it, using strong encryption (e.g. using AES-256, and then protect the encryption key, or using asymmetric encryption and have the OS protect the cert), and then store it in a configuration file (outside of the web directory) with strong ACLs.
Actually, the best practice is to store your database crendentials in environment variables because :
These credentials are dependant to environment, it means that you won't have the same credentials in dev/prod. Storing them in the same file for all environment is a mistake.
Credentials are not related to business logic which means login and password have nothing to do in your code.
You can set environment variables without creating any business code class file, which means you will never make the mistake of adding the credential files to a commit in Git.
Environments variables are superglobales : you can use them everywhere in your code without including any file.
How to use them ?
Using the $_ENV array :
Setting : $_ENV['MYVAR'] = $myvar
Getting : echo $_ENV["MYVAR"]
Using the php functions :
Setting with the putenv function - putenv("MYVAR=$myvar");
Getting with the getenv function - getenv('MYVAR');
In vhosts files and .htaccess but it's not recommended since its in another file and its not resolving the problem by doing it this way.
You can easily drop a file such as envvars.php with all environment variables inside and execute it (php envvars.php) and delete it. It's a bit old school, but it still work and you don't have any file with your credentials in the server, and no credentials in your code. Since it's a bit laborious, frameworks do it better.
Example with Symfony (ok its not only PHP)
The modern frameworks such as Symfony recommends using environment variables, and store them in a .env not commited file or directly in command lines which means you wether can do :
With CLI : symfony var:set FOO=bar --env-level
With .env or .env.local : FOO="bar"
Documentation :

How secure is a powershell runspace/session

If i create a powershell runspace, either programatically with .NET or just by launching the powershell console; How secure are the scripts/commands that are run?
I'm not speaking about signing scripts, but the actually memory space that the scripts are run in.
I'm worried that if sensitive information is gathered as part of the script (a sql query into a salary database for example) that someone could hack this data out.
I know most people are thinking SecureString at this point, i know about SecureString.... I'm wanting to know specifically about the powershell runspace, not how to store strings securely inside a runspace (lets hope that last sentence didn't just answer my own question).
Specifically :
Are other applications/scripts/whatever able to peer into the runspace and see the commands i'm running?
Powershell script security works by controlling whether or not a script is "allowed" to run on your machine. If you have a machine running an execution policy of "AllSigned", that machine will require the Powershell script to be signed by a trusted certificate.
Scott Hanselman has a really good article on it here.
To my knowledge, your command history isn't permanently saved. You can do a "get-history" to see the commands you've entered in your current session, but it's not like linux/unix where "history" will contain all of the commands you've ever run on the system. As far as other applications being able to "peer into" or query your session, I have no idea.