When 'Close Enough' Opens the Door: How Weak Checks Let Attackers Into Older PHP Applications

Arjun P

Solution Architect

28 Oct 20266 min read

When 'Close Enough' Opens the Door: How Weak Checks Let Attackers Into Older PHP Applications

Older PHP code often checks passwords, codes and payments with a loose comparison that can treat two different values as equal. That has let attackers log in without a password and mark bookings as paid without paying. Here's what it means for your business.

Every time someone logs in to your website, resets a password or confirms a payment, your application asks a simple question: does this match what we expected? You would assume the answer is a reliable yes or no. In older PHP code, it often depends on how the question was asked.

PHP offers two ways to compare values. One asks "are these exactly the same?" The other asks "are these the same once I've converted them into a similar form?" The second, looser check gives some surprising answers. Two different passwords can appear to match. An empty value can match a missing one. The word "true" can match a secret code. Developers call this behaviour type juggling, and in ageing PHP applications it has repeatedly turned into a way to get past a login or a payment check.

For a business, that means the parts of your system you most need to trust may be the parts most worth checking.

When "close enough" counts as a match

Imagine a security guard who compares ID cards by glancing at the first few letters of a name rather than reading the whole card. Most days, nothing goes wrong. But anyone who knows the guard's habit can get through with a card that only looks similar.

A loose comparison in software behaves in much the same way. When PHP compares two pieces of text that happen to look like numbers, the loose check treats them as numbers. Some scrambled password records, known as hashes, happen to look like the number zero written in scientific notation. Under a loose check, any two of those records count as equal, so a different password whose scrambled form also looks like zero can be accepted.

This is not one bug in one product. It is a recurring pattern, and it keeps producing new entries in the US National Vulnerability Database (NVD), the public record of known security flaws. A search of NVD for "type juggling" returned 33 entries as of 23 October 2026. A few examples:

  • phpList 3.5.0, an email newsletter tool, allowed attackers to bypass the admin login because password records were compared loosely. NVD rates it 9.8 out of 10.
  • Cacti before 1.2.27, a network monitoring tool, had a fallback login path with the same kind of loose password comparison.
  • MantisBT 2.27.1 and below, an issue tracker, let an attacker who knew a username log in to that account without knowing the actual password.
  • Five Star Restaurant Reservations for WordPress, up to 2.7.16, could be tricked into marking bookings as paid without any payment, because an empty value was treated as equal to a missing one.
  • Bookly for WordPress, up to 28.2, checked a one-time verification code loosely, letting attackers overwrite customer contact details.

These are mature, widely used products, not hobby projects. The mistake is easy to write, easy to miss in review, and tends to sit in the most sensitive code an application has.

What could go wrong for your business

The examples above show the realistic range of outcomes when a loose comparison sits in the wrong place:

  • Unauthorised access. An attacker logs in as an administrator or as a customer without knowing the password, and can see or change whatever that account can.
  • Lost revenue. A payment check that can be fooled means orders or bookings confirmed without money changing hands.
  • Altered customer data. Contact details, account settings or records changed by someone who should never have had access.
  • Damaged trust and compliance concerns. Customers expect their accounts to be protected. Explaining that a login could be bypassed is difficult, and may raise questions about how personal data was safeguarded.

Not every loose comparison is dangerous, and finding one does not mean it has been abused. The risk depends on where the check sits and what it protects. That is exactly why it needs someone to look.

Could your website be next?

Many attacks are not aimed at a particular business. Attackers often use automated tools to scan large numbers of websites, identify which products and versions they run, and try known weaknesses against them. A small or little-known website can be found this way simply because it is online, not because anyone chose it.

That matters most for this issue when your website runs a widely used product or plugin. Once a flaw like those in phpList, MantisBT or a WordPress booking plugin is publicly recorded, the details are available to anyone, including people building scanning tools. A site still running an affected version can be picked out from thousands of others without any special effort.

Custom-built applications are less exposed to mass scanning, because their weaknesses are not publicly listed. But they are not automatically safe either. The same habits that produced these published flaws appear in bespoke code, often in the login and payment logic written when the application was first built.

And a clean history does not guarantee anything. A loose check in a login page can sit unnoticed for years and still work for the first person who tries it.

Why legacy PHP applications deserve attention

Current PHP gives developers everything they need to avoid this problem, and well-maintained PHP code that uses those tools is not the concern. Some of PHP's most surprising comparison behaviour was also changed in PHP 8. The risk lies with older applications, for three reasons:

  • The code predates better habits. Applications written many years ago often store passwords in older, weaker ways and compare them loosely. That combination is exactly what led to several of the flaws above.
  • The runtime is out of support. Some of the riskiest comparison behaviour still applies on PHP 7.4 and older. According to php.net, PHP 7.4 reached end of life on 28 November 2022 and PHP 8.0 on 26 November 2023, so those versions receive no security fixes of any kind.
  • Upgrading changes behaviour quietly. Because PHP 8 changed how some comparisons work, moving an old application to a newer version can change the outcome of checks without any error or warning. Teams that know this often postpone the upgrade. Teams that don't can introduce changes nobody tested.

This is a common pattern in ageing software: the longer an application goes without care, the harder and riskier each change becomes. To be fair, other languages, including JavaScript, have their own loose comparisons, and any codebase can contain logic mistakes. The difference lies in how consistently the code is checked and maintained.

What this means for your organisation

You don't need to read code to act on this. The useful questions are about what your applications do and how well you understand them:

  • Which of your systems handle logins, password resets, one-time codes or payments?
  • Which PHP version does each of them run on, and is it still supported?
  • When were those parts of the code last reviewed by someone independent of the original developers?

If the answers are unclear, the application deserves a closer look before an incident gives you a reason. Knowing the real condition of your login and payment logic is also an important input to any decision about the application's future, whether that is a targeted repair, an upgrade or a wider modernisation.

Recommended next step

Don't assume the checks guarding your logins and payments are as strict as they look. Take our free Legacy PHP assessment to understand which PHP versions you run, how your authentication and payment logic is handled, and where older code may be leaving gaps.

Then speak to our team about the findings and the options that suit your application. For some systems, a careful upgrade on PHP is the right path. For others, modernising on a stack such as Node.js, with strict checks enforced automatically and tests that run on every change, may better fit the application's architecture and business goals. No platform is immune to logic mistakes, but a well-maintained one makes them much easier to catch.

Free Legacy PHP Risk Assessment

Not sure whether your login and payment code has type-juggling bugs? We'll review your PHP version, authentication code paths, password storage and dependencies, and tell you plainly where you're exposed and what your options are, whether that's a targeted fix, an upgrade or a migration.

Email us to request a free Legacy PHP Risk Assessment

Build with us. Deploy with us. Win with us

We don't deliver projects and walk away. We build with you, inside your mission.

Book a strategic consultation