Your application should be PCI-DSS-compliant. đ


If youâve ever had to write an app to process card payments, not like integrating PayPal, but like being PayPal. Youâve probably heard of PCI DSS.
Payment Card Industry Data Security Standard (PCI DSS) is an information security standard for organizations that handle branded credit cards from the major card schemes. - Wikipedia
In other words, itâs a giant checklist that says: âHey, if youâre going to store or process peopleâs money, maybe donât leave your database open to the world.â
Why Am I Even Writing This?
After working on a PCI DSSâcompliant app, I had a bit of an existential crisis and asked myself, âWhy shouldnât all apps follow PCI DSS secure coding practices?â
Believe me, PCI DSS is not as terrifying as it sounds. Compliance and privacy folks have a way of making every simple process sound enormous to feel good about themselves. Want to have a stressful day? Listen to them talk about PIA, DPIA, DSAR, or ROPA.
Not to oversimplify things, compliance can be painful. But if it helps protect your data and keeps you from ending up on âHave I Been Pwnedâ. Isnât it kind of worth it?
Tips To Secure Coding
If youâre building a payment system or just trying to sleep better at night, here are some easy ways to secure coding that will bring you closer to PCI DSS compliance. Letâs dive in!
Subnets, NAT Gateways, and the Drama of Networking
If your appâs database is in a public subnet, Iâm going to need you to stop reading and fix that. Now!
Ensure you use private subnets for anything sensitive, then route their traffic through a NAT Gateway so they can reach the internet (for patches, updates, memes, etc.) without being directly exposed. Think of it as giving your app a VPN to access the world, but telling it not to talk to strangers.
For âThe Matrixâ lovers, the Matrix world is a private subnet, the real world is the public subnet, and the secure phone Neo and his friends use to travel between worlds is the NAT Gateway. They can go through, but the machines canât!
I love that reference, hope you do too. It took me a while. đ
Encrypt All the Things
Youâve heard this before. Youâll hear it again.
Encrypt at rest.
Encrypt in transit.
Encrypt logs, backups, and even environment variables if youâre feeling spicy.
For cloud services, managing encryption is easy peasy. You only have to enable them.
And please, Base64 is not an encryption. Itâs for people who lie to themselves. You know who you are. Sure, it has its uses, but security is not one of them.
Security Headers
Security headers are HTTP response headers that instruct the browser on how to handle security-related aspects of a website. They help you prevent attacks like Cross-Site Scripting (XSS), clickjacking, and man-in-the-middle attacks. Set It and Forget It
At the very least, add:
Strict-Transport-Security
X-Content-Type-Options
Content-Security-Policy
X-Frame-Options
Theyâre easy to configure in most frameworks and cloud services. Do it once, and youâre already better off than most.
Firewalls? Definitely Firewalls.
Route public requests to your application through a firewall. Itâs like putting a bouncer in front of your app.
Unlike the days of the boomers, where configuring a firewall is like assembling your furniture with instructions from Asgard. You might get it working, but at what cost? Present-day applications make this process a lot easier. Better if youâre on the cloud.
Cloud services like AWS WAF and Azure Firewall already come with pre-configured rules for common threats; you just have to switch them on, and they get to work.
Firewalls with minimum effort will help you stop known attack patterns, filter out bad IPs, and block that one guy still trying SQL injection from 2008.
Access Control
Your app isnât a public library. Donât give every service full access to everything just because itâs easier. Youâre not Oprah Winfrey: âYou get admin! You get admin! Everyone gets admin!â
Follow the âPrinciple of least privilegeâ, which means every user gets only what they absolutely need.
Try to rotate credentials and keys regularly and use roles over static keys when possible. Even cloud services prefer this. And they wrote the cloud.
Staging Is Not Production
Your staging environment should mirror production in structure, not in secrets.
Encrypt staging data too. Attackers donât care where they get data from.
Donât copy production secrets into staging.
Implement monitoring and WAF rules here as well.
Hackers love a staging environment with fewer alarms. Whatâs a better place to test their scripts?
Change Management
This is adulting for DevOps. PCI DSS requires you to have procedures to track changes in code, infrastructure, and security policies.
In simple terms, use Git, use Infrastructure-as-code (Serverless Framework, Terraform, AWS CDK, etc.), and set up alerts. You want to know when someone (maybe even you) decides to push trauma into production.
Logging Saves Lives
Logs are crucial. You hope to never need them, but if you do, you really need them. Keep secure and central logs for everything that matters:
Application logs: Log errors from applications and other important information to help you debug. Make sure not to log sensitive information.
Access logs: Log who did what and when.
Database logs: Catch slow queries, weird access patterns, and potential breaches.
Audit logs: Log changes to permissions, firewall rules, and code deployments. Tools like AWS CloudTrail, GuardDuty, and Config can help you with this.
Prefer ORMs
This is your first line of defense (and sanity). Forget raw SQL unless youâre a database wizard with a death wish. Use an ORM. Yes, you could parameterize your raw SQL and improve security; however, thereâs still a large chance that future you or your colleague will forget to parameterize a query properly, and just like that, youâre cooked.
ORMs abstract your database interactions, making code easier to maintain and less prone to injection attacks. Most modern ORMs parameterize queries out of the box. That means fewer chances to accidentally DROP TABLE users;
during a late-night commit.
In Conclusion
Now, seriously, was it that deep? Itâs a long list, but Iâm sure itâs filled with things youâre already doing. Just a few adjustments here and there, and youâre compliant!
Compliance is annoying, but so is a data breach. PCI DSS might feel like a giant list of âNo, you canâtâ but itâs just trying to keep you and your customers safe. On cloud platforms like AWS, Azure, and GCP, thereâs no excuse not to follow these best practices. Youâve got the tools, youâve got the docs, and now youâve got a very persuasive blog post.
Stay safe. Stay compliant. And for the love of all that is good, donât store unencrypted card numbers in a database column called card_number
.
Subscribe to my newsletter
Read articles from Victor Anuebunwa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
