RedScore.ai

Fixes

Technology Fingerprinting · Updated 2026-05-02

Stack Exposure Profile

Composite of stack visibility and outdated-version signals (18 pts). Reduce identifiable tokens and update behind-current-stable software.

Stack Exposure Profile is the rollup of how much of your technology stack is identifiable from public HTTP responses. It aggregates fingerprints from response headers (Server, X-Powered-By, X-AspNet-Version, X-Generator), HTML meta tags, and content patterns across every primary host, then deducts points for two separate things: how many distinct technologies were fingerprinted, and how many of them are observably behind current stable releases. Most attackers begin reconnaissance by fingerprinting the stack; this check measures how cheap that work is for them.

How the check works

Two deductions stack on top of the 18-point weight:

  • Visibility deduction (based on distinct technology count): 0 tokens deducts 0 points; 2-3 deducts 12; 4-5 deducts 22; 6 or more deducts 35 (capped at 18 since the weight is 18).
  • Outdated-version penalty: 5 points per detected component running behind current stable (PHP < 8.x, Apache < 2.4.x, Tomcat < 10.1, etc.). Capped at the remaining weight after visibility deduction.

Final score = (weight - visibility_deduction - outdated_penalty) / weight. Verdict thresholds: pass at score 0.9 and above, warn at 0.45 and above, fail below.

How the verdict maps to evidence

  • Pass (low severity): few or no distinct stack tokens detected; no outdated components.
  • Warn (medium): some stack visibility, or a small number of outdated components.
  • Fail (high): many distinct technologies fingerprinted, or several outdated components, or both.

Evidence shows distinct_technology_count, distinct_technologies (list of detected tokens), visibility_deduction_points, and outdated_signals (list of behind-stable components with observed and baseline versions).

Special states

  • Not Applicable: domain redirects to a different site (the redirect target is scored on its own scan), or primary host serves a default/placeholder page (stack scoring is not meaningful for empty hosting).
  • Degraded: probe data unavailable (Web Assessability or upstream issue). Returns no score until probes succeed.

Fix: reduce visibility, then update outdated software

Two independent levers. Most domains see the biggest gain from the visibility lever because it is fast and free; the outdated lever takes more work but closes harder vulnerabilities.

1. Reduce identifiable stack tokens

The visibility deduction looks at how many distinct technologies your responses leak. The dedicated fix pages cover specific headers (Server Header Disclosure, Framework Disclosure, Debug Indicators); this is the high-level summary:

  • Genericize or remove the Server header. nginx and Apache both expose version by default; configure to send only a generic value or none at all.
  • Strip framework-disclosure headers: X-Powered-By, X-AspNet-Version, X-AspNetMvc-Version, X-Generator. Most frameworks have a one-line setting; some require explicit removal.
  • Remove or genericize meta generator tags in HTML (<meta name="generator" content="WordPress 6.x">). CMS templates often leave these in by default.
  • Audit X-Runtime, X-Drupal-Cache, X-Pingback, X-Backend-Server and similar diagnostic headers. Useful for debugging; do not need to be public.
  • Move static asset paths off framework-default routes (/wp-content/, /sites/default/files/). Per-host renaming is rarely worth it, but consolidating behind a CDN with custom paths is.

Per-server snippets for header removal

nginx (hide version, no X-Powered-By)

server_tokens off;          # Server: nginx (no version)
proxy_hide_header X-Powered-By;
proxy_hide_header X-AspNet-Version;
proxy_hide_header X-Drupal-Cache;
proxy_hide_header X-Generator;

Apache (hide version, remove headers)

ServerTokens Prod           # Server: Apache (no version)
ServerSignature Off
Header unset X-Powered-By
Header unset X-AspNet-Version
Header unset X-Generator

Express / Node.js (Helmet)

import helmet from "helmet";
app.disable("x-powered-by");          // remove default Express header
app.use(helmet.hidePoweredBy());      // belt and braces

ASP.NET Core

// Program.cs
builder.WebHost.UseKestrel(options => {
    options.AddServerHeader = false;  // remove Server header
});

// In web.config (IIS-hosted), strip X-Powered-By:
// <httpProtocol>
//   <customHeaders>
//     <remove name="X-Powered-By" />
//   </customHeaders>
// </httpProtocol>

Django

# Django does not set X-Powered-By by default.
# If a middleware adds it, audit MIDDLEWARE in settings.py.
# Strip generator meta tags from base templates.

WordPress

// In your theme's functions.php or a small plugin:
remove_action('wp_head', 'wp_generator');                // <meta name="generator">
add_filter('the_generator', '__return_empty_string');    // RSS feed generator
remove_action('wp_head', 'rsd_link');                    // RSD link
remove_action('wp_head', 'wlwmanifest_link');            // Windows Live Writer
remove_action('wp_head', 'wp_shortlink_wp_head');        // shortlink

// Strip X-Powered-By in nginx/Apache config or via security plugin.

2. Update outdated software

Each outdated_signals entry lists the platform, what was observed, and the baseline current-stable version. Common cases the check looks for include PHP older than 8.x (PHP 7.x is end-of-life), Apache below the current stable, and Tomcat below 10.1. The fix is straightforward: schedule the upgrade.

  • PHP: 7.x is EOL as of 2022. Upgrade to PHP 8.2 or later. Most CMS and framework code runs unchanged on 8.x; some legacy code may need a compatibility pass.
  • Apache HTTP Server: stay on the latest 2.4.x release. End-of-life branches stop receiving security updates.
  • Tomcat: stay on a maintained branch (10.1, 11.x). Older branches reach end-of-life and stop receiving fixes.
  • Other detected platforms: check the vendor's lifecycle page and upgrade to a maintained release.

The check intentionally flags outdated even without CVE correlation; the signal is hygiene, not exploit feasibility. A vendor-supported branch is the floor.

Verify the fix

  • curl -sI https://yourdomain.tld | grep -iE 'server|x-powered-by|x-generator|x-aspnet' shows what your server is currently leaking.
  • View the page source and search for <meta name="generator". Modern browsers expose this in DevTools → Sources or Elements panel.
  • Wappalyzer browser extension or BuiltWith tells you what a typical fingerprinter sees from your responses; aim for fewer distinct hits.
  • Re-run the RedScore lookup. distinct_technology_count and outdated_signals in the evidence show the current state.

Common pitfalls

  • Genericizing the Server header but leaving X-Powered-By. Each header is a distinct fingerprint. Remove or genericize them all.
  • Removing one fingerprint header but adding two more. Some "security" plugins add their own custom headers (X-Powered-By: Wordfence, X-MyPlugin-Version). Audit the response after every plugin install.
  • Stripping headers at the CDN but origin still leaks them. Strict-mode WAFs that go around the CDN see origin headers. Strip at both layers.
  • Updating PHP but missing the underlying server fingerprint. The Server header may show "Apache/2.4.x (Debian)" while PHP-FPM is the real upgrade target. The check looks at all signals; fix where each one originates.
  • Calling the fix done after one round. Plugins, framework upgrades, and CDN config changes can reintroduce headers later. Re-scan periodically.
  • Treating low fingerprint count as security. Reducing visibility makes attacker recon harder; it does not protect against vulnerabilities in the underlying software. Visibility reduction and version updates are independent levers; do both.
  • Hiding behind "security through obscurity" arguments. Yes, an attacker can still exploit your stack without the Server header. The point is to slow recon and force the attacker to spend more probe budget. Headers cost nothing to remove and the deductions are real points.

What to do next

See how these recommendations apply to your site's current scan results.

Scan domain