A lightweight fast Go script to detect which CMS or framework a given website is running, based on HTTP response fingerprints.
- Detects 60+ CMS/frameworks (WordPress, Drupal, Shopify, Laravel, Wix, β¦).
- Multiple fingerprint methods:
- HTML body regex & string search
- HTTP headers
- Cookies (including Base64/JSON decoding)
- CLI modes:
- Standard (colorful output)
- Raw (--raw) β just the CMS name (script-friendly)
- JSON (--json) β structured output
- Works with both http:// and https:// targets.
Prereq: Go 1.21+ (for go install). For prebuilt binaries from Releases, no Go toolchain is required.
Download a prebuilt binary for your OS/arch from the Releases page and put it on your PATH.
- Releases: https://github.com/joshuavanderpoll/CMS-Detector/releases
- Artifacts naming: cmsdetector_.(tar.gz|zip)
Examples:- cmsdetector_v1.0.0_linux_amd64.tar.gz
- cmsdetector_v1.0.0_darwin_arm64.tar.gz
- cmsdetector_V1.0.0_windows_amd64.zip
# pick the right asset from the release page
tar -xzf cmsdetector_v1.0.0_linux_amd64.tar.gz
chmod +x cmsdetector_v1.0.0_linux_amd64/cmsdetector
sudo mv cmsdetector_v1.0.0_linux_amd64/cmsdetector /usr/local/bin/cms_detector
cms_detector --helpExpand-Archive .\cmsdetector_V1.0.0_windows_amd64.zip -DestinationPath .
Move-Item .\cmsdetector_V1.0.0_windows_amd64\cmsdetector.exe $Env:ProgramFiles\cms_detector\cms_detector.exe
$Env:ProgramFiles\cms_detector\cms_detector.exe --helpThis builds and installs directly from the repoβs module path.
go install github.com/joshuavanderpoll/CMS-Detector@latest
# or use a specific version:
go install github.com/joshuavanderpoll/CMS-Detector@v1.0.0
# Usage
~/go/bin/CMS-Detector --help# Clone the repository
git clone https://github.com/joshuavanderpoll/CMS-Detector.git
cd CMS-Detector
# Build the Go binary
go build -o cms_detector ../cms_detector --host "https://wordpress.com"Output:
CMS Detector
[β’] Made by: https://github.com/joshuavanderpoll/CMS-Detector
[@] Scanning host "https://wordpress.com"...
[β] "https://wordpress.com" is using "WordPress"!
β³ matched by: string_contains:/wp-content/
./cms_detector --host "https://wordpress.com" --rawOutput:
wordpress
./cms_detector --host "https://wordpress.com" --jsonOutput:
{"host":"https://wordpress.com","status_code":200,"detected":true,"matches":[{"name":"WordPress","matched_by":["string_contains:/wp-content/"]}],"timing_ms":188,"redirects":0}| Option | Description |
|---|---|
--host |
Target host (e.g. example.com, https://example.com) |
--raw |
Print only CMS name(s) in lowercase (e.g. wordpress) |
--json |
Return structured JSON output |
--timeout |
Set request timeout (default: 10s) |
--insecure |
Disable SSL verification (verify=False) |
--ua |
Custom User-Agent string |
--no-redirect |
Do not follow HTTP redirects |
- Laravel
- WordPress
- Drupal
- Lightspeed
- Shopify
- PrestaShop
- Squarespace
- Sanity
- Wix
- Next
- Microsoft
- JouwWeb
- Magento
- Weebly
- Joomla
- Blogger
- SilverStripe
- Icordis CMS
- Sulu
- Gatsby
- Webflow
- Zendesk
- Django
- CoreMedia
- ProcessWire
- TYPO3
- Blox
- Odoo
- Netlify
- Amazon S3 (Static Website)
- Vercel
- GitHub Pages
- Ghost
- Craft CMS
- Umbraco
- Sitecore
- Strapi
- HubSpot CMS
- BigCommerce
- Tilda
- Webnode
- GoDaddy
- Adobe
- Strato
- Duda
- Nuxt.js
- OpenCart
- Bitrix (1C-Bitrix)
- Jimdo
- Adobe Experience Manager
- Microsoft Word (generated HTML)
- Contao
- IONOS MyWebsite
- Salesforce Experience Cloud
- Mobirise
- Microsoft FrontPage
- Adobe Muse
htmlβ Match a CSS selector against the parsed DOM (recommended for HTML β no false positives from page text)regexβ Match regex in HTMLstring_containsβ HTML contains substringstrings_containβ HTML contains all substrings (pipe-separated)header_key_equalsβ Header key existsheader_key_valueβ Header key/value matchheader_key_value_containsβ Header keyβs value contains substringcookie_key_equalsβ Cookie key existscookie_key_valueβ Cookie key/value matchcookie_key_value_containsβ Cookie value contains substringcookie_key_value_b64_json_keysβ Decode cookie from Base64 β JSON β check for keyscookie_substr_key_value_b64_typeβ Check cookie name suffix, decode Base64, verify value type
Unlike string_contains, the html type parses the response into a real DOM and runs a
CSS selector (powered by cascadia). It only
matches actual elements/attributes, so a blog that merely mentions /wp-content/ in its
text is not a false positive β the path has to live in a real <link href>/<script src>.
Supported selector features: tag/class/id, descendant & child combinators, selector groups
(a, b), and attribute matchers [attr], [attr=val], [attr*=val] (contains),
[attr^=val] (prefix), [attr$=val] (suffix).
// WordPress (fingerprints/fingerprints.go)
{Type: `html`, Value: `meta[name="generator"][content*="WordPress"]`},
{Type: `html`, Value: `link[href*="/wp-content/"], script[src*="/wp-content/"]`},Detections are plain Go data in fingerprints/fingerprints.go.
Add a CMS entry to the All slice β no engine changes needed:
{
Name: `My CMS`,
Fingerprints: []Fingerprint{
{Type: `html`, Value: `meta[name="generator"][content*="My CMS"]`},
{Type: `header_key_value_contains`, Key: `X-Powered-By`, Value: `MyCMS`},
},
},A CMS is reported if any of its fingerprints match. Invalid regex/CSS selectors are skipped at startup rather than crashing, so a typo in one fingerprint won't break the rest. PRs with new detections are welcome.