Skip to main content
GrN.dk

Main navigation

  • Articles
  • Contact
  • Your Digital Project Manager
  • About Greg Nowak
  • Services
  • Portfolio
  • Container
    • Excel Freelancer
    • Kubuntu - tips and tricks
    • Linux Apache MySQL and PHP
    • News
    • Image Gallery
User account menu
  • Log in

Breadcrumb

  1. Home

WordPress 6.8 Password Hashing: The Hidden Risk in Legacy Login Bridges

By Greg Nowak. Last updated 2026-07-15.

WordPress 6.8 made password storage stronger without asking users to reset their passwords. For an ordinary site using the standard WordPress login, the change is deliberately uneventful. The operational risk sits elsewhere: old plugins, member portals, mobile APIs, migration tools, and support scripts that treat WordPress database fields as a stable authentication interface.

Those integrations may work for months after an upgrade. Then one user logs in through WordPress, their old password hash is replaced, and a separate login bridge stops recognising the account. That delayed failure is why this deserves an audit rather than a quick admin-login check.

What WordPress 6.8 actually changed

Since WordPress 6.8, wp_hash_password() uses bcrypt by default. WordPress first processes the password with SHA-384 to avoid bcrypt’s 72-byte input limit, then stores the resulting hash with a WordPress-specific prefix—normally $wp$2y$.

Existing phpass hashes, usually identified by $P$, remain valid. During the standard username-and-password authentication flow, WordPress checks whether a successful login needs rehashing and saves a new hash when necessary. Users are not migrated in one database operation, so old and new formats can coexist indefinitely on a site with infrequent users.

WordPress also introduced wp_fast_hash() for randomly generated, high-entropy secrets. Application passwords, password-reset keys, personal-data request keys, and recovery-mode keys can consequently appear with a $generic$ prefix. This fast BLAKE2b-based mechanism is not intended for user-chosen passwords.

The problem is the contract, not the prefix

A common patch is to teach an integration about $wp$2y$ and $generic$. That may restore service today, but it preserves the underlying design problem: an internal storage format has become an undocumented contract between systems.

WordPress already knows how to handle its current format, legacy phpass and MD5 values, compatible hashes created by plugins, and deliberately selected alternatives such as Argon2. Custom code should call the relevant WordPress authentication API instead of reproducing that decision tree.

Authentication path Warning sign Preferred boundary Minimum test
Browser or member login Reading user_pass directly wp_authenticate() Login before and after rehashing
Custom password check Calling PHP password_verify() on WordPress data wp_check_password() Legacy and current hashes
Application integration Inspecting _application_passwords REST authentication or WP_Application_Passwords::check_password() Old and newly issued credentials
Password reset Reimplementing user_activation_key checks check_password_reset_key() Issue, validate, expire, and reuse attempts
SSO or social login Fallback code touches stored hashes The provider callback and WordPress user APIs Success, denial, logout, and fallback
A practical decision matrix for reviewing authentication code after the WordPress 6.8 hashing change.

Search the codebase before tracing individual bugs

Start with custom plugins, must-use plugins, theme code, deployment utilities, and integration packages. These searches are intentionally broad; a match is a review prompt, not proof of a vulnerability.

rg -n '\$P\$|\$wp\$2y\$|\$generic\$|user_pass|user_activation_key|_application_passwords|PasswordHash' wp-content/
rg -n 'md5\(|password_verify\(|password_hash\(|wp_hash_password|wp_check_password|wp_verify_fast_hash' wp-content/

Also search repositories outside the WordPress installation. A Node, Java, .NET, or older PHP service that receives a copy of wp_users is often the real source of the failure. Database exports, reporting replicas, and migration code deserve attention too.

Use the highest-level supported API available

For a conventional username-and-password flow, let WordPress run the authentication pipeline:

$user = wp_authenticate( $username, $password );

if ( is_wp_error( $user ) ) {
    return $user;
}

// Authentication succeeded.

If custom code already has a user object and genuinely needs a password comparison, use wp_check_password(). Remember that this function only checks the value; it does not itself save a replacement hash. The standard wp_authenticate_username_password() flow performs the rehash after a valid check. A custom flow that bypasses it must deliberately handle that lifecycle, including the session implications of updating a password.

For application passwords, prefer WordPress’s REST authentication rather than reading user metadata. If verification inside WordPress is unavoidable, WP_Application_Passwords::check_password() handles both current and pre-6.8 application-password hashes. Use wp_verify_fast_hash() directly only for an appropriate high-entropy secret hashed through the matching WordPress mechanism—not as a generic password checker.

If another service needs to authenticate WordPress users, exporting password hashes is the fragile option. A small authenticated endpoint, an established identity provider, or a proper SSO boundary keeps the hashing implementation inside the system that owns it.

A staging test that reflects production

Create a test matrix around user journeys, not only functions. Include an account with a legacy hash and confirm its first standard login succeeds. Capture only the hash prefix—not credentials or full hashes—then confirm that the stored format changes and a second login still works.

Repeat the test through every real entry point: member portal, mobile client, customer dashboard, support impersonation tool, SSO fallback, password reset, application password, and recovery flow. Test failure cases as well as success. An integration that accepts an expired reset key or sends useful credentials into logs is a more serious problem than a clean rejection.

Finally, review observability. Authentication logs should identify the route, integration, and error category without recording plaintext passwords, tokens, or complete stored hashes. That gives the operations team enough context to distinguish a proxy problem, disabled application-password feature, rejected SSO assertion, and incompatible legacy bridge.

When a targeted review is worth it

A standard WordPress site probably needs no special project. A site with custom authentication, shared user tables, an inherited membership plugin, or credentials checked by another service does. The useful deliverable is a map of authentication paths, evidence from staging, and a short remediation list—not a speculative rebuild.

If ownership of those paths is unclear, Greg can audit the WordPress and integration code, replace direct hash handling with supported boundaries, and build a focused test plan for your release process. Talk to Greg about a targeted WordPress authentication review.

Related on GrN.dk

  • CodeIgniter Tips and Tricks for Secure Login and Password Resets
  • NGINX 1.30 changed upstream connection reuse by default: what to check before you upgrade
  • When AI writes JSON, one bad field can break the workflow

Need help with this kind of work?

Ask Greg about a WordPress authentication audit Get in touch with Greg.

Sources

  • WordPress 6.8 will use bcrypt for password hashing
  • wp_check_password() – WordPress Developer Resources
  • wp_authenticate_username_password() – WordPress Developer Resources
  • wp_verify_fast_hash() – WordPress Developer Resources
  • WP_Application_Passwords::check_password() – WordPress Developer Resources
Last modified
2026-07-15

Tags

  • wordpress
  • authentication
  • php
  • Operations

Review Greg on Google

Greg Nowak Google Reviews

 

Illustrated infographic summarizing: A Voice Agent Is Only Ready When the Human Handoff Works
A Voice Agent Is Only Ready When the Human Handoff Works
2026-07-15

A practical guide to voice agents that recognise failure, pass useful context to staff, protect customer data, and improve resolution after launch.

Illustrated infographic summarizing: If the Facts Need JavaScript, AI Search May Miss the Full Page
If the Facts Need JavaScript, AI Search May Miss the Full Page
2026-07-14

A practical guide to finding and fixing JavaScript rendering gaps that can hide services, prices, contact details and metadata from AI search crawlers.

Illustrated infographic summarizing: Search Console Can See Social Posts—Your Reports Need a New Map
Search Console Can See Social Posts—Your Reports Need a New Map
2026-07-13

Search Console now reports how social posts perform across Google. Here’s a practical way to manage properties, permissions, baselines and exports.

Illustrated infographic summarizing: WordPress 7.0 Has an AI Client. Plugins Need Their Own Guardrails
WordPress 7.0 Has an AI Client. Plugins Need Their Own Guardrails
2026-07-12

WordPress 7.0 standardizes how plugins call AI providers, while leaving developers responsible for access control, cost limits, capability checks and graceful failures.

Illustrated infographic summarizing: Google’s AI Search toggle needs a test plan, not a gut decision
Google’s AI Search toggle needs a test plan, not a gut decision
2026-07-11

Google’s AI Search control creates a measurable publishing choice. Test visibility, traffic and leads before changing the setting across your site.

Illustrated infographic summarizing: OpenAI Is Retiring Agent Builder: Save the Workflow, Not Just Prompts
OpenAI Is Retiring Agent Builder: Save the Workflow, Not Just Prompts
2026-07-10

OpenAI retires Agent Builder on November 30, 2026. Here is what teams need to preserve, how to choose a migration path, and how to cut over safely.

Illustrated infographic summarizing: AI agents need a browser policy before they start clicking around
AI agents need a browser policy before they start clicking around
2026-07-09

Browser-using AI agents can save time, but they need clear rules before they enter CRMs, CMSs, portals, or admin tools and start taking action.

Illustrated infographic summarizing: When AI writes JSON, one bad field can break the workflow
When AI writes JSON, one bad field can break the workflow
2026-07-08

Structured AI output is useful in real workflows, but teams need schemas, validation, retries, and logs before JSON reaches production systems.

Illustrated infographic summarizing: AI search is eating the click: measure the queries before rewriting pages
AI search is eating the click: measure the queries before rewriting pages
2026-07-07

AI summaries are cutting into search clicks. Start with a practical dashboard that shows query risk, bot purpose, page value, and crawler policy.

Illustrated infographic summarizing: AI shopping visibility now depends on boring product-data plumbing
AI shopping visibility now depends on boring product-data plumbing
2026-07-07

AI-assisted shopping puts more pressure on ecommerce catalog data, feeds, schema, prices, availability, and return-policy governance.

More articles
RSS feed

GrN.dk web platforms, web optimization, data analysis, data handling and logistics.