Playframework 2 - Storing your credentials - configuration

Where do you store you credentials like secret key , mail passwords, db passwords?
I made a post on https://security.stackexchange.com/questions/19785/security-concerns-about-my-webapp/19786#19786
And it seems the best way to store the credentials is on an external server.
But play2 uses the application.conf to do this.
So how and where do you store your credentials in play2?
Update 1:
Okay I am using heroku.
I set my enviroment variable like this:
heroku config:add test=ITWORKS
in application.conf I added
sometest=${test}
I trying to access it like this:
Logger.info(Play.application().configuration().getString("sometest"));
But I get the following error:
UnresolvedSubstitution: conf\application.conf: 54: Could not resolve substitution to a value: ${test}
So I guess play2 doesn't find the variable test because it is on heroku. But then I also added it in my local windows environment -> still the same error.
Any idea what is wrong?
Update2:
Okay it works, I just have to reboot after I added an env variable.
Last question:
It's kinda annoying to add the system variable everytime on my local machine. Is there a dev mode?

application.conf supports environment variables, e.g. db.default.user=${DB_USER}. You can pass it as a console parameter (which is not safe since it appears in ps), or more safely set it as an environment variable.
On Heroku, set the environment variable via heroku config, e.g. heroku config:add DB_USER=MyDBAdmin.
Locally you can set them via export DB_USER=MyDBAdmin, or add them to your ~/.bash_profile (if you use bash).

ad. 3: In Play application.conf is not accesible via any route or other kind of path so it can not be considered as 'placed in webroot'. Terry's advice is proper in PHP, but doesn't fit to Play (he warned, that he don't know the framework of course). He gives a sample of PHP script, but believe me, the diffrence between access to http://somdomain.tld/config.php and Play's conf/application.conf is huge. They can't be compared directly.
Storing credentials in application.conf is the safest (and fastest) way for now, I can't imagine a way to decompile the file in browser even if parser would die (which isn't possible as it's not PHP). If you'll decide to store credentials in some distant location, you'll gain the new risk, as you will need to additionally check if client has permissions to get the config, time required for application's start will rise etc, etc.
Update 1:
Using environment variables is not a secure way - as Marius pointed, it will appear in the process list, so you will show your credentials to each admin and I'm pretty sure that you don't want do that with ie. your email.
In Heroku of course it's a way for passing their DB connection URL, but other credentials should be stored in config file. Finally remember that Procfile command length is limited to 255 chars, so placing all credential in it will cause, that your app won't start some day.
Resolution in this case is using alernative configuration files, scenario is quite simple
in your application.conf keep an URL to your production database If it's Heroku most probably db.default.user and db.default.password should be commented as common heroku URL contains credentials in it.
For your local version create a file ie: conf/local_postgres.conf include application.conf at the beginning and override/add all required configuration keys like credentials to your local Postgres DB. Additionally you can set there other things, change logging levels, enable smtp.mock, etc.
Run your app locally with this conf. (note, I had some problem with -Dconfig.resource so I had to use -Dconfig.file syntax instead, you have to find which method will be working good in your system) ie.
play -Dconfig.resource=local_postgres.conf "~run 9123"
Tip: Using non default port is the easiest way to "demonstrate" that you're working with local config. If you'll forget that you have alternative config and will start your app with common play ~run command, your app in location http://localhost:9123 will be just unavailable.
Create a bash script run-local (or run-local.bat file in Windows) and place there command from previous point. Ignore it in .gitignore file.
From now you'll be running the application for local development with the script from point 4. While pushing to Heroku it will deploy your app with values from application.conf as you don't set alternative config in the Procfile. What's more with some other combinations you can run locally your application with Heroku's SQL to perform evolutions without pushing it to deployment, or check newest fix-pack. Of course you have to always make sure that you're developing on the local version of database, otherwise there's a risk that you accidentally change/destroy your life data.
Update 2:
Finally using *.conf files is better than storing it in separate classes in case when you have to change configuration for different locations (as mentioned yet, team working on the same code, dev/prod environments etc.)
Of course can be shortened to:
import play.Configuration;
import play.Play;
// ...
Configuration cfg = Play.application().configuration();
cfg.getString("smtp.password");
cfg.getBoolean("smtp.mock");
cfg.getInt("smtp.port");

Related

Deploy Mediawiki to Azure: no SSL Connection

I'm trying to deploy mediawiki to Azure Web App. I created the app using Linux and PHP 7.3. I unpacked WikiMedia 1.35.1 into wwwroot and used the browser to run the installation
I want to use MySQL for Azure as the database. So I enter the mysql.database.azure.com parameters and press install.
The error I get is
Cannot access the database: :real_connect(): (HY000/9002): SSL connection is required.
The docs say I need to set $wgDBssl to true in LocalSettings.php.
The problem is that LocalSettings.php does not exist yet. How do I specify an SSL connection during installation?
I am trying to figure out the same dilemma and hoping someone with more PHP knowledge can provide a better answer. As a work around, you can disable "Enforce SSL" on your MySQL database in Azure. Then you can run the setup, create the localSettings.php file. After which you can add the settings for $wgDBssl and re-enable enforce ssl setting.
To my knowledge, a connection to the database is being using the "/includes/installer/MysqlInstaller.php" when running the setup. In the "DatabaseMysqli.php" and "Database.php" of /includes/libs/rdbms/database/ directory these two files are used for connecting to the database when running any query.
I am trying to see if there is a way to set the SSL setting in these 3 files first then run the setup and application. Apologies that I've entered this as an answer also. I am new to StackOverflow and cannot create comments yet.
I was able to work around this issue by forcing the following clause in /includes/libs/rdbms/database/DatabaseMysqli.php to always be true by adding || true at the right place between the two closing parentheses:
if ( $this->getFlag( self::DBO_SSL ) || true ) {
$flags |= MYSQLI_CLIENT_SSL;
$mysqli->ssl_set(
$this->sslKeyPath,
$this->sslCertPath,
$this->sslCAFile,
$this->sslCAPath,
$this->sslCiphers
);
}
Maybe there's a more elegant way to make the original condition $this->getFlag( self::DBO_SSL ) to evaluate as true naturally?

rake db:migrate runs in development AWS Beanstalk

I'm new to Beanstalk. I've created a Rails application and set the database production configuration to use the environment variables hopefully provided by AWS. I'm using Mysql (mysql2 gem), and want to use RDS and Passenger (I have no preference there).
On my development environment I can run the rails application with my local Mysql (it is just a basic application I've created for experimentation).
I have added the passenger gem to Gemfile and bundled, but I'm using WEBBrick in development still.
The only thing I did not do by the book is that I did not use 'eb' but rather tried from the console. My application/environment failed to run as while "rake db:migrate" it still thinks I wanted it to connect to the local Mysql (I guess from the logs that it is not aware of RACK_ENV and hence uses 'development').
Any tip? I can of course try next the 'eb', yet would prefer to work with the console.
Regards,
Oren
In Elastic Beanstalk (both the web console and the cli), you can pass environnement variables. If you pass the RAKE_ENV variable, you will change your environnement.
After that you still need to pass your database parameters (db password, name, ...) which should not be hardcoded into the code.
Have you tried to run
bin/rake db:migrate RAILS_ENV=development
?
I got the same issue and that worked for me.
I recommend you enter to EC2 instance through this command "eb ssh" (The first time you need specified you .pem file, if you have not one you can create in IAM services) and check your logs for more information about yours error.
If you have problems when you are uploading your code (eb deploy) you have the log in this file: "/var/log/eb-activity.log" (Remember this file is in your EC2 instance)
If you have a problems with your app, you can read the logs in this files: "/var/app/support/logs/production.log" or "/var/app/support/logs/passenger.log"
Other recommedations is install EB CLI version 3. for manage your eb instance
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html
I believed that Elastic Beanstalk will run 'rake db:migrate' by itself. Indeed it seems to try, but that is failing. I gave my bounty to 'Yahs Hef', even though I will only try this evening (UK). My disorientation with AWS caused me to forget this easy solution, of running the migration by myself. If this does not work by itself, I'll simplify the database configuration as possibile.

How NOT to edit SSIS dtsx packages manually to change config filter in SQL Server configuration schema

I have many packages that are using the package configuration with the following way:
-ALL Packages have the XML configuration file that has only one proporty defined. The ConnectionString of the SQL Server connection that holds the configuration table for the rest of the properties
-A SEPARATE SQL Server package configuration for each connection manager in the package.
-Finally i have an SQL Server configuration for all the properties that are specific to this package.
I attach a pic of what i mean:
Yellow is the XML config with the connectionstring, Blue the connectionamangers and purple the package specific.
So with this setup i can:
Change the xml file location and just point all the setup in another sql server or another database.
Or create different configuration filters in the same config table and try to go into the package and change the filter.
With all the above the problem is that if i do anything from within VS, i am loosing the password in the connectionstring because i am not using the encrypt property. And i dont want to use it...
What are my options? Just go in .dtsx with notepad and chage what i want BEFORE i open the package or before i deploy?
-I dont want to use EncryptSensitiveWithPassword, so:
When i go to package configuration and try to change the ConfoigurationFilter to point to another setting then i am getting to the screen to select the property (connectionstring) and when i finish the DATABASE record for the setting is cleared from the Password= that i have put previously.
So i short what i want:
-No EncryptSensitiveWithPassword in my packages.
-Being able to change configuration from within VS WITHOUT resetting the connectionstring string.
The recommended way for setting this up would be to store the file location of the dtsconfig file in an environment variable. Then change the dtsconfig to use the environment variable rather than a hardcoded location.
So the nuances of that scenario are this:
The password gets blanked out when you resave the xml file (as you pointed out in your question). This is what it is, and it is one of the reasons I never use them.
A process (devenv.exe) will cache the values of the environment variables on start up. This means you need to restart visual studio if you make a change to the value of the environment variable.
The same issue above applies to the integration services service. This will need to be restarted after you add environment variables. Or when you run your packages, the values will not be found.
The idea is that your dev machine points to a dev instance. Then as you migrate the packages to new environments - QA, Prod, each server has it's own environment variable pointing to its respective dtsconfig file.
As a side note, a similar pattern which avoids the password obliteration would be to add a sql connection manager which points to the server which will load the rest of the configurations. Then set the connection string of this connection manager with an environment variable. The advantage is that you don't have to go copying config files around. This works best with integrated security so you are not storing credentials in an environment config. If you want to be more cryptic about it, you could use a registry entry.

Cakephp is not establishing a database link

I have a cake installation on a webserver and a database on a separate server.
I am able to connect to the database remotely via shell, but my cake gives
Error: Mysql requires a database connection
Error: Confirm you have created the file : app/Config/database.php.
Notice: If you want to customize this error message, create app/View/Errors/missing_connection.ctp.
I checked and PDO is setup, mod_rewrite is enabled and I have a similar setup on development server running properly. I checked core.php and it echoes proper base site url, and database.php echoes proper database selection.
Any ideas what may be causing it?
Trying to cover all of the possibilities...
With regard to the database.php file, make sure that the database credentials are being set to the $default variable and not $test, unless of course you're trying to run database unit tests of course.
The file that handles all of the initializing is the webroot's index.php file. You'll want to verify that all paths within that file are using the proper paths. If all you did was extract the CakePHP framework without any folder rearrangements, it should be all correct.
You mention that you checked mod_rewrite is enabled - did you do this with a phpinfo() call to a file located on the same (sub)domain just to verify the settings in the same location?
Although not related to the errors you're experiencing, you'll also want to verify that the external DB allows connection from your webserver's IP.

MySQL: host name universal change

I am making some updates to a php site which I did not design. I have a local copy of the site. At the top of each page there are settings for the host name for the db connection.
Is there someway I can setup a pointer to the remote address. The address is 'mysqlhost' for example and I want that to point to 'mysql.myhost.com'. I tried creating a HOST record for mysqlhost pointing to the IP address it resolves to but that doesn't work.
If I put 'mysql.myhost.com' in the connection it works. If I put that IP address it doesn't so that is probably why the HOST record idea doesn't work.
Other than creating a local copy of the DB is there a quick way so that I don't have to modify each file in my dev environment and then again when I redeploy?
It will probably be more maintainable if you do a global search and replace with your favorite text editor.
While you're doing that, put the connection info in a .inc file and change the current host info to a line that just includes the one .inc file.
Once you have done that, you can just change the .inc file (or have conditional logic in the .inc file to indicate DEV vs. PROD), so there's just one place to update when moving between environments.