Several years ago, we designed sodium_compat: a pure-PHP implementation of (most of) libsodium. It has since been installed over 60 million times, not counting WordPress.
Our goals with sodium_compat were as follows:
To repeat ourselves a bit, this was several years ago. The PHP community has evolved. WordPress now requires PHP 7.0 to function (although they do recommend 7.4). As of this writing, the oldest still-supported version of PHP is 8.2 (8.1 if you count "security fixes only"). We asked ourselves, and the /r/PHP subreddit, if anyone still even needs PHP 5 support in 2024.
The answer was a resounding, "No."
That's the background story, anyway. If you're a busy developer, the remainder of this post will be broken down into a Q&A format to explain what's changing, what's not changing, what you need to do, and whether you need to do anything.
Since our company's inception in 2015, we've sought to make the Internet more secure for everyone.
Up front, this required doing a lot of the sort of work that benefits society but most companies wouldn't invest time or money in:
So why did we?
We reasoned that, in the long term, simply doing important work that benefits everyone is cheaper than airtime when it comes to advertising a security consulting company.
(And we were right! Our clients have been keeping us very busy. Hence, the drop in update frequency for our company blog for the past few years.)
However, we didn't get a lot of practice with marketing or advertising, which means some of the important work we've done over the years went unnoticed. For example: Sigstore does 2/3 of what Gossamer does, but the Sigstore team hadn't heard about it until a recent Hacker News thread.
To correct this oversight, we thought it would be helpful to provide a recap of some of the projects we've worked on since our inception that are still active today, and most importantly, why they matter for the security of the Internet.
To assert that "There exist supply-chain security risks" in any software ecosystem doesn't require a formal analysis nor multiple experts to peer review such a notion. It's kind of a given, especially with recent tech news.
However, it's not a new problem. We were vocal about it in 2015, when it was common practice for software projects to tell you to install their widget by running curl http://some-domain | sh
in a terminal window. This specific anti-pattern had already been criticized widely by others since at least 2013, but we were more interested in proposing a general solution to secure code delivery.
The only things that have really changed in the intervening years are:
That last item might seem bold, but we've been laying the groundwork for elegantly solving these problems for the PHP ecosystem since our company's inception. We had briefly introduced our complete solution when we announced that WordPress would cryptographically sign its automatic updates in 2019. (If you'd like more depth into this subject, we've previously written about supply-chain security in 2017 and automatic security updates in 2016.)
Part of making an acceptable solution even possible required getting modern cryptography into PHP and writing a pure-PHP polyfill of ext/sodium for legacy versions of PHP. (These are just two of the things that we're known for in the PHP community.)
So with all that in mind, let's take a quick look at Gossamer, our proposal for securing the software supply-chain for the PHP ecosystem.
Last month, Thomas Ptacek wrote API Tokens: A Tedious Survey on the fly.io blog, which talks about all things API Token.
His post covered JWT, PASETO (our design), and a few other token formats. He went on to clarify, on Hacker News, that:
The one thing I'm not super comfortable about here is my PASETO take. My attitude going in was that PASETO has a lot of boosters and not a lot of critical takes. I can beat up on Macaroons because we're using them, and I'm going to follow up with a post about what our Macaroons like like. I'm not doing that with PASETO. So, like, I stand by it, but take it for what it's worth.
What was his take, exactly? Our succinct understanding of the criticisms laid out in the fly.io article are as follows:
Out of these criticisms, the first two are actionable and warrant further inspection, while the latter are Thomas's opinion.
When we designed PASETO, our goal was to provide an easy-to-use, secure-by-default, and simple protocol that solves the same sort of problems as JSON Web Tokens (except actually secure).
This resulted in two types of PASETO token being defined for each version of the protocol:
This solved the majority of use cases, but not all: If you wanted to use public-key encryption instead of symmetric-key encryption, you couldn't accomplish that with PASETO. Put flatly, there was no JWK-equivalent for PASETO.
With that in mind, today we'd like to announce the first PASETO extension:
Three years ago, we introduced PASETO to the Internet, as an alternative to the insecure JOSE standards.
PASETO was designed with the philosophy of avoiding in-band negotiation, as well as recognizing that any cryptography key should always be considered to be the raw key material alongside its parameter choices. To that end, PASETO was built with versioned protocols at its foundation (and each key could only be used with a given version and purpose).
Today, we announce the next iteration of the PASETO specification, which includes two new protocols (Version 3 and Version 4).
v3.local
) use AES-256-CTR + HMAC-SHA384 (Encrypt-then-MAC)v3.public
) use ECDSA over NIST P-384v4.local
) use XChaCha20 + BLAKE2b-MAC (Encrypt-then-MAC)
v4.public
) use Ed25519.Security teams will mostly be interested in the Rationale page in the PASETO Specification repository. Pay special attention to the section on ECDSA security and questions for security auditors.
Ristretto is a technique for constructing prime order elliptic curve groups with non-malleable encodings. It extends Mike Hamburg's Decaf approach to cofactor elimination to support cofactor-8 curves such as Curve25519.
Ristretto255 is Ristretto defined over Curve25519, which allows cryptographers to extend the Ed25519 signature scheme to support complex zero-knowledge proof protocols without having to deal with the cofactor.
(The cofactor in Ed25519 is what caused the multi-spend vulnerability in CryptoNote cryptocurrencies (n.b. Monero).)
Imagine that you want to build a brick wall.
However, instead of laying each brick deliberately and using mortar to assemble the desired structure, you are instead instructed to assemble a three-dimensional lattice of mortar, like so:
This might seem strange, so naturally you ask what the purpose is for such a design. You are told: "This will allow the inhabitants to hot-swap bricks whenever they need to. For example, if an influx of termites that can eat clay brick infest the area, they might want to switch to concrete bricks to protect their house."
Would you trust such a wall to support the weight of a roof?
Clearly not.
So why do we expect cryptography designed this way to be secure?
It's been more than eight years since Javascript Cryptography Considered Harmful was published.
It's just as true today as it was eight years ago that JavaScript cryptography in a web browser is dangerous. But the ecosystem itself has changed immensely in this time.
WordPress's core development team began a discussion recently about the challenges involved in enabling plugin/theme developers to manage their own keys. This led to a discussion about Project Gossamer and our designs for zero-authority public key infrastructure (za-PKI).
And then WordPress.org, being halfway across the bridge, decided to make a sharp left turn and discuss rolling back the Ed25519 signature for core updates in favor of "SSL with checksums".
I do want to reiterate that I want to see package signing come to fruition, so rolling back the current implementation is primarily about clearing the way to ensure it's done properly, rather than trying to rush a half-baked solution.
(Emphasis mine.)
This development was accompanied by a blog post with a confusing title ("SSL for auto updates"), for which the biggest takeaway seems to be: Nobody understands server-side HTTP requests.
If that's the case, to any WordPress freelancers in the audience: you'll want to read this post to distinguish yourself from the majority of your peers.
WordPress 3.7 was released on October 24, 2013 and introduced an automatic update mechanism to ensure security fixes would be automatically deployed on all WordPress sites, in an effort to prevent recently-patched vulnerabilities from being massively exploited in the wild. This is widely regarded by security experts as a good idea.
However, the WordPress automatic update feature had one glaring Achilles' heel: If a criminal or nation state were to hack into the WordPress update server, they could trigger a fake automatic update to infect WordPress sites with malware.
This isn't just a theoretical concern, it could have happened if not for WordFence's security researchers finding and disclosing an easy attack vector into their infrastructure.
WordPress 5.2 was released on May 7, 2019 and provides the first real layer of defense against a compromised update infrastructures: offline digital signatures.
Recommended reading: What's a digital signature?
A lot has been written about cryptography key lengths from academics (e.g. Lenstra's equation) and various standard committees (ECRYPT-CSA, Germany's BSI, America's NIST, etc.) over the years.
Despite the abundance of coverage on this material on the Internet, these resources lack the clarity that we look for when drafting recommendations for software developers and system administrators. Additionally, many of them are showing their age and desperately need to be brought up to speed with a modern understanding of real world cryptography.
Back in 2017, we outlined the fundamentals of searchable encryption with PHP and SQL. Shortly after, we implemented this design in a library we call CipherSweet.
Our initial design constraints were as follows:
Today, we'd like to talk about some of the challenges we've encountered, as well as some of the features that have landed in CipherSweet since its inception, and how we believe they are beneficial for the adoption of usable cryptography at scale.
If you're not familiar with cryptography terms, you may find this page useful.
Since our inception, we've typically published retrospective blog posts every year:
A recurring theme of these posts has been, "We have an ambitious plan to make the Internet more secure."
At the end of 2015 looking towards 2016, we wanted to emphasize "secure-by-default" as the best attitude towards security.
Our goal for 2017 was to get libsodium into the PHP core (which we did! The vote passed 37 to 0) and write a pure-PHP polyfill library we call sodium_compat.
Our goal in 2018 was to kickstart an ecosystem-wide clean-up effort to address the discoverability problem: It's much easier for new PHP developers to discover bad security advice than good security advice. We wanted to flip the script on this problem and make new developers learn tools and techniques that are, at a base, far more conducive to developing secure applications.
This was somehow even more ambitious than our 2017 goal, and unsurprisingly, we didn't have the same measure of success this time around. But the campaign is still young, and may take several years to play out in full, and we believe a recent announcement from another organization shines a light of hope on our efforts. More on that in a minute.
Today, we answer some reader questions about secure credential management, the benefits of ChaCha and BLAKE2 over AES and SHA2, and fault attacks on EdDSA.
Astute readers have noticed that our blog posts have decreased in frequency this year. We put a heavy emphasis on quality, not so much on quantity.
At the same time, we field a lot of questions on social media, where our answers (and, sometimes, the questions themselves) are difficult to locate, especially when people close or lock their accounts.
With both of these thoughts in mind, I asked my Twitter followers if they'd be interested in a Q&A-style blog series. I expected maybe a 55:45 split on yes/no responses, but the final tally was overwhelmingly "Yes".
So with that in mind, I'd like to introduce the pilot for our new series, Slice of PIE.
Earlier this year, the World Wide Web Consortium (W3C) and FIDO Alliance shared their latest drafts for a standard Web Authentication API called WebAuthn.
For context (present and historical): The current version (as of this writing) of the WebAuthn specification lives here, and the most up-to-date version can be found here.
Our security team took an interest to this proposal since WebAuthn would be used in conjunction hardware two-factor authentication devices. Hardware 2FA has proven to be far more resilient against phishing attacks than HOTP or TOTP (meanwhile, SMS-based 2FA is essentially security theater; avoid like the plague).
Despite the importance of WebAuthn to web security for the years to come, our analysis of the standard reveals a lot of concerns that almost any cryptographer should have been able to identify and remedy earlier in the design phase.
Regardless of whether this was a failure of the W3C and/or FIDO Alliance to enlist the aid of cryptography engineers, or of the cryptography community to be more proactive in preventing the deployment of error-prone cryptographic designs, there is only one path forward; and that is to fix the design of WebAuthn before it's set in stone.
Asymmetric cryptography (also known as public-key cryptography) is widely misunderstood.
Most non-cryptographers don't understand asymmetric cryptography at all due to the lack of a relatable, real world analogy they can reference.
Conversely, most cryptographers don't seem to understand how and why developers use asymmetric cryptography in their own software.
I believe solving both problems (first, assisting developers understand what asymmetric cryptography is and how it works; but also, ensuring cryptographers understand the business needs that lead to the inclusion of asymmetric cryptography in software) will lead to all-around better cryptography designs and non-catastrophic asymmetric cryptography deployments.
The shortest answer to any question about securely using RSA is: Don't.
Because there are much better cryptography choices available today, if you can avoid using RSA, don't use RSA. Then everything else in this document becomes not your problem.
Throughout this post, we assume at least a casual understanding of what RSA is, and the role of asymmetric cryptography in general.
If you do not meet these prerequisites, or experience any difficulty understanding the rest of this post, this is a good introduction to RSA and this talk by Colin Percival (slides) is a good follow-up. If you're more of a book learner, you can't go wrong with a copy of Serious Cryptography by Dr. Jean-Philippe Aumasson.
Paragon Initiative Enterprises (P.I.E.) got its name on March 14, 2015. How have things changed in three years?
This is a follow-up to our 2017 blog post that made the case for avoiding JSON Web Tokens (JWT) and its related standards.
Many developers responded to our post with the same question: "What should we use instead of JWT?" Today, I'm happy to announce a viable replacement.
Last month we published our guide to building secure PHP software in 2018. It provides clear and accessible guidance to writing secure PHP software. If you're a web developer, that page should serve as a great starting point for writing secure software going forward.
However, that guide only solves half the problem.
The other half is the abundance of outdated blog posts and PHP tutorials littered across the Internet that demonstrate bad security practices. And we'll need your help (yes, yours!) to clean up the ecosystem.
As the year 2018 approaches, technologists in general—and web developers in particular—must discard many of their old practices and beliefs about developing secure PHP applications. This is especially true for anyone who does not believe such a feat is even possible.
This guide should serve as a complement to the e-book, PHP: The Right Way, with a strong emphasis on security and not general PHP programmer topics (e.g. code style).
When an encryption scheme is said to be homomorphic, what that means is that if you perform some mathematical operation on the ciphertext, you affect the plaintext in a useful way once it's decrypted.
While this sounds neat, there are three major problems with current homomorphic encryption designs:
While research into solving the performance and distinguishability problems of homomorphic encryption schemes is ongoing, there has been very little attention given towards preventing chosen-ciphertext attacks.
If you're interested in homomorphic encryption because you want to be able to search encrypted database fields in a web application you're developing, see the linked article instead.
Last week, our security expert introduced Certainty, our CA-Cert automation library, which we designed to make disabled certificate validation an extinct vulnerability in the PHP ecosystem.
Most of our open source software projects have historically fallen into the local developer tools genre.
random_bytes()
/ random_int()
API without usability breaks.However, there has been an increasing need for security-oriented, self-hostable microservices. With that in mind, we'd like to introduce you to PIE-Hosted.com.
I won't mince words: There is an epidemic of PHP software that disables certificate validation when using cURL, and this is (in most cases) harmful.
Let's talk about what the dangers are, how to do it correctly, and a tool we built to make doing the right thing easier.
I generally don't like writing about current events, because the inherent ephemeral nature of the news means that your words become less meaningful with each passing day. As a professional, I find wasting other people's time in poor taste.
However, the topic of supply chain attacks has come up repeatedly in the recent months, so I'd like to take a moment to reflect on these incidents, as well as the work I've done through Paragon Initiative Enterprises (PIE for short) to be able to solve this problem at scale.
Should your software update itself automatically? YES!
If you aren't convinced, we've previously made the case for automatic software updates as a means of preventing yesterday's software vulnerabilities from being exploited today.
However, as our previous article on the subject notes, implementing automatic software updates requires a nontrivial amount of engineering effort in order to be secure.
Our company has been hard at work for the past few years to diminish the effort required to achieve secure automatic software updates in the PHP community. Most of our efforts are reproducible and/or relevant to any other programming stack, although PHP remains the first major programming language to decide to adopt modern cryptography in its standard library.
Let's explore how to use our existing work to build a secure automatic software update system, without having to do any of the heavy lifting.
If you're a business owner, every hour spent worrying about criminals breaking into your website and stealing your customer's financial information is an hour you're not making your business more profitable.
That's why we created Ward.
Six months ago, I wrote a blog post titled Let's Make 2017 the Year of Simply Secure PHP Cryptography, which at the time seemed ambitious and possibly erring on the side of idealism. The goals were as follows:
I'm happy to report that, halfway through 2017, both efforts have been successful.
"Blockchain" is one of the hottest technology industry buzz-words of 2017. A lot of time, money, and engineering talent is being invested into building blockchain technologies. Despite the name, blockchain has nothing to do with the Cipher Block Chaining mode of encrypting large messages with a block cipher; instead, it's used to refer to a specific type of ledger, and more specifically to crypto-currencies like Bitcoin and Zcash.
As a technology company that specializes in application security, applied cryptography, and code auditing, we get a lot of emails and questions at technology conferences that fit into this formula: "We have $problem
. Can we use blockchain to solve that?" Sometimes the answer is "Yes", but in most cases a blockchain is total overkill for the problem that needs to be solved.
With that in mind, we'd like to introduce our latest open source project, Chronicle, which may solve your problem without committing to a blockchain to solve inappopriate problems.
The most fundamental requirement for any website to be secure is to use HTTPS (formally defined as HTTP over TLS, and preferably TLS 1.2 or 1.3). However, HTTPS alone does not satisfy every company's security needs.
In the typical HTTPS usage, the server is authenticated to the client, but not vice-versa. (You can play with TLS client certificates, but they're too cumbersome for most software developers.)
Certificate authorities can behave abusively or get outright hacked.
The defense-in-depth strategy for untrusted CAs is public-key pinning, but for PHP developers, enforcing public-key pinning isn't straightforward (or always possible, depending on how old your software is).
What if we told you we've developed a PHP library that solves all of these problems for your APIs, that works with PSR-7 HTTP messages, carries minimal added complexity, and just released the source code on Github?
If you're not familiar with cryptography terminology, read this page first. It covers everything from terms (e.g. nonce) to concepts (e.g. public-key encryption).
Last Friday at Day Camp 4 Developers, I presented a talk titled Cooking with Sodium in PHP 7.2, which was largely live-demoing the various cryptography features provided by libsodium. One of the questions I was asked by attendees was about knowing which feature to use to solve specific problems. This is the sort of problem that I suspect many people run into, so here's a quick reference table followed by a detailed explanation.
In the table below, all encryption modes utilize authenticated encryption.
Libsodium Function | Type | Notes / Use Case |
---|---|---|
Libsodium Function | Type | Notes / Use Case |
crypto_pwhash | Password hashing | Secure password storage, key derivation from user input |
crypto_generichash | Cryptographic hash function | Collision- and preimage-resistant; replace MD5/SHA1/etc. |
crypto_shorthash | Short-input hash function | Hash tables, bloom filters, cache lookup keys |
crypto_auth | Symmetric authentication | Both parties can verify and/or forge messages |
crypto_sign | Asymmetric authentication | Digital signature (anyone can verify, only sender can sign) |
crypto_aead_* | Symmetric encryption | Shared-secret encryption with additional data |
crypto_secretbox | Symmetric encryption | Compatibility with NaCl, TweetNaCl, etc. |
crypto_box | Asymmetric encryption | Both sender and receiver can decrypt |
crypto_box_seal | Asymmetric encryption | Only receiver can decrypt; sender is anonymous |
It might never occur to most business owners or software developers to hire a security team to audit their software's source code, but if you're producing or consume a lot of boutique software, the benefits of a code audit are hard to pass up.
Update (2019): We've implemented the design this blog post builds up towards. Read the new blog post about our implementation here.
We get asked the same question a lot (or some remix of it).
This question shows up from time to time in open source encryption libraries' bug trackers. This was one of the "weird problems" covered in my talk at B-Sides Orlando (titled Building Defensible Solutions to Weird Problems), and we've previously dedicated a small section to it in one of our white papers.
The question is, How do we securely encrypt database fields but still use these fields in search queries?
Our secure solution is rather straightforward, but the path between most teams asking that question and discovering our straightforward solution is fraught with peril: bad designs, academic research projects, misleading marketing, and poor threat modeling.
If you're in a hurry, feel free to skip ahead to the solution.
Application security has a checklist problem.
There's an old article titled The Six Dumbest Ideas in Computer Security. When someone attempts to secure an application or a network using a checklist, they're committing the second fallacy in that list: "Enumerating Badness."
(Related: security through configuration rather than competent design is common in the PHP ecosystem.)
Until recently, a few checklists were given a pass because they were generally considered reputable among information security professionals. The reasons usually given vary from "At least this checklist isn't that bad" to "It helps bridge a gap between security teams and development teams". One such "christened checklist" was the infamous OWASP Top 10.
And then OWASP published their draft for the 2017 edition of the OWASP Top 10. The reactions and criticisms were equal parts appropriate and ferocious.
The addition of "A7. Insufficient Attack Protection" in the 2017 edition was enough to prompt a lot of information security professionals to decry the OWASP Top 10 project as a useful security tool. I'm arguing that this doesn't go far enough. It's time to face facts:
CMS Airship is a Free Software content management system (available on Github) that we introduced to the world last year.
We chose to build CMS Airship for two reasons:
Although we have tried for years (and will continue to try) to improve the security posture of other open source CMS platforms, we believe that truly democratized publishing is only possible if a secure-by-default option is available today.
How can we be certain that CMS Airship is secure?
The rest of this post is dedicated to answering this question in detail. There is one thing we want you to keep in mind as you read this blog: If you're an Airship user, these are problems you'll likely never have to solve. The work is all done for you.
If you're not an Airship user, you may want to take notes and contrast our solutions with the platform you develop for.
Update (March 2018): Paseto is a Secure Alternative to the JOSE Standards (JWT, etc.)
If you've already decided to implement Javascript Object Signing and Encryption (JOSE), whether you want JSON Web Tokens, JSON Web Encryption (JWE), or JSON Web Signatures (JWS), you should question this decision. You're probably making a mistake.
Everything in this blog post was written to be accurate as of RFC 7519, RFC 7515, and RFC 7516. It's possible that new RFCs in the future could supersede the flaws detailed within.
If you're not already familiar with basic cryptography terms and concepts, start here. Hyperlinks are provided throughout the article to explain things in detail, for the sake of brevity.
Token-based authentication schemes (i.e. how you would typically implement "remember me" cookies or password reset URLs) typically suffer from a design constraint can leave applications vulnerable to timing attacks.
Fortunately, our team has identified a simple and effective mitigation strategy we call split tokens, which you should strongly consider adopting anywhere your software uses token-based authentication.
While working on sodium_compat, our pure-PHP implementation of libsodium, it has come to our attention that a lot of the engineering decisions we've made to minimize the risk of side-channels aren't well-known outside of our development team. In the interest of transparency, as well as promoting a better understanding among the PHP developer community, we'd like to take this opportunity to document our methods.
Important: Because sodium_compat has not been audited yet, this should not be considered exhaustive. There may be additional steps that are necessary for producing secure cryptography code in PHP.
This page should be considered supplementary to the existing rules for programming cryptography code in C.
It was the year 2017. The last remnant of the PHP 5 series was demoted into security fixes only status. Soon it was to be retired to the dustbin of technological history; its purpose spent. The world was largely moving towards supporting PHP 7 exclusively. Discussion towards improving the language and cleaning up the existing software ecosystem was ongoing.
And then, in one fell swoop, all of this great progress gets discarded because someone decided to regurgitate ancient PHP 5.1-era advice about LAMP stack hardening.
There have been countless examples posted in various places (Reddit, Hacker News, Twitter, Facebook, Slashdot, and even LinkedIn group discussions), and while a handful occasionally contain one or two tips that might be beneficial towards securing your PHP applications, almost all of the advice they contain is either wrong, a huge waste of time, downright silly, or all of above.
As part of a team that specializes in application security (in particular: securing PHP applications), I feel it's high time someone cleared the air about this advice.
Did you know that PHP powers more than 80% of websites on the Internet? (Currently reported to be 82.4%, but that figure changes over time.)
Despite its impressive market share, the PHP community hasn't historically received a great deal of support from the computer security industry. In particular, your options for public key encryption in PHP are both limited and insecure-by-default out-of-the-box. Your public key signature options aren't much better.
Our company recognizes the importance of securing software written in PHP to the Internet at large. For instance, if an attacker were to compromise WordPress's automatic update server, they could take control of more than 27% of websites in an instant. It's hard to estimate the DDoS bandwidth available to a botnet of that magnitude, but a back-of-the-envelope calculation yields lots. At the very least, it would be more than most (if not all) networks could mitigate today.
Fortunately, we do have a plan to prevent such disasters from ever happening.
Last year, our security team identified CVE-2015-7503 a.k.a. ZF2015-10, a vulnerability in the RSA feature of Zend Framework's cryptography library.
The actual vulnerability (a padding oracle attack against RSA encryption that uses PKCS1v1.5 padding) was originally published in 1998 by Daniel Bleichenbacher. This padding oracle vulnerability allows an attacker to take an encrypted message, and repeatedly send altered ciphertexts to the server (each time looking for some indication of a padding error), and consequently decrypt the original message.
One might hope that any vulnerability (that has been known for over sixteen years) which allows attackers to decrypt arbitrary encrypted messages would be widely known by developers and/or mitigated out-of-the-box by all of the available tooling.
Sadly, when we look at PHP software (both open source and proprietary), we still uncover application-layer cryptography protocols written in 2016 that are vulnerable to this attack (and others we'll cover below).
We believe there are two primary forces at work here:
As you may be aware by now, in addition to our professional security consulting services, we're developing a secure-by-default content management system called CMS Airship. CMS Airship is a Free Software product (though we do sell commercial licenses if you'd like to use Airship in non-free software; get in touch).
If you weren't aware, these articles will bring you up to speed:
Let's not mince words: Rolling your own cryptography is almost always a mistake. Almost always, the correct answer is DON'T DO IT.
If you roll your own crypto, you do so at your own risk.
If you're writing your own cryptography code for educational purposes or you're a cryptographer, you can sometimes get away with discarding this advice. However, most developers simply ignore it and proceed to design their own broken cryptography protocols.
If you're going to throw all caution to the wind, be prepared for disastrous outcomes. If proceeding down this perilous path is necessary, it's important to take every precaution possible.
Most of the software security vulnerabilities known to man are preventable by careful development practices. For example, SQL injection can be prevented by separating the user-provided data from the SQL query. We've covered quite a few of these topics before. Read A Gentle Introduction to Application Security if you're not familiar with web application security.
However, even if you're trying to do everything right, eventually we all make mistakes and ship exploitable software.
Once a security bug exists in your customer's networks, preventing a security breach involves a lot of moving parts, but most importantly:
Consider the timeline below:
The time between point 0 and point 1 might be years. For the Linux kernel, it's about 5 years on average. There are a lot of ways to reduce this number, and most of them involve automated testing and manual code review from security experts.
The time between point 1 and point 2 might be weeks or months. Our average vulnerability identified-to-fixed time window is less than 24 hours. Most organizations do not enjoy the same agility or expertise.
Most development teams have no control over the time between points 2 and 3 -- the amount of time it take for the fix to be applied (and the vulnerability to be neutralized) after the update is available.
By making updates manual rather than automatic, you're forcing your customers to take all the responsibility for making sure that your mistakes don't hurt their business. Only a very small minority of your customers might prefer the responsibility of verifying and applying each update themselves.
By and large, most people do not have the security awareness, time management, and discipline to undertake this responsibility 24/7/365.
Automatic security updates reduce the interval between points 2 and 3 from possibly infinite to nearly zero. That's clearly a meaningful improvement over manual patch management.
The problem of outdated software is well-studied by the information security industry. According to Verizon's 2015 Data Breach Investigations Report (PDF), for example, when a software vulnerability was used...
99.9% of the exploited vulnerabilities were compromised more than a year after the CVE was published.
Earlier this year, Wombat Security reflected on similar studies in an article titled Out-of-Date Software and Plug-ins Compound End-User Risk. An article on Help Net Security examines findings from F-Secure and echoes the problem of companies relying on out-dated software and putting their users at risk.
The danger of outdated software is supported by both the data and by simple logic: If criminals are aware of a specific vulnerability in a software product, it doesn't matter that the vendor published a security patch if most of the companies that use their product will remain vulnerable when criminals want to exploit it.
Although the current trend of the security industry is funneling users towards password managing software (and two-factor authentication), they're not ubiquitous and inevitably some of your users will forget their passwords.
How can we design a system that allows users to recover access to their account, securely, without administrator intervention?
We've previously covered user authentication in detail, including using PHP's built-in session management effectively and how to safely store your users' passwords.
Our previous post included a checklist comparing CMS Airship (our Free Software CMS platform designed with security in mind) to the three most popular content management systems currently in use on the Internet:
The checklist compared out-of-the-box security properties (features or design decisions that affect the security of the software and any extensions developed for it) rather than what's possible with community-provided extensions. Tooltips were also provided on individual cells to clear up any confusion on why we did or did not award a checkmark to a given project for a given security property.
Since the previous post was published, several technologists asked us to explain the individual security deficits of other PHP content management systems in detail. Some of these are straightforward (e.g. WordPress doesn't offer encryption, so there's nothing to analyze), but others require a careful eye for code auditing. Familiarity with PHP security is also greatly beneficial to understanding, although we will attempt to explain each item in detail.
We're going to set Airship aside for the remainder of this post. All you need to know is Airship met all of the criteria for a secure-by-default content management system. If you'd like to learn more about Airship's security features, we've covered this in detail here.
All three content management systems score points for being Free Software, released under the GNU Public License. Consequently, their source code is available for their users to inspect and analyze. This offers three benefits:
For example, last year, we made WordPress's wp_rand()
function cryptographically secure as of WordPress 4.4.0. This would not have been possible without the first two properties.
In addition to being open source, all three provide a security mechanism to mitigate Cross-Site Request Forgery attacks. We didn't include whether or not plugins/extensions fail to utilize the CSRF mitigation feature in our analysis. If you're using a third-party plugin, don't assume that CSRF vulnerabilities can't or won't happen to your application just because there's a mitigation feature in the core.
Your golden ticket to managing all of your business's online content—blogs, photos, infographics, artwork, multimedia, and more—is now available.
We are excited and proud to announce the availability of CMS Airship on the Amazon Web Services (AWS) Marketplace.
The past few years have brought more products and services that offer cryptography features as a selling point. More security is good, but a lot of products and services seem to ship before a cryptography expert has a chance to correct the marketing copy. Even worse: Often, these misconceptions corrupt the design and implementation of the feature itself.
Cryptography is a difficult subject for non-experts to understand, as is. Muddying the waters further is bad for everyone. If you're looking for a primer on basic cryptography terms and concepts, see the linked blog post instead.
This list is not exhaustive. This blog post will be updated and the list will be expanded as time goes on.
Caddy is a modern open source HTTP/2 webserver written in Go. One of its most attractive features over other webservers (Apache, nginx, lighttpd, etc.) is that Caddy integrates with the free LetsEncrypt certificate authority to ensure all of your websites support HTTPS, out of the box.
(Caveat: localhost
and IP address virtual hosts are excluded from this automatic HTTPS, which also makes Caddy suitable for local development environments.)
What follows is a step-by-step guide for getting the latest version of Caddy (0.8.3) set up on a freshly installed Debian Linux 8.5 (Jessie) server. Please note that this was written on July 17, 2016; if you are reading this in the distant future, some of the steps may be incorrect. (In all likelihood, it will become easier.)
It was the year 2016. A business owner just had a great idea to expand their reach in the marketplace, and they needed to build a web application to pull it off. After a bit of market research, they decide the best course of action is to hire PHP programmers to build their vision.
Let's say you're a PHP programmer. A few days later, you find yourself employed at the company to make this vision happen. As you're sitting at the desk reviewing the wireframes that were agreed upon, the news on TV says something that catches your ear. You turn the volume up and learn that another company got hacked, all their customers' data was compromised, and it's just a mess all around.
You look back at your wireframes and wonder, "If it were to happen to this project, how would it fare?" How would you even begin to answer this question?
We're excited to announce that the first official release of CMS Airship is now available to download and install.
For anyone who hasn't been following along with our development work over the past few months, CMS Airship is a secure PHP CMS developed by Paragon Initiative Enterprises.
CMS Airship utilizes strong side-channel resistant cryptography, solves the problem of secure code delivery, and provides a list of security benefits other PHP projects can't match.
PHP CMS Out-of-the-Box Security Comparison Chart | |||||
---|---|---|---|---|---|
Security Feature | CMS Airship | WordPress | Drupal | Joomla! | Notes |
Note: A detailed technical breakdown of the security of the other CMS platforms is available. | |||||
Automatic Updates | The automatic updates you receive are secure against forgery even if our update server is compromised. | ||||
Prepared Statements | For preventing SQL Injection vulnerabilities. | ||||
CSRF Protection Everywhere | Plugins notwithstanding. | ||||
Context-Aware Output Escaping | Escapes on input |
For preventing cross-site scripting vulnerabilities. | |||
Content Security Policy | CMS Airship lets you manage CSP and HPKP headers through a web interface. | ||||
HTTP Public-Key-Pinning | |||||
Password Hashing | Argon2i |
Salted MD5 |
SHA512Crypt |
bcrypt |
Read more about how to safely store users' passwords and why Argon2 is the best choice. |
Two-Factor Authentication | |||||
Secure "Remember Me" Checkboxes | We outlined how to implement secure "remember me" checkboxes in PHP last year. | ||||
Login Brute-Force Resistance | |||||
Account Recovery: Opt Out | |||||
Account Recovery: GnuPG Encryption | CMS Airship allows users to provide a public key, which will be used to encrypt the outgoing account recovery emails. | ||||
Encryption | Halite |
N/A | N/A | Defuse v1* |
* As of v3.5.0; before, JCrypt was insecure. |
Minimum PHP Version | 7.0 |
5.2.4 |
5.5.9 |
5.3.10 |
Read more about why low minimum PHP version requirements are bad for security. |
Code Footprint | 56,078 |
490,115 |
978,569 |
851,019 |
Less code usually implies less room for bugs to slip in. This metric is useful for estimating the cost of a full audit. |
Free / Open Source |
Github |
Trac |
Git |
Github |
All four are released under GPL |
Security Feature | CMS Airship | WordPress | Drupal | Joomla! | Notes |
CMS Airship is free software available under the GNU Public License. We also sell commercial licenses for companies that desire to use CMS Airship to develop non-GPL software.
Earlier this year, we set out to implement an implementation of all the RFC 4648 character encoding functions (and their respective decoding functions) that was fully constant-time. Fortunately, a lot of the groundwork was already laid by Steve "Sc00bz" Thomas (of the DecryptoCat fame).
Our implementation is available on Github under paragonie/constant_time_encoding under the same license as Steve's code (MIT). Feel free to use it to enhance the security of your PHP projects, especially if you need Base32 encoding (which PHP doesn't provide but, for example, Google Authenticator requires).
It's also available via Composer:
composer require paragonie/constant_time_encoding
This post discusses a situation where encoding (which, despite widespread confusion, is a distinct concept from encryption) intersects with designing safe cryptography systems.
The "what and why" for generating secure random data in various programming languages has been adequately covered elsewhere. In a nutshell:
Use /dev/urandom instead of /dev/random.
What hasn't been adequately covered is the how. So without further ado, how to safely generate random numbers in...
As part of our efforts to reduce the friction to adopt secure authenticated secret-key encryption in the PHP community, our Chief Development Officer has been helping Taylor Hornby develop the next version of Defuse Security's PHP Encryption Library (henceforth, referred to as, "Defuse Crypto"). After a year of research and development, we're happy to announce that version 2 is now available for use in your PHP projects.
As always, if you're allowed to install PHP extensions, you should really consider using PECL libsodium instead of a PHP-land cryptography library. We've contributed documentation for libsodium in PHP.
If you cannot (for whatever reason) install PHP extensions, you're much better off using Defuse Crypto than attempting to write your own cryptography library.
Last year, we began developing Halite, a FOSS high-level wrapper for the PHP bindings to libsodium. We use Halite extensively in our own projects (including our upcoming CMS which has quite a few of its own innovative cryptography features baked-in).
As of version 2.1.0
, we are confident that Halite solves all of the application-layer cryptography problems that most PHP developers face; and it does so in three easy steps. (For transport-layer cryptography, you should still use TLS, of course.)
It's been over a month since we announced the first beta for our new open source project, CMS Airship. We've been hard at work since then, both at a code level and at a protocol design level, and we're nearing the release of the second beta (in semantic versioning: 0.2.0
). Before we continue the next steps, let's take a look at some of the cryptography features currently implemented. (Yes, we're using libsodium. No need to panic.)
Although some of what we cover will be complicated, most of these details will be abstracted away from end users. (Only engineers who want to get their feet wet in our protocol designs and implementations need to know this stuff.)
Let's dive in, shall we?
We built numerous free and open source projects over the past year. Since the primary goal of most of these projects is to improve the security of the PHP ecosystem, it's important for us to publicly formalize our release cycle and help answer the question, "Which version should we use and why?"
A frequent problem that developers encounter when building web applications in PHP is, "How should I represent this data structure as a string?" Two common examples include:
This seems like the sort of problem that you could expect would have pre-existing, straightforward solutions built into every major programming language that aren't accompanied by significant security risk. Sadly, this isn't the case.
From our active involvement in helping the open source community with security issues, we have identified a lot of deficits in the tools and frameworks available to the general public. We've helped where we can, but many times the best solution is incompatible with the project's other goals and many of the risks are poorly understood by developers (many of whom do not proclaim to be security experts).
As we have previously stated, our philosophy towards software development is:
Software should be secure by default. Tools should be simply, yet comprehensively, secure. Cryptography should be boring (PDF).
To further this initiative, we decided to build Airship. And today, we are launching the first public beta.
This is a frequently asked question that doesn't get the attention that it probably deserves, until now:
"How can I be sure that an incoming HTTP request was generated by a specific app?"
Some variant of this question comes up quite frequently. Every hyperlinked word in the preceding sentence is a distinct StackOverflow question from 2016 that is looking for the same solution.
Problem: You want to create a system whereby when a user authenticates to example.com
, they're also automatically logged in at foo.com
, bar.com
, baz.com
, and any other domains that you decide to add to the list at a later date.
Okay, great, that seems straightforward, except there's a complication: The Same Origin Policy prevents you from getting/setting cookies on domains other than the one you control. (Unless your users' browser foolishly disables the Same Origin Policy like Comodo did).
Let's narrow it down a little bit further: Unlike a situation where e.g. "Login with Facebook" would be appropriate, you control all of the domains. They just happen to be different, so the Same Origin Policy kicks in. For simplicity, feel free to assume they're on the same server and application codebase, but you have a multi-site architecture in place where some of the sites have a different domain name.
Let's work around this limitation with as few moving parts as possible.
Before we go any further, first make sure that OAuth2 or SAML don't already solve your exact use case (particularly if you want users' consent or you don't already control every domain in scope of single sign-on). Generally: follow the standards before blog posts.
That said, OAuth2 and SAML are trying to solve the 99% problem, instead of the 50% problem.
Is there a way to solve this problem, securely, without dealing with OAuth, SAML, LDAP, JSONP (or JavaScript in general)? It turns out: Yes.
We propose a simpler solution (which may NOT be right for you). Instead of mucking with HTTP headers and various types of tokens, or having to implement and secure a server-side XML parser (at minimum, with libxml_disable_entity_loader()
), we propose a solution that only requires:
Earlier this week, we published an article titled How to Safely Store Your Users' Passwords in 2016, which ended up on the front page of Hacker News for a full day. The feedback we received from the community was overwhelmingly constructive (and mostly positive), but many first-time readers had questions that, upon closer investigation, boiled down to a difference in philosophy rather than a simple communication error.
It occurred to me that we never officially formalized our philosophy anywhere, partly because I assumed nobody would be interested in reading about it, but also because we don't have a mono-culture; just because these are the principles that we hold doesn't mean anyone who joins our company as we grow needs to agree with our statements along with all of their nuances and immediate logical consequences. It's also not a mindset that we would ever seek to force upon others (especially clients).
However, I've decided to publish this today as a blog post for two reasons:
(Unlike most of our blog posts, there is little-to-no technical information ahead.)
If you are unfamiliar with cryptography concepts or the vocabulary it uses, or especially you are looking for guidance on "password encryption", please read this page first.
We've previously said that even security advice should carry an expiration date. So unlike most of our past blog posts, this page should be considered a living document: As requirements change and new attacks are discovered, we will update it accordingly. A changelog is at the end of the document.
Semantic point: Don't store the password, store a hash of the password. (Obligatory.)
In layman's terms, a backdoor is usually something a computer criminal leaves behind in your system after they've broken in the first time, to save them the trouble of breaking in the hard way in the future.
However, backdoors can be also be an intentional security vulnerability inserted into software projects with the hopes that doing so will give the attacker access to your system. See also: Juniper.
We're going to talk about the second type of backdoor.
There is some programming ahead, but if you can't read code just skip the code blocks and I'll explain what's going on afterwards.
It seems like 2015 just started the other day, and it's already approaching New Years' Eve. We've definitely been busy. Here's a brief list of some of the things we've been working on throughout the past year:
All our sploits have come
Here, but now they're gone
Servers don't fear the hacker
Nor do the cache, the stack or the heap
(We can use ASLR)
Come on newbie
(Don't fear the hacker)
...
As the Chief Development Officer for an application security and software development company that specializes in cryptography, of all things, it should come as no surprise that I, like many other talented people, am a hacker.
Usually when someone publicly subscribes to this label, they're quick to follow it up with an additional label, such as "white hat". This tendency has the unfortunate consequence that it conditions people (and especially, companies) to believe that there are two or three types of hackers in the world. It doesn't take much of a logical leap to go from this black/grey/white-hat trichotomy towards an adversarial stance against anyone who isn't a perfect match for their personal opinion of what a white-hat hacker should be.
Unfortunately, in my experience, many individuals and businesses sit on the adversarial end of the spectrum, and it makes life difficult for all parties involved in the discovery and disclosure of security vulnerabilities. The consequences of this position reach further than you might anticipate.
It is my hope that anyone who reads this post will realize that hostility towards hackers is mostly pointless and self-destructive and distracts you from very real threats.
The theory goes: You cannot have perfect security against all possible threats all the time for free. Usually, we expect our applications to incur a cost (usually in terms of CPU, memory, or electricity usage) in order to be secure. It seems logically correct that, if you need more security, your cost must therefore be higher.
Fortunately, this is not always true! Sometimes, given a choice between two solutions, the more secure option costs less than the insecure one.
If the words on this page are confusing, please read our guide to cryptography terms and concepts first.
Cryptography is not magic. Adding encryption to an application doesn't automatically make it secure against attackers (especially if you aren't authenticating your ciphertext). But if you do need it to satisfy a business need, conventional wisdom states that you almost certainly should not try to design your own cryptography. Instead, you should use an existing cryptography library.
Okay, great. So which PHP cryptography library should I use?
That depends on your exact requirements. Let's look at some good choices. (We won't cover any terrible choices.)
Modern cryptography protocols are more likely to be broken by side-channel information leaks than the persistent efforts of clever mathematicians.
One of the common cryptographic side-channels that developers should be aware of is how long a specific operation, such as a string comparison, takes to complete. Thus, they are called timing attacks.
A common place to find a timing attack vulnerability in a cryptography library is in the MAC validation logic.
if ($mac === hash_hmac('sha256', $message, $authKey)) {
return decrypt($message);
}
Timing attacks are possible because string comparison (usually implemented internally via memcmp()
) is optimized. For example: If you compare "apple" with "acorn", it will take measurably longer (on a nanosecond scale) than if you were to compare "apple" with "pecan", simply because the first character matches. This allows an attacker to slowly guess the first character, then the second, etc. of a valid Message Authentication Code for a forged message.
If, in the course of developing a web application for yourself or for a client, you ever find yourself writing code to allow users to upload files, you've just entered a whole new world of complexity where a simple mistake could result in remotely exploitable security vulnerabilities.
Fortunately, there is one simple design decision you can make that will stop the most common vulnerabilities associated with handling file uploads:
CSPRNG stands for Cryptographically Secure PseudoRandom Number Generator
At Paragon Initiative Enterprises, we believe that security should be the default state of affairs, not something only in the reach of security experts. That is why, in addition to the security consulting services we provide to help companies prevent expensive and embarrassing data breaches (which their customers would otherwise, most likely, be hurt by the most), our team spends a great deal of time working to improve the security of popular free and open source software.
Today, we're pleased to announce an exciting security enhancement coming to WordPress in the next major version.
Starting in 4.4.0,
wp_rand()
is cryptographically secure on all platforms.
Whether you're planning the development of a brand new application or trying to prevent legacy code from causing a costly data breach, if you're going to be writing PHP, where should you begin? That is the question we will attempt to answer, in detail.
The question of how to encrypt/decrypt a URL parameter (such as a username, email address, or primary key for a relational database) has become increasingly common, so we'd like to offer a simple and actionable solution for people who are asking the same (or a very similar) question.
Cryptography is a tricky field, especially for newcomers. To a security expert, it's immediately obvious why encrypting URL parameters is a bad idea. Let me explain why, and then I'll offer a superior alternative solution.
Use libsodium. Use libsodium. Use libsodium. Use libsodium. Use libsodium. Use libsodium. Use libsodium.
With the release date for PHP 7 drawing near, let's take a look at everything good and bad about developing cryptography features in PHP, what got fixed in PHP 7, and what remains to be fixed in a future version of PHP.
I have some grim news for the programmers in the audience. This news comes with a silver lining of course.
If you are a web developer (or are thinking about teaching yourself web programming), you probably don't think of yourself as a security engineer, or a white-hat/blue-team member of an information security assurance team. You might have considered security threats in the context of quality assurance before (e.g. validating input), but perhaps you're no expert on the subject.
But the second your code is deployed in production, your code is the front line of defense for that entire system and quite possibly the entire network. Logically, that means the software you produce must be made reasonably secure.
Accidentally concatenate a user-provided value with your query string, and someone can steal all your data and cripple your application in their wake. Forget to escape some data before displaying it, or escape it improperly, and suddenly your application has betrayed your users' trust in your client's brand and infected them with malware.
This might seem like a lot of pressure. A common argument I hear from other developers is, "Our clients don't pay us for security; they want it pretty, they want it feature-complete, and most importantly they want it done yesterday."
I'm not going to say you need to become an application security expert. That very notion betrays the (largely untapped) potential for rich diversity in the technology communities. But I will say this:
There's a ton of bad programming and security advice on the Internet. Some of the advice is bad because the author is misinformed, some because it emphasizes precision over clarity and most people wind up lost in the jargon.
If you feel that cryptography is a weird, complicated, and slightly intimidating subject for which your feelings might be best described as lukewarm (on a good day), we hope that by the time you finish reading this page, you will have a clear understanding of the terms and concepts people use when this topic comes up.
Warning: The example snippets on this page are for illustrative purposes. Don't use them in your projects. If you want a real-world example to reference, check out the snippets in our Chief Development Officer's StackOverflow answer instead.
Our previous blog post discussed securely generating a random integer or string in PHP. Since it was published, we began working on a free and open source library to expose PHP 7's CSPRNG functions in PHP 5 projects, which we call random_compat, with many great contributions from other PHP developers.
But also, we've discovered that the volume of bad information about random number generators offered to PHP developers is at least an order of magnitude higher than we anticipated. Since we've already done our homework on this subject, we'd like to provide some nifty helper functions that other PHP programmers are usually looking for.
Quick Answer: If you're developing a web application and your project needs a simple and safe solution for generating random integers or strings, just use random_bytes()
(PHP 7 only, or available through our random_compat library). Alternatively, Anthony Ferrara's RandomLib is a good choice.
<?php
$factory = new \RandomLib\Factory;
$generator = $factory->getMediumStrengthGenerator();
$password = $generator->generateString(26, 'abcdefghijklmnopqrstuvwxyz234567');
If you're using libsodium (which we highly recommend), you can use Sodium::randombytes_uniform()
like so:
function random_str($length, $keyspace = 'abcdefghijklmnopqrstuvwxyz234567')
{
$str = '';
$keysize = strlen($keyspace);
for ($i = 0; $i < $length; ++$i) {
$str .= $keyspace[\Sodium\randombytes_uniform($keysize)];
}
return $str;
}
Finally, the follow-up blog post about common uses for CSPRNGs contains some example functions.
Cross-Site Scripting (abbreviated as XSS) is a class of security vulnerability whereby an attacker manages to use a website to deliver a potentially malicious JavaScript payload to an end user.
XSS vulnerabilities are very common in web applications. They're a special case of code injection attack; except where SQL injection, local/remote file inclusion, and OS command injection target the server, XSS exclusively targets the users of a website.
There are two main varieties of XSS vulnerabilities we need to consider when planning our defenses:
Cross-Site Scripting vulnerabilities can be used by an attacker to accomplish a long list of potential nefarious goals, including:
Cross-Site Scripting represents an asymmetric in the security landscape. They're incredibly easy for attackers to exploit, but XSS mitigation can become a rabbit hole of complexity depending on your project's requirements.
Computer security is a topic rich with detail, depth, and nuance, but only some of us will become security experts in our lifetime. Owning or managing your own business shouldn't require you to burn countless hours learning about computer and network security (unless of course you run a security business).
There are simple, actionable ways to secure your online presence.
This is the first half of a two-part blog post series. Part one covers the theory, part two is an implementation.
Because there is no accepted industry standard algorithm for determining popularity, content publishers can afford to get creative in their assessments. Sometimes, however, these algorithms can be trivially exploitable by spammers to deliver low-quality content to high-traffic areas of a website (e.g. the front page of the website).
What follows is Paragon Initiative Enterprise's user-driven popularity algorithm that is resilient against fraudulent voting. There is no patent for this algorithm; instead, we release it to the public domain. We hope that, after being refined and studied, it can be put to use for the public good.
SQL Injection is a technique for taking control of a database query and often results in a compromise of confidentiality. In some cases (e.g. if SELECT 'evil code here' INTO OUTFILE '/var/www/reverse_shell.php'
succeeds) this can result in a complete server takeover.
Since code injection (which encompasses SQL, LDAP, OS Command, and XPath Injection techniques) has consistently remained on top of the OWASP Top Ten vulnerabilities, it's a popular topic for bloggers trying to get their feet wet in the application security field.
While more people sharing knowledge about application security is a good thing, unfortunately much of the advice circulating on the Internet (especially on ancient blog posts that rank high on search engines) is outdated, unintentionally misleading, and often dangerous.
Foreword: You probably should not be deploying your own cryptography to begin with, especially if you don't already understand that encryption is not authentication. For production systems, use PECL libsodium or defuse/php-encryption and save yourself the headache.
The rest of this post is intended for PHP developers who still want to write their own cryptography code, or already have.
Paragon Initiative Enterprises strives to help software developers around the world learn how to write code that is more secure, easier to maintain, and more efficient. In addition to publishing security-related blog posts, discovering security vulnerabilities in popular open source products, and performing formal code audits (our first report is coming soon), we actively pursue find newer and better ways to engage with computer programmers and IT administrators to share our team's knowledge on computer security.
So last month, we started to maintain a curated application security reading list on Github. It currently has over 390 stars and the number keeps increasing every day.
"Encryption is not authentication" is common wisdom among cryptography experts, but it is only rarely whispered among developers whom aren't also cryptography experts. This is unfortunate; a lot of design mistakes could be avoided if this information were more widely known and deeply understood. (These mistakes are painfully common in home-grown PHP cryptography classes and functions, as many of the posts on Crypto Fails demonstrates.)
The concept itself is not difficult, but there is a rich supply of detail and nuance to be found beneath the surface.
A common problem in web development is to implement user authentication and access controls, typically accomplished through sign-up and log-in forms. Though these systems are simple enough in theory, engineering one that lives up to application security standards is a daunting undertaking.
Without a great deal of care and sophistication, authentication systems can be as fragile as a cardboard lemonade stand in a category five hurricane. However, for everything that can go wrong, there is an effective (and often simple) way to achieve a higher level of security and resilience.
At a Glance
If you're confused about any of the terms used on this page, please feel free to consult our guide to cryptography terms and concepts first.
Most modern web applications use some form of session management system to link multiple HTTP requests to the same user. Every web application that has some concept of authentication relies on a session management system.
Typically, session management involves some sort of unique identifier stored in a cookie (e.g. PHPSESSID=usuheickmc37dbesu8a2oe3kns
), established by the server, and returned by the client on every subsequent request.
Anyone who can steal a user's session identifier can impersonate the user who legitimately possesses it. Let's make sure that doesn't happen.
As part of our efforts to better our community, both online and offline, we built a new tool for examining the differences between two .phar files. We call it Pharaoh, and we just released its code on Github under the MIT License.
Update (May 28, 2016): We've discontinued this project and incorporated its security wins into CMS Airship.
Will tomorrow bring costly and embarrassing data breaches? Or will it bring growth, success, and peace of mind?
Our team of technology consultants have extensive knowledge and experience with application security and web/application development.
We specialize in cryptography and secure PHP development.
Want the latest from Paragon Initiative Enterprises delivered straight to your inbox? We have two newsletters to choose from.
The first mails quarterly and often showcases our behind-the-scenes projects.
The other is unscheduled and gives you a direct feed into the findings of our open source security research initiatives.