We regularly receive requests to help with Formidable Forms projects where the requirements include storing either credit card or ACH details in the WordPress database. While we love working on any Formidable Forms projects for our clients, we believe it's incumbent upon us to educate and inform you of the risks and potential liabilities involved with doing so.
Because of regulatory compliance specifications, it is strongly recommended not to store these data elements in your website's database. The legal liability that accompanies doing so can be significant. We recommend using a 3rd-party PCI compliant payment processor instead. However, if you can't avoid it, the data elements you are permitted to save should at least be encrypted. If a breach occurs, the thieves won't be able to view the data in plain text.
In this article, we'll explain:
- What is PCI/ACH
- Strong Cryptography
- Formidable Pro Credit Card Field
- Encrypt/decrypt Data
- Use with Formidable Forms
- Demo Form Ajax OpenSSL
- Final Thoughts
What is PCI/ACH?
Payment Card Industry
The Payment Card Industry Security Standards Council (PCI SSC), comprised of Visa, Mastercard, American Express, Discover and JCB, is in charge of establishing minimum safety standards for how credit card payment information is captured, sent, processed, and stored.
Payment Card Industry (PCI) compliance is a set of guidelines that govern data security across a broad range of credit and debit card payments. Remaining compliant with these guidelines is mandatory for every business that captures credit card or ACH details in their online forms.
The Payment Card Industry has established four compliance levels based on your processing volume and how you choose to accept payments.
- Level 1: If you process more than 6 million transactions annually, regardless of how you accept those credit card payments (online, in person, over the phone, etc.)
- Level 2: If you process between 1 million and 6 million credit card transactions annually, regardless of how you accept those payments
- Level 3: If you process between 20,000 and 1 million e-commerce card-based transactions annually
- Level 4: If you process fewer than 20,000 e-commerce transactions annually or if you process up to 1 million offline sales every year
Most small business merchants likely qualify for Level 4 PCI compliance, which has some of the simplest rules.
The PCI DSS (Payment Card Industry Data Security Standard) has 12 general requirements, organized in 6 groups, also known as control objectives. The goal of these objectives is to:
- Build and Maintain a Secure Network;
- Protect Cardholder Data;
- Maintain a Vulnerability Management Program;
- Implement Strong Access Control Measures;
- Regularly Monitor and Test Networks;
- Maintain an Information Security Policy;
You can download the complete PCI DSS documentation, which includes a thorough description of the PCI compliance requirements, from this URL.
Automated Clearing House
Automated Clearing House (ACH) is a government-regulated electronic network through which financial institutions can transmit funds back and forth. The process is similar to credit cards, except that senders and receivers use bank routing codes instead of traditional 16-digit credit card numbers.
Enabling ACH payments offers important advantages to businesses and customers alike:
- Businesses are able to save both time and money by accepting ACH payments. Cutting paper-based checks is a huge drain on limited resources.
- Customers benefit from the convenience that ACH payments offer. This is especially true for direct deposit payroll and any payments that require recurring billing.
Everyone benefits since ACH payments are environmentally friendly. Because all transactions happen electronically, there's no need for material resources like paper, postage, and ink cartridges.
However, before you can enable ACH payment information in your online forms, there are certain precautions you must take to protect both your business and your customers. The most important step requires building ACH functionality around PCI-compliant security standards. These are the same “safety” protocols used for credit card processing. But because ACH provides direct access to bank accounts, PCI-compliance is even more important.
You May Need to Move Your Site
If you decide to store PCI related data on your site, your entire platform may have to be moved to a PCI compliant host. For example, GoDaddy is a very popular website host. At this time, the only GoDaddy products that offer PCI compliance are Online Store and Quick Shopping Cart. While this may change in the future, if your site is not using these products, you have to move your site.
If your site has to move, our recommendation is SiteGround's GoGeek hosting plan that is PCI compliant and offers a safe and stable environment for online merchants and their businesses. Higher-end dedicated hosting solutions provided by SiteGround can also be made PCI compliant, if need be. Always check with your host first and ask about their support for PCI compliant environments before moving your site.
Victor Font Consulting Group, LLC is not a PCI QSA (Qualified Security Assessor). We encourage that an audit be conducted by a QSA to determine the exact requirements for storing PCI related data on your server based on your unique business needs.
The technical guidelines presented in the PCI SSC's PCI Data Storage Do’s and Don’ts requires, at a minimum, that the Primary Account Number (PAN) is rendered unreadable anywhere it is stored—including portable digital media, backup media, and in logs.
In addition, storing the card-validation code or value (three- or four-digit number printed on the front or back of a payment card used to validate card-not-present transactions) is prohibited.
Rendering the PAN unreadable means using Strong Cryptography to encrypt the data. Strong Cryptography is defined in the PCI SSC's Glossary of Terms, Abbreviations, and Acronyms as:
Cryptography based on industry-tested and accepted algorithms, along with strong key lengths and proper key-management practices. Cryptography is a method to protect data and includes both encryption (which is reversible) and hashing (which is not reversible, or “one way”). SHA-1 is an example of an industry-tested and accepted hashing algorithm. Examples of industry-tested and accepted standards and algorithms for encryption include AES (128 bits and higher), TDES (minimum double-length keys), RSA (1024 bits and higher), ECC (160 bits and higher), and ElGamal (1024 bits and higher).
Formidable Pro Credit Card Field
You may not be aware of this, but Formidable Pro has a built-in credit card field that you can just drag from the field list and drop on the form. It captures credit card number, expiration date, and CVC. The Credit Card field will automatically appear if you have the Stripe or Authorize.net AIM add-on active. If you have another way of processing payments, you can enable the credit card field by adding this line to your code:
While this field does just about everything right when it comes to storing or not storing data, it does not provide a method for encrypting data in the database.
This isn't the first time the subject of encrypting/decrypting Formidable Form fields has been discussed. There is a "Tips and Tricks" post from Eddiemoto on the Formidable Help Desk explaining his proof of concept for encrypting/decrypting fields related to the European Union's General Data Protection Regulation (GDPR).
As you read through Eddie's approach, his process uses the OpenSSL standard but requires installing and loading the cryptor library to make it all work. We believe this is an unnecessary extra step. OpenSSL functionality has been built into PHP since version 5.3.
OpenSSL is widely used in Internet web servers, serving a majority of all web sites. OpenSSL contains an open-source implementation of the SSL and TLS protocols. The core library, written in the C programming language, implements basic cryptographic functions and provides various utility functions.
Most hosts have the OpenSSL feature activated in their default PHP configurations. If you're not certain if your host has enabled OpenSSL or the functions we create in this tutorial produce OpenSSL related errors, run phpinfo() on your site. If OpenSSL is enabled, it will say so in the phpinfo() output. If OpenSSL is not enabled, ask your host to enable it. OpenSSL is required for the functions defined in this tutorial to work. If your host doesn't allow for OpenSSL functionality in their PHP configurations, find a better host
openssl_encrypt() & openssl_decrypt()
Our encrypt/decrypt functionality is built upon PHP's openssl_encrypt() and openssl_decrypt() functions. The prototypes for these functions are:
Both of these functions return strings; openssl_encrypt() returns the encrypted string and openssl_decrypt() returns the decrypted string. At a minimum, these functions require 5 parameters to do their jobs. The parameters are:
- $data—The plaintext message data to be encrypted or the encrypted message to be decrypted
- $method—The cipher method. For a list of available cipher methods, use openssl_get_cipher_methods()
- $key—The encryption/decryption key
- $options—a bitwise disjunction of the flags OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING. The default value is 0. Leave this at the default value.
- $iv—A non-NULL Initialization Vector. The default for this parameter is an empty string, however, leaving the value as an empty string produces an error.
The openssl_get_cipher_methods() function returns an array of 98 supported cipher methods. For this demonstration, we've chosen the AES-256-CBC method.
The Advanced Encryption Standard (AES) is considered among the top ciphers. In theory it's not crackable since the combinations of keys are massive. If you decide to implement the output of this tutorial on your site, you can choose any supported cipher method.
It's been estimated that a brute-force attack on a message encrypted with 256-bit AES would take even a supercomputer longer to break than the universe has been in existence.Source: https://www.zdnet.com/article/has-the-nsa-broken-ssl-tls-aes/
For this demonstration, we've chosen to define constants in wp-config.php for the $method, $key, $options, and $iv values.
To create what we're calling the FORMIDABLE_SALT or $key, we used the same process that we do when creating the WordPress Authentication Unique Keys and Salts. That is running the https://api.wordpress.org/secret-key/1.1/salt/ URL and copying any one of the results and renaming it FORMIDABLE_SALT.
The FORMIDABLE_METHOD is defined by any one of the values returned from openssl_get_cipher_methods().
FORMIDABLE_OPTIONS is 0.
Last, the FORMIDABLE_IV is a random string with a length that must match the length required by your chosen cipher method. How do we know the iv length required by the chosen cipher method? We use the openssl_cipher_iv_length($cipher) function to find out.
The openssl_cipher_iv_length() function receives the chosen cipher method as a parameter and returns an integer reporting the required length of the $iv string. In our case, the AES-256-CBC cipher method requires an $iv length that is 16 characters long. You can use any method you want to create the random string. In our case, we used the password tool in 1Password to create the 16-character string. If you choose a cipher method other than AES-256-CBC, you'll have to determine the required $iv string length by running the openssl_cipher_iv_length() function on your own.
Once you define these constants, save them someplace where you will never lose them. These constants are required for both the encrypt and decrypt functions. Both functions must use the same parameter values otherwise nothing will work. If you lose these constants, you will never be able to decrypt your data.
We placed the constants in wp-config.php. For security purposes, we regularly install wp-config.php in the directory above public_html so it is out of the reach of Apache and any hacking attempts that can come through the web. In order to hack wp-config.php with such a configuration, the cyber-criminal would have to gain access to the actual server and be able to traverse its directory structure.
In their most basic form, the encrypt/decrypt functions are:
Use with Formidable Forms
Encrypting Field Data
To encrypt field data before it is actually saved to the database, we have to hook into frm_pre_create_entry and frm_pre_update_entry. These hooks allow us to do something with the data that was entered in the form prior to the entry’s creation or before the form is updated. The example is:
Decrypting Field Data
To decrypt field data when it is retrieved from the database for editing, we have to hook into frm_setup_edit_fields_vars. This hook allows us to do change field values, options, and other field settings before editing an entry. There's no reason to hook into frm_setup_new_fields_vars because it's only triggered when an entry is created. There is no value to encrypt on an empty form. The example is:
To decrypt field data for information displayed in emails, Views, or anywhere else that Formidable shortcodes are accepted, we hook into frmpro_fields_replace_shortcodes. To make this work, include decrypt=1 as a parameter to any Formidable shortcode. When added to a shortcode, Formidable adds it to the $atts array which makes it available to our function. Here's the example:
Demo Form Ajax OpenSSL
This is a simple Formidable Form utilizing the OpenSSL process through Ajax. The code is a little different in that Ajax is called by jQuery and jQuery calls the PHP functions.
- Enter the String to Encrypt
- Click the Encrypt button.
- Click the Decrypt Button
- If everything works, Decrypted String is identical to String to Encrypt
The jQuery and PHP code for this form is packaged in a zip file. You can download it from this URL.
Ideally, we'd love to see the Strategy 11 team include this type of functionality in a future version of Formidable Pro. Until/when that may happen is anyone's guess.
If you want to implement this for yourself, you could refactor the code as a plugin, or better yet, a MU plugin. The creation of the constants could be added to a configuration screen.
While this article focuses on integrating encryption/decryption with Formidable Forms, the truth is, with a little refactoring this process can be used for any data elements stored in the WordPress database.
Cybersecurity is a critically important topic. With the rising sophistication of today's cyber-criminals, nobody's online presence is safe from intrusion. The best thing we can do is educate ourselves and learn how to protect our businesses, families, and loved ones from serious harm. Download our free Cybersecurity eBook and jump start your education.