Encrypt Apache-Tomcat database connection

Introduction

Sensitive information for Java applications is commonly placed in XML file context.xml/server.xml, which is required by web application at runtime. This config file has sensitive information for making connection to databases or SMTP server, API keys used within the application or for connecting internal/external web services. This sensitive information like database name, port, username, and password/other information has to be encrypted from being exposed to everyone.

In case of using Apache Tomcat webserver, Tomcat’s JNDI connections are defined within XML configuration files server.xml or context.xml within either Tomcat’s global configuration or within the deployed web application. Tomcat’s use of XML for connection definition potentially exposes the password for these connections as plain text. While these files should be on a server where access to these configuration files is secured and monitored, passwords in plain text may be a challenge for all environments.

Apache Configuration Container

Apache Tomcat Servlet/JSP container’s connection pull configuration via JNDI (Java Naming and Directory Interface ) resources. The connection pool we will look at is javax.sql.DataSource, which is a JDBC API for getting a connection instance to a database.

javax.sql.DataSource is a factory for getting connections to different physical data sources. javax.sql.DataSource interface is registered with the naming service based on JNDI API. A data source driver allows accessed to the database via DataSource interface. A DataSource object is looked up in the context based on registered through JNDI Resource. The connection to the data source, such as database is attempted when javax.sql.DataSource‘s getConnection() method is called.

JDBC API acts as an interface between Java applications and database systems allowing the same Java code base to be used with different database systems.

To encrypt passwords in context.xml we will need to create custom factory based on AES encryption and specify the factory in context.xml.

Architecture to Encrypt password using custom factory

We will create a custom factory based on Advanced Encryption Standard(AES) encryption  algorithm, which will encrypt any sensitive information stored in Context.xml. Apache Tomcat at runtime is cable of decrypting the sensitive information stored in Context.xml with custom factory to run web applications.

Below shows the complete process of encryption and decryption of Context.xml.

Tomcat-Encryptionprocess

Create Custom Data source Factory & Encrypt File

Here are the steps to encrypt Context.xml file.

  1. Simple config file
    <Context>
    <Resource auth="Container" 
    driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" maxActive="100" 
    maxIdle="10" minEvictableIdleTimeMillis="60000"  maxWait="-1"
    name="DBDataSource" password="keepitsecret26" type="javax.sql.DataSource"
    poolPreparedStatements="true" maxOpenPreparedStatements="100"
    url="jdbc:sqlserver://nycr-dmzsqlserver:2433;databaseName=SENSITIVEPRODDB;
    integratedSecurity=true" username="whatsupuser" validationQuery="SELECT 1"/>
    </Context>
  1. Create custom encryption factory using AES encryption. 
  1. Create/generate cityofny.jar from step2. or download from here 
  1. Generate new encrypted password using custom data source factory from step3. 
  1. Append Context.xml file with Custom Data Source Factory and update password with encrypted value. 
<Context>
  <Resource auth="Container" factory="com.secure.hroit.EncryptedDataSourceFactory"
   driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" maxActive="100"
   maxIdle="10" minEvictableIdleTimeMillis="60000" maxWait="-1" name="DBDataSource"
   password="c24d8b7c07fe2bb07e4941912968baaf00e60f8170bc365ea06a428afe6a558"
   type="javax.sql.DataSource" poolPreparedStatements="true" 
   maxOpenPreparedStatements="100" url="jdbc:sqlserver://nycr-dmzsqlserver:2433;
   databaseName=SENSITIVEPRODDB;integratedSecurity=true" username="whatsupuser"
   validationQuery="SELECT 1" />
</Context>

Steps to Encrypt Context.xml file

Jar file is available for download from here.

1. Copy the cityofny.jar to this Tomcat instalation diretory. For example C:\Program          Files\Apache Software Foundation\Tomcat 7.0\lib.

  1. Run below java command to get encrypted password using jar created above.

For example, C:\Program Files\Apache Software Foundation\Tomcat 7.0\lib>java -jar         newyorkcity.jar mysecretpassword

  1. Above command will output the password similar to this.

mysecretpassword:      c24d8b7c07fe2bb07e4941912968baaf00e60f8170bc365ea06a428afe6a558

  1. Copy the password and replace it in Context.xml file in Tomcat. Restart Tomcat webserver for changes to take effect.

References:

https://examples.javacodegeeks.com/enterprise-java/tomcat/tomcat-connection-pool-configuration-example/

http://www.jdev.it/encrypting-passwords-in-tomcat/

 

Encrypt Decrypt IIS Web.config

Introduction

Sensitive information for ASP.NET applications is commonly placed in XML file web.config, which is required to by web application at runtime. This config file has sensitive information for making connection to databases or SMTP server, API keys used within the application or for connecting internal/external web services. This sensitive information like database name, port, username, and password/other information has to be encrypted from being exposed to everyone.

As Web.config may contain sensitive data, it is important the contents of Web.config kept safe and hidden from unauthorized users. By default, any HTTP request to a file with the .config extension is handled by the ASP.NET engine, which returns page not served error. However, what if an attacker is able to exploit to get your Web.config file and he can get into other web services or database using the sensitive information stored in the Web.config?

Configuration provider

ASP.NET includes a protected configuration system for encrypting and decrypting configuration information. This includes methods in the .NET Framework that can be used to pro-grammatically encrypt or decrypt configuration information. The protected configuration system uses the provider model, which allows developers to choose what cryptographic implementation is used.

The .NET Framework ships with two protected configuration providers:

Encrypting Sensitive data

We will create a custom data provider based on RSAProtectedConfigurationProvider, which will encrypt any sensitive information stored in Web.config. IIS web server at runtime is cable of decrypting the sensitive information stored in Web.config to run web applications.

Below shows the complete process of encryption and decryption of Web.config.
EncryptionProcess

Steps to Encrypt Config File

Here are the steps to encrypt config file.

  1. Take web.config file
  1. Create custom config provider using RSAProtectedConfigurationProvider 
  1. Appended Web.config file with Custom Data Provider. 
  1. Encrypt Web.config file using Custom Data Provider 

All these steps are achieved using the EncryptConfigs tool

Step1

Step2

Step3

Step4

Note: Delete button is provided to delete created custom provider if its not required.

 Download Encryption Tool.

 

Remove All Permission for a Folder

function Remove-All-Permissions {
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$Path
)
$acl = Get-Acl $Path
$isProtected = $true
$preserveInheritance = $false
$acl.SetAccessRuleProtection($isProtected, $preserveInheritance)
Set-Acl -Path $Path -AclObject $acl
$allusers = (Get-Acl $Path).Access
foreach($val in $allusers)
{
Write-Host $val.IdentityReference.Value ” ” $val.FileSystemRights
Set-TargetResource -Path $Path -Account $val.IdentityReference.Value -Rights $val.FileSystemRights -Ensure “Absent”
}
}
function Set-TargetResource {
param
(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$Path,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String]$Account,
[Parameter()]
[ValidateNotNullOrEmpty()]
[String]$Rights,
[Parameter()]
[ValidateSet(“Present”, “Absent”)]
[String]$Ensure = “Present”,
[Parameter()]
[ValidateSet(“Allow”, “Deny”)]
[String]$Access = “Allow”,
[Parameter()]
[Bool]$NoInherit = $false
)
$InheritFlag = if($NoInherit){ “None” }else{ “ContainerInherit, ObjectInherit” }
$DesiredRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Account, $Rights, $InheritFlag, “None”, $Access)
$CurrentACL = (Get-Item $Path).GetAccessControl(“Access”)
if($Ensure -eq “Present”)
{
$CurrentACL.AddAccessRule($DesiredRule)
Set-Acl $Path $CurrentACL
}
else
{
$CurrentRules = $CurrentACL.GetAccessRules($true, $false, [System.Security.Principal.NTAccount])
$Match = $CurrentRules |?{ ($DesiredRule.IdentityReference -eq $_.IdentityReference) -and
( $DesiredRule.FileSystemRights -eq $_.FileSystemRights) -and
( $DesiredRule.AccessControlType -eq $_.AccessControlType) -and
( $DesiredRule.InheritanceFlags -eq $_.InheritanceFlags )}
$Match | % {[void]$CurrentACL.RemoveAccessRule($_)}
Set-Acl $Path $CurrentACL
}
}
Remove-All-Permissions “C:\mytestfolder”

Quick Firewall Port Status

Quick way to check the ports open in a windows machine…netstat -a

Powershell script to check list of ports open on windows machine

<#
.NOTES
===========================================================================
Created on: 12/03/2015 11:00 AM
Created by: Pramod S Kumar 
Filename: GetFirewallStatus.ps1
===========================================================================
.DESCRIPTION
Checks firewall ports based on environment
.Usage: .\GetFirewallStatus.ps1 -CSVFile “ListofPorts.csv”
#>
param (
[string]$CSVFile = $null
)
function Check-FirewallState
{
[CmdletBinding()]
param
(
[Parameter(Position = 1, Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$CsvFileName
)
$CsvObject = Import-Csv $CsvFileName
$OutArray = @()
foreach($line in $CsvObject)
{
$RemoteServer = $($line.’IP Address’)
$Port = $($line.’Port Number’)
if (![string]::IsNullOrEmpty($RemoteServer) -and ![string]::IsNullOrEmpty($Port))
{
$myobj = “” | Select “Hostname”,”Port”,”Status”
$myobj.Hostname = $RemoteServer
$myobj.Port = $Port
Try
{
$tcp = New-Object System.Net.Sockets.TcpClient
Write-Host “Connecting to “$RemoteServer”:”$Port” (TCP)..”;
$myobj.Status = “Open”
$tcp.Connect($RemoteServer, $Port);
Write-Host “Connection successful” -ForegroundColor Green;
}
Catch
{
Write-Host “Connection failed” -ForegroundColor Red;
$myobj.Status = “Closed”
}
Finally
{
$tcp.Dispose();
}
$OutArray += $myobj
$myobj = $null
}
}
$OutArray | export-csv “PortStatus.csv”
}
Check-FirewallState $CSVFile

Above script takes input from csv file(listofports.csv) in below format and creates output file portstatus.csv. Script can be downloaded here.

Excelsheet
Connection