How to Check If a Website Is Vulnerable
You can check if your website is vulnerable without attacking it by reading what your site already tells the public: its response headers, page source, and visible script files, then matching any software versions you find against a vulnerability database like OSV.
This is for site owners, developers, and anyone managing a WordPress, Shopify, or custom-built site who wants to answer "is my website vulnerable" without hiring a hacker or risking downtime. You'll get a step-by-step passive check you can run in a browser in about ten minutes, a plain-English explanation of what the results do and don't mean, and a clear line for when you need a person instead of a tool.
What "checking without attacking" actually means
A passive check makes the same requests a browser makes. It loads a page, reads the response headers, and looks at the public script files your site already serves to every visitor. It sends no attack payload, no malformed request, and nothing designed to break or bypass anything. Nothing about a passive check can crash your site or trigger a security alert on your host, because it looks identical to a normal page load.
This is different from an active vulnerability scan that probes for things like SQL injection, and very different from a penetration test, where a person is paid to actually try to break in. If you want to understand where passive checks sit relative to real testing, our guide on manual vs. automated penetration testing breaks down the difference.
Step-by-step: run a passive check yourself
- Load your homepage in a normal browser and open DevTools (F12, or right-click and choose Inspect), then open the Network tab.
- Reload the page and click the first request, which is your domain. Check the Response Headers panel for lines like Server, X-Powered-By, or X-Generator.
- Right-click the page and choose "View Page Source." Search (Ctrl+F) for version-looking strings. WordPress plugin and theme file paths often carry a version query string, like ?ver=6.4.2.
- If your site is built with Next.js, search the page source or the loaded JS chunks for "version" near "next". Next.js includes its version string in client scripts on many sites, but many large sites deliberately don't expose it, so finding nothing isn't unusual.
- Check your CMS admin footer or "About" screen. WordPress, Joomla, and most CMS admin panels show the exact core and plugin versions whether or not that information is visible on the public-facing site.
- Write down every version number you find: CMS core, theme, plugins, and any framework.
Here's what the most common headers and files tend to reveal, and what usually hides them:
| Where to look | What it can reveal | What hides it |
|---|---|---|
| Server header | Web server software, sometimes version (Apache, nginx) | Server token settings turned off |
| X-Powered-By header | Often the PHP version | expose_php = Off in php.ini |
| Page source / JS chunks | Next.js version string | Many sites strip it; absence proves nothing |
| Theme/plugin URLs | WordPress theme and plugin versions via ?ver= query string | Developers who remove version query strings |
| robots.txt | Presence of CMS-style paths (e.g. /wp-admin/), not a version number | Doesn't apply, it was never a version source |
| readme.html | CMS core version (WordPress ships a readme.html by default) | Deleting or blocking the file |
On servers that haven't hardened their configuration, the PHP version shows up because of two settings: expose_php (controls whether PHP adds an X-Powered-By header) and ServerTokens (an Apache directive controlling how much the Server header reveals). Turning both off is one of the simplest hardening moves available, and you can check your current headers with our free security headers tool.
How a version turns into a vulnerability result
Once you have a version number, like "plugin X, version 3.2.1," the next step is matching it against a public vulnerability database. Two of the most useful are:
- OSV (osv.dev): an open vulnerability database that aggregates the GitHub Advisory Database and other sources. You can query it by package name, ecosystem (npm, PyPI, RubyGems, Go, crates.io, Maven, NuGet, Packagist, Debian/Alpine, and other language or distro ecosystems), and version, and it returns the published advisories that cover that exact version. OSV doesn't cover WordPress plugins or themes, so for those, check the WPScan Vulnerability Database or Patchstack instead.
- The GitHub Advisory Database: GitHub's own catalog of security advisories, many of which OSV also indexes.
An advisory describes a flaw in a specific version range, for example "affects 3.0.0 through 3.2.4, fixed in 3.2.5." If your version falls inside that range, the advisory applies to you. That lookup, read the version, search the database, see what's published against it, is the entire mechanical process behind "version fingerprinting."
Why an affected version isn't proof you're exploitable
This is the part most automated scanners skip past, and it matters. An advisory describes a flaw that exists in the code. Whether that flaw can actually be used against your specific site depends on the feature or setup involved, so the advisory text itself has to be read, not just the severity label.
A few concrete reasons a matching version doesn't automatically mean you're at risk:
- The vulnerable feature might require a setting your site doesn't use, such as an import function you've disabled or an API endpoint you don't expose.
- The flaw might need authenticated access, and your site might not allow public account creation.
- If you run a Linux distribution's packaged version of software (Debian, Ubuntu, RHEL, and similar), the distro maintainers often backport security fixes into an older package without changing the version number. That means a version-only check against a distribution package can be wrong in either direction: it can flag you as vulnerable when you've already been patched, or miss a real issue because the number looks current. Distro-packaged software needs the vendor's own security tracker or changelog checked directly, not just the version string.
In short, a version match is a lead worth investigating, not a verdict. If you want a broader read on your exposure before chasing any one finding, start with our free website security check and the companion guide on is my website hackable.
What passive checks and scanners can't see
Version fingerprinting only covers known, published flaws in named software. It says nothing about problems specific to how your particular site was built, because there's no advisory database for your custom code.
Two categories that scanners reliably miss:
- Access control flaws: a logged-in user who can view or edit someone else's order, invoice, or account just by changing an ID in the URL. No published advisory covers your specific app, so no scanner will catch it.
- Business logic flaws: a checkout flow that lets someone apply a discount code twice, or a password reset link that never expires. These aren't bugs in the traditional sense, the code runs exactly as written, it just wasn't thought through. Scanners and other automated tools can't judge access control or business logic; a person testing by hand is what finds these.
That's the honest boundary between a free passive check and a real audit. A tool can tell you "this plugin version has a published SQL injection advisory." It can't tell you "this custom checkout page leaks other customers' order history if you change one number in the URL." For that, you need a person who understands how your site actually works and tries it the way an attacker would.
A quick decision checklist
Use this to decide what level of check you need right now:
- [ ] I just want to know if my CMS and plugins are out of date: run the passive steps above, then check OSV for frameworks and libraries, or WPScan/Patchstack for WordPress plugins and themes.
- [ ] I handle customer logins, payments, or personal data: a version check alone isn't enough; plan for a look at access control too.
- [ ] I need to answer a client's or insurer's security questionnaire: a written report with evidence usually matters more than a clean scanner result.
- [ ] I found an affected version and I'm not sure it's really exploitable on my setup: read the advisory's "affected functionality" section, or get a second opinion.
- [ ] I don't know what I don't know: that's exactly the gap manual testing closes.
The legal line
Only test systems you own or have written permission to test. Passive checks that read what a server already publishes to every visitor are generally low-risk, but anything beyond that, login attempts, scanning third-party plugins, probing endpoints, should only happen on sites you're authorized to test. Don't run even "harmless" tools against a client's or a competitor's site without their sign-off.
Key takeaways
- A passive check reads headers, page source, and public scripts the way a browser does; it sends no attack payload and is safe to run against your own site.
- Hardened servers hide version info (expose_php, ServerTokens off), so an empty result doesn't mean you're unpatched, it might just mean the header is hidden.
- Match any version you find against OSV or the GitHub Advisory Database, then read the advisory text before assuming you're at risk.
- A matching version is a lead, not a verdict: Linux distributions backport fixes without changing version numbers, and advisories often depend on specific features or configurations.
- Scanners can't judge access control or business logic flaws in your own custom code; that needs a person testing by hand.
When to bring in a person
If your passive check turns up an out-of-date plugin or an exposed version string, that's fixable today: update the software, hide the version headers, move on. But if you store customer data, take payments, or simply want to know what a hands-on tester would actually find, that's where a real audit earns its cost. Bug Circuit's manual audit is a one-time $49: a real person reviews your whole site and hands you a written report with severity, evidence, and exact fixes, the part a passive check or scanner was never built to do. See pricing for how that compares with our other plans.
A real human security engineer audits your whole site by hand and sends a full report: every issue, its severity, and the exact fix. From $49, with a 14-day money-back guarantee.
See pricing