
Authors: Matthew Hall, Brian Waskiewicz, and Mike Forgione
Threat intelligence feeds and other sensitive data pipelines found in many contexts make use various different Authentication methods to protect data when transferred or at rest.
Some examples of these methods are:
The wide range of authentication complicates the secure software development process. One must consider the TLP (Traffic Light Protocol) restrictions, cryptographic best practices (such as PCI or FIPS requirements), and system hardening (such as NIST recommendations), to create a secure solution.
The most secure methods for accessing sensitive data, such as HTTP Basic Authentication and TLS Client Certificates, or SSH infrastructure, require secure credential storage to allow automated access to a data pipeline.
Secure credential storage consists of:
When these requirements are met, it greatly complicates the process of credential exposure and/or exfiltration, or in the case of a hardware implementation, can potentially guarantee exfiltration is impossible.
Sadly, most popular software development reference sites, such as StackOverflow, Github projects, open-source code, programing language API guides, etc. recommend some or all of a series of common unsafe practices, which will increase the risk of compromise as well as making it difficult to certify for PCI and FIPS compliance:
setproctitle() after reading the credentials, but it isn't a complete guarantee since a patient adversary can still catch them in the clear early in the process's life, or by disrupting or slowing the process during launch.authorized_keys file format to restrict the purpose and scope of headless SSH keys to prevent misuse. This is explained in the sshd(8) man page section, AUTHORIZED_KEYS FILE FORMAT.sshd(8) man pageRunning software that relies upon unsafe code is a security risk and a liability risk, as well as a business risk. It also cannot be sold to the US Government and many highly-security-conscious organizations. Fortunately, the industry developed a small number of platform-independent techniques for secure credential storage to mitigate these risks:
libnss with nss-db and libsecmod: this is the only popular open-source multi-language multi-platform cryptography and SSL/TLS library with an integrated FIPS-compliant keystore. OpenSSL, GnuTLS and most other libraries do not offer much assistance with these requirements. Because of this libnss is widely used in browsers.PKCS#11 provider (includes support for NSS and smartcard / HSM): this is the gold standard for high-security operations in Java. This includes any of the following:PKCS#11 device to get a FIPS-certified solution.PKCS#12 cryptographic archive file format: this format is not necessarily as heavily-secured and feature-rich as the other formats, but still provides great protection and works in the widest range of environments, because it has been around the longest.Recently, we needed to access a data pipeline which used a PKCS#12 containing an SSL/TLS Client Certificate and Private Key, from inside of a Python application.
We decided to use pycurl because we had existing products that used it, so it was simpler than using NSS, and it provided sufficient security for the type of data pipeline we were building.
Fortunately, pycurl can be configured to access a PKCS#12 keystore with a passphrase protecting the Client Certificate and Private Key. However the configuration and troubleshooting process was somewhat difficult due to a usability bug in libcurl itself, which we fixed and released to the community:
curl pull request to improve PKCS#12 errors
When troubleshooting our code sample sample below, we found that three different failure points in the PKCS#12 load process used the same non-specific error message, unable to use client certificate (no key found or wrong pass phrase?). This made it difficult to determine the true cause of a failure in the PKCS#12 initialization process. In our patch we added separate messages for each, and logic to retrieve a more detailed error from inside OpenSSL itself for more detail.
This code sample loads a PKCS#12 file in pycurl, and uses the credentials to access a target URL:
import cStringIO import pycurl request = pycurl.Curl() response = cStringIO.StringIO() request.setopt(pycurl.URL, request_url) request.setopt(pycurl.SSLCERTTYPE, "P12") request.setopt(pycurl.SSLCERT, pkcs12_file_path) request.setopt(pycurl.SSLKEY, pkcs12_file_path) request.setopt(pycurl.SSLKEYPASSWD, pkcs12_file_passphrase) request.setopt(pycurl.WRITEFUNCTION, response.write) request.perform()
We encourage everyone to take a little time to think about the sensitive data in a system while it is in transit, in use, or at rest. We enjoy working with the security and technology industry to set good examples, and educate developers about safe ways to handle sensitive credentials. We will keep encouraging everyone to build data pipelines that are secure by default.
FEATURED RESOURCES

