infoSeverity: infoRisk ratingHow usable this gap is to an attacker. Severity sets the posture penalty: critical −40, high −20, medium −10, low −4, info −1. Higher severity means fix it sooner.App framework / headersWhere it livesImplementationThis fix is applied in: App framework / headers. That's the surface you'll edit, DNS, response headers, or a static file.~3 minTime to fixEffortRoughly 3 minutes of hands-on work, propagation aside. Most of these are copy-paste.+1 posture+1 postureScore impactPoints this fix recovers in the ApeCyber posture score (0–100). Posture = 100 minus the severity penalty of every open finding; clearing this finding adds these points back.

X-Powered-By: remove the header that names your framework

Dropping X-Powered-By stops your responses from telling attackers which framework and version to exploit

The threat

The scanner saw an X-Powered-By header on your responses, something like X-Powered-By: Express or X-Powered-By: PHP/7.4.3. It’s a courtesy stamp the framework adds by default. It does nothing for your visitors, it only announces what’s running under the hood.

Same idea as the Server banner. An attacker, usually an automated one, reads that string, looks the framework and version up against public vulnerability lists, and leads with the attacks already known to work on it. Removing the header doesn’t fix a bug, it just stops handing out the map.

The exact fix

Turn it off as close to the app as you can. Lead with your stack:

Express / Node (one line):

// app.js
app.disable('x-powered-by');
// or, if you already use helmet, it removes this header for you:
// app.use(helmet());

PHP (turn off expose_php):

; php.ini
expose_php = Off

That drops the X-Powered-By: PHP/… header PHP adds on its own.

Strip it at the web server (works no matter what set it):

# Apache (mod_headers)
Header always unset X-Powered-By
# nginx (needs the headers-more module)
more_clear_headers "X-Powered-By";

Check the response a visitor actually gets, not just the app’s. If a framework, a reverse proxy, and a CDN are chained together, more than one layer can add its own X-Powered-By, so confirm at the edge. On Netlify and similar managed hosts your static responses won’t carry this header at all; if you see one, it’s coming from an app server or function you control, fix it there.

Verify it

curl -sI https://yourdomain.com | grep -i x-powered-by

Success is no output at all: the header is gone. Any line that comes back (X-Powered-By: Express, X-Powered-By: PHP/7.4.3) means something in the chain is still adding it.

Proof

The ApeCyber scanner flags this passively on every scan, from the outside, touching nothing. apecyber.com grades A / 100 on Netlify and returns no X-Powered-By for a bot to match against a CVE list; dev3lop.com went from a failing grade to A / 100 doing exactly these small cleanups. It’s a 3-minute, −1 fix, one of the easiest points on the whole report.