How to encrypt User-Provided Service values in cloud foundry? - encryption

I am trying to encrypt my username and password on cloud foundry. Currently I am storing these values as a CUPS (VCAP_SERVICES).
SPRING_DATASOURCE_URL: jdbc:oracle:thin:#//spring.guru.csi0i9rgj9ws.us-east-1.rds.a‌​mazonaws.com:1521/OR‌​C
SPRING_DATASOURCE_USERNAME: UserAdmin
SPRING_DATASOURCE_PASSWORD: p4ssw0rd
SPRING_DATASOURCE_initialize: false
I want to encrypt it so it would show some type of token/encryption or UUID instead of my actual username and password. How would I be able to encrypt these values so that, when I look at my VCAP_SERVICES these values would not be exposed?
Example from Cloud Foundry Provided Service
VCAP_SERVICES=
{
cleardb: [
{
name: "cleardb-1",
label: "cleardb",
plan: "spark",
credentials: {
SPRING_DATASOURCE_URL: "jdbc:oracle:thin:#//spring.guru.csi0i9rgj9ws.us-east-1.rds.a‌​mazonaws.com:1521/OR‌​C",
SPRING_DATASOURCE_USERNAME: "UserAdmin",
SPRING_DATASOURCE_PASSWORD: "p4ssw0rd",
SPRING_DATASOURCE_initialize: "false"
}
}
]
As you can see VCAP_SERVICES above is exposed how can I encrypt it so that username and password is encrypted like example below
Desired output
Username: hVB5j5GgdiP78xCSV9sNv4FeqQJducBxXlB81090ozYB
Password: hVB523fff78xCSV9sNv4FeqQ341090324234fdfdsrrf

Depending on what do you want to archive you can use spring vault mentioned by you or external vault instance with hashicorp service broker https://github.com/hashicorp/cf-vault-service-broker to retrieve/store credentials within your application in a secure way.
As a side note - the Mongodb service credentials on the screenshot are not encrypted but randomly generated by the service broker.
Most importantly - you shouldn't store/provide service credentials in your application manifest, but obtain this credentials (for binded cloudfoundry services) by parsing environment variable VCAP_SERVICES.
https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES
External services should be presented to cloud foundry apps via CUPS https://docs.cloudfoundry.org/devguide/services/user-provided.html

Since you appear to be using Spring already, you might want to look at Spring Cloud Config.
https://cloud.spring.io/spring-cloud-config/
For larger projects it makes it easy to externalize and manage your configuration. A common setup would be to store the configuration in Git (but there are other backends, including Vault), Spring Cloud Config then runs as a server and provides the configuration to your running applications (clients). Your application (client) doesn't need to do much beyond include the Spring Cloud Config dependencies and a couple lines of config. Settings are obtained automatically and integrated through the Environment and PropertySource abstractions, which makes for a very clean integration where you don't need to do a lot of work.
For smaller projects, it might be more overhead than you'd like. For starts, you have to run the Spring Cloud Server. If you only have one or two small apps, the resources to run the SCC server might be more than your app or apps total. Complexity would be another concern. Using SCC definitely adds some complexity and possible failure scenarios. You'd need to understand what's happening well enough to troubleshoot when there is a problem.
What you might want to consider instead for smaller projects is simply using user provided services in CF. These make for a central place to store your config settings (doesn't have to just be databases, could be keys and other things too). You can then bind these to your apps to expose the configuration settings to that app.
There is some security in that Cloud Controller manages who can access your services. I believe the information that Cloud Controller stores is also encrypted at rest, which is a plus. That said, information is exposed to your applications via environment variables (i.e. VCAP_SERVICES) so anything in the container that can see the environment variables will be able to read your settings.
Using user provided services is one step up on environment variables. Not really from a security stand point, but more from a management stand point. You create the user provided service once, and can then bind it to any number of apps. With env variables, you'd need to set those for every app. It's more tedious, and it's prone to typos. You can also put the service name into your manifest.yml file so it automatically binds to the app and still check that into source control. If you were putting env variables with sensitive info into your manifest.yml, you wouldn't want to check it into source control and you'd have to be a lot more careful with that file.

Related

Is there a way to create a single copy data pipeline that shares a single source data set and file system connection pointing to different drives?

I'm attempting to deploy an azure data factory with a copy data pipeline that pulls files from one or more deployed / on-prem file system paths and dumps them in blob storage. The source file paths on the file system may span multiple different drives (e.g. - C:\fileshare1 vs D:\fileshare2) and may include network locations referenced via UNC paths (e.g. - \\localnetworkresource\fileshare3).
I'd like to configure a single local file system connection and source data set and just parameterize the linked service's host property. Then my pipeline would just iterate over a collection of file share paths and reuse the dataset and linked service connection. However, it doesn't look like there's any way to have the data set or pipeline provide the host information to the linked service. It's certainly possible to provide folder information from the pipeline and dataset, but that will be concatenated to the host specified in the linked service connection and therefore won't allow me access to different drives or network resources.
It was reasonably straightforward to do this by configuring separate linked service connections, data sets and pipelines for each distinct file share that needed to be included, but I'd prefer to manage a single pipeline.
Yes, you can parameterize linked service.
https://learn.microsoft.com/en-us/azure/data-factory/parameterize-linked-services
Currently, ADF UI only supports 8 kinds of linked service parameterization. But actually all the linked service are supported in ADF Runtime. You could use json code to do it.
Refer these two post here:
Azure Data Factory - Dynamic Account information - Parameterization of Connection
How to provide connection string dynamically for azure table storage/blob storage in Azure data factory Linked service

Application Insights: Filter website health checks?

I'm using Azure Application Insights on the free tier. We also use amazon AWS health checks that hits a pre-determined page expecting a 200 response it then does things if it gets a different response.
All the requests from AWS are filling up telemetry pretty quickly.
Is there a simple way to filter or exclude these requests?
Can it be done from the App Insights console, or does it require modifying the telemetry collector on the actual application. I'd rather not create my own implementation of the ITelemtryProcessor...
And if i am stuck going that route, would this work to filter AWS Route53 checks?
public void Process(ITelemetry item)
{
if (!string.IsNullOrEmpty(item.Context.Operation.SyntheticSource)) {return;}
this.Next.Process(item);
}
Edit-Update
Has anyone seen this part of the applicationinsights.config I'm not certain by what it means that it will not have correlation headers.
<ExcludeComponentCorrelationHttpHeadersOnDomains>
<!--
Requests to the following hostnames will not be modified by adding correlation headers.
This is only applicable if Profiler is installed via either StatusMonitor or Azure Extension.
Add entries here to exclude additional hostnames.
NOTE: this configuration will be lost upon NuGet upgrade.
-->
<Add>core.windows.net</Add>
<Add>core.chinacloudapi.cn</Add>
<Add>core.cloudapi.de</Add>
<Add>core.usgovcloudapi.net</Add>
<Add>localhost</Add>
<Add>127.0.0.1</Add>
</ExcludeComponentCorrelationHttpHeadersOnDomains>
Does anyone have any other resources or tutorials, the only one i was able to find: https://learn.microsoft.com/en-us/azure/application-insights/app-insights-api-filtering-sampling#filtering
It seems that probably most simple way to implement is to grab a collection from the web.config, define the processor in its own class file, then insert the processor into the chain into the global config...
You'll have to write a telemetry initializer like you have above.
However, you might want to look more specifically at the synthetic source and verify content and only throw away the amazon health checks instead of all synthetic traffic (you could also look at request name, etc to make your decisions), as i'm not exactly sure what information is in those inbound requests from amazon.
Otherwise, you might be throwing away incoming requests/dependencies/exceptions that might occur from your webtests, which would also show up as synthetic.

How to invoke code within a web app that isn't externally open?

Say, for example, you are caching data within your ASP.NET web app that isn't often updated. You have another process running outside of the app which ocassionally updates this data, when you do this you would like the cached data to be cleared immediately so that the next request picks up the new data straight away.
The caching service is running in the context of your web app and not externally - what is a good method of calling into the web app to get it to update the cache?
You could of course, just hack a page or web service together called ClearTheCache that does it. This can then be called by your other process. Of course you don't want this process to be externally useable or visible on your web app, so perhaps you could then check that incoming requests to this page are calling localhost, if not throw a 404. Is this acceptable? Could this be spoofed at all (for instance if you used HttpApplication.Request.Url.Host)?
I can think of many different ways to go about this, mainly revolving around creating a page or web service and limiting requests to it somehow, but I'm not sure any are particularly elegant. Neither do I like the idea of the web app routinely polling out to another service to check if it needs to execute something, I'd really like a PUSH solution.
Note: The caching scenario is just an example, I could use out-of-process caching here if needed. The question is really concentrating on invoking code, for any given reason, within a web app externally but in a controlled context.
Don't worry about the limiting to localhost, you may want to push from a different server in future. Instead share a key (asymmetrical or symmetrical doesn't really matter) between the two, have the PUSH service encrypt a block of data (control data for example) and have the receiver decrypt. If the block decrypts correctly and the data is readable you can safely assume that only the service that was supposed to call you has and you can perform the required actions! Not the neatest solution, but allows you to scale beyond a single server.
EDIT
Having said that an asymmetrical key would be better, have the PUSH service hold the private part and the website the public part.
EDIT 2
Have the PUSH service put the date/time it generated the cipher text into the data block, then the client can be sure that a replay attack hasn't taken place by ensuring the date/time is within an acceptable time period (say a minute).
Consider an external caching mechanism like EL's caching block, which would be available to both the web and the service, or a file to cache data to.
HTH.

How to keep multiple connectionString passwords safe, separate, and easy to deploy?

I know there are plenty of questions here already about this topic (I've read through as many as I could find), but I haven't yet been able to figure out how best to satisfy my particular criteria. Here are the goals:
The ASP.NET application will run on a few different web servers, including localhost workstations for development. This means encrypting web.config using a machine key is out. Each "type" or environment of web server (dev, test, prod) has its own corresponding database (dev, test, prod). We want to separate these connection strings so that a developer working on the "dev" code is not able to see any "prod" connection string passwords, nor allow these production passwords to ever get deployed to the wrong server or committed to SVN.
The application will should be able to decide which connection string to attempt to use based on the server name (using a switch statement). For example, "localhost" and "dev.example.com" will should know to use the DevDatabaseConnectionString, "test.example.com" will use the TestDatabaseConnectionString, and "www.example.com" will use the ProdDatabaseConnectionString, for example. The reason for this is to limit the chance for any deployment accidents, where the wrong type of web server connects to the wrong database.
Ideally, the exact same executables and web.config should be able to run on any of these environments, without needing to tailor or configure each environment separately every time that we deploy (something that seems like it would be easy to forget/mess up one day during a deployment, which is why we moved away from having just one connectionstring that has to be changed on each target). Deployment is currently accomplished via FTP. Update: Using "build events " and revising our deployment procedures is probably not a bad idea.
We will not have command-line access to the production web server. This means using aspnet_regiis.exe to encrypt the web.config is out. Update: We can do this programmatically so this point is moot.
We would prefer to not have to recompile the application whenever a password changes, so using web.config (or db.config or whatever) seems to make the most sense.
A developer should not be able to get to the production database password. If a developer checks the source code out onto their localhost laptop (which would determine that it should be using the DevDatabaseConnectionString, remember?) and the laptop gets lost or stolen, it should not be possible to get at the other connection strings. Thus, having a single RSA private key to un-encrypt all three passwords cannot be considered. (Contrary to #3 above, it does seem like we'd need to have three separate key files if we went this route; these could be installed once per machine, and should the wrong key file get deployed to the wrong server, the worst that should happen is that the app can't decrypt anything---and not allow the wrong host to access the wrong database!)
UPDATE/ADDENDUM: The app has several separate web-facing components to it: a classic ASMX Web Services project, an ASPX Web Forms app, and a newer MVC app. In order to not go mad having the same connection string configured in each of these separate projects for each separate environment, it would be nice to have this only appear in one place. (Probably in our DAL class library or in a single linked config file.)
I know this is probably a subjective question (asking for a "best" way to do something), but given the criteria I've mentioned, I'm hoping that a single best answer will indeed arise.
Thank you!
Integrated authentication/windows authentication is a good option. No passwords, at least none that need be stored in the web.config. In fact, it's the option I prefer unless admins have explicity taken it away from me.
Personally, for anything that varies by machine (which isn't just connection string) I put in a external reference from the web.config using this technique: http://www.devx.com/vb2themax/Tip/18880
When I throw code over the fence to the production server admin, he gets a new web.config, but doesn't get the external file-- he uses the one he had earlier.
you can have multiple web servers with the same encrypted key. you would do this in machine config just ensure each key is the same.
..
one common practice, is to store first connection string encrypted somewhere on the machine such as registry. after the server connects using that string, it will than retrieve all other connection strings which would be managed in the database (also encrypted). that way connection strings can be dynamically generated based on authorization requirements (requestor, application being used, etc) for example the same tables can be accessed with different rights depending on context and users/groups
i believe this scenario addresses all (or most?) of your points..
(First, Wow, I think 2 or 3 "quick paragraphs" turned out a little longer than I'd thought! Here I go...)
I've come to the conclusion (perhaps you'll disagree with me on this) that the ability to "protect" the web.config whilst on the server (or by using aspnet_iisreg) has only limited benefit, and is perhaps maybe not such a good thing as it may possibly give a false sense of security. My theory is that if someone is able to obtain access to the filesystem in order to read this web.config in the first place, then they also probably have access to create their own simple ASPX file which can "unprotect" it and reveal its secrets to them. But if unauthorized people are trouncing around in your filesystem—well… then you have bigger problems at hand, so my whole concern is now moot! 1
I also realize that there isn’t a foolproof way to securely hide passwords within a DLL either, as they can eventually be disassembled and discovered, perhaps by using something like ILDASM. 2 An additional measure of security obscurity can be obtained by obfuscating and encrypting your binaries, such as by using Dotfuscator, but this isn’t to be considered “secure.” And again, if someone has read access (and likely write access too) to your binaries and filesystem, you’ve again got bigger problems at hand methinks.
To address the concerns I mentioned about not wanting the passwords to live on developer laptops or in SVN: solving this through a separate “.config” file that does not live in SVN is (now!) the blindingly obvious choice. Web.config can live happily in source control, while just the secret parts do not. However---and this is why I’m following up on my own question with such a long response---there are still a few extra steps I’ve taken to try and make this if not any more secure, then at least a little bit more obscure.
Connection strings we want to try to keep secret (those other than the development passwords) won’t ever live as plain text in any files. These are now encrypted first with a secret (symmetric) key---using, of course, the new ridiculous Encryptinator(TM)! utility built just for this purpose---before they get placed in a copy of a “db.config” file. The db.config is then just uploaded only to its respective server. The secret key is compiled directly into the DAL’s dll, which itself would then (ideally!) be further obfuscated and encrypted with something like Dotfuscator. This will hopefully keep out any casual curiosity at the least.
I’m not going to worry much at all about the symmetric "DbKey" living in the DLLs or SVN or on developer laptops. It’s the passwords themselves I’ll keep out. We do still need to have a “db.config” file in the project in order to develop and debug, but it has all fake passwords in it except for development ones. Actual servers have actual copies with just their own proper secrets. The db.config file is typically reverted (using SVN) to a safe state and never stored with real secrets in our subversion repository.
With all this said, I know it’s not a perfect solution (does one exist?), and one that does still require a post-it note with some deployment reminders on it, but it does seem like enough of an extra layer of hassle that might very well keep out all but the most clever and determined attackers. I’ve had to resign myself to "good-enough" security which isn’t perfect, but does let me get back to work after feeling alright about having given it the ol’ "College Try!"
1. Per my comment on June 15 here http://www.dotnetcurry.com/ShowArticle.aspx?ID=185 - let me know if I'm off-base! -and some more good commentary here Encrypting connection strings so other devs can't decrypt, but app still has access here Is encrypting web.config pointless? and here Encrypting web.config using Protected Configuration pointless?
2. Good discussion and food for thought on a different subject but very-related concepts here: Securely store a password in program code? - what really hit home is the Pidgin FAQ linked from the selected answer: If someone has your program, they can get to its secrets.

How to restrict a Flex application to only run from my website?

is it possible to make a Flex-application to only run from my domain? So a user can't copy the .swf and start it locally.
In a lot of cases this won't work because of the security model associated with the crossdomain.xml.
http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html
Say for example, I have a flex app that has a service call and login to my backend database (perhaps PHP and mysql). Unless I explicitly enable it in crossdomain.xml policy file the app will not be able to communicate with my server unless the swf file is directly loaded from my domain. If the app was local it would look to my server like localhost was trying to access my backend through the flex app. So by default this would not work unless an explicit rule was put in place in the crossdomain.xml to allow access from localhost. Likewise someone cannot simply put the swf on a different server and try to access from my server unless I add that remote server to the crossdomain.xml policy.
So back to your question. Obviously, this crossdomain.xml stuff doesn't really apply if your flex app is really simple and does not try to make service calls to a server. For example, if you have simple game that just loads and plays without additional server calls inside the flex game.
If you wanted to protect your app you could have a basic "phone home" process during the startup sequence that makes a very simple server call to your website. It doesn't have to be anything super complicated, just require a round trip service call in the start up of your app. Perhaps check for a simple key or string stored in a variable on the PHP side, and don't let the flex app run unless that key is valid. You could hardcode the expected key inside the actionscript. Or perhaps have a basic logger that tracks how many times the app is launched and store the count in a database or something. The main thing is do not let the app completely launch until this request to the server has returned a valid result.
If you have this in place then the crossdomain.xml policies will kick in and if someone downloads your swf it shouldn't work because it will try to make a call from localhost to your server. Or if they steal your app and host it on their site it shouldn't work either.
The simplest solution il probably to check the value of
Application.application.loaderInfo.url
on application startup (for example in the applicationComplete event) and match it with your web site domain.
Do check out flash.System.Capabilities.playerType on LiveDocs as well.

Resources