Post

404-Fingerprint: What 404 Pages Reveal About Your Tech Stack

How default 404 pages expose backend technologies, and how my tool 404-Fingerprint automates this fingerprinting process.

404-Fingerprint: What 404 Pages Reveal About Your Tech Stack

Introduction

One day I opened my LinkedIn profile and saw “404 profielbezoekers (404 profile visitors)” 404 Not Found

It made me think about the technical implications of the HTTP 404 status page, even LinkedIn can’t find anyone looking at my profile. That moment also reminded me of something I use frequently during reconnaissance: the 404 Not Found page. I also check how the page behaves when requesting files such as /index.php, /index.html, /index.jsp, etc. The way a server responds often exposes the underlying runtime or routing logic.

For most users, a 404 page is boring.
For security researchers and penetration testers it’s a fingerprint.
It can reveal frameworks, servers and interesting details.

That thought led to the creation of 404-Fingerprint, my tool that classifies backend technologies purely from 404 responses. This tool is heavily inspired by the work of 0xdf: 0xdf Cheatsheet — 404 Fingerprinting ↗


Why 404 pages matter during reconnaissance

404 error pages are often overlooked, but they can leak valuable metadata such as:

  • default HTML templates from web frameworks
  • custom error tokens
  • server identifiers
  • template engine markers
  • behavior differences in routing, middleware, and controllers

404 responses often bypass WAF inspections entirely because they are considered benign error pages. This makes them a reliable fingerprinting vector even in hardened environments.

Because many applications leave their 404 pages unmodified, they provide a stable and reliable fingerprinting method, even when banner grabbing is disabled.


What different 404 pages reveal

Server fingerprints

Certain web servers have characteristic 404 pages:

  • Apache httpd
  • nginx
  • Microsoft IIS

Even when the frontend looks beautiful and custom designed, the server often can’t help but let its true identity peek through, hidden in comments, whitespace, or error codes.

Framework fingerprints

Backend frameworks also leave signatures:

  • Spring Boot: Shows often the whitelabel error page.
  • Tomcat: Shows often that the requested URL was not found on this server.

Recognising these patterns helps build a full tech-stack picture early in a reconnaissance workflow.


Introducing 404-Fingerprint

404-Fingerprint is a Python tool that analyses 404 responses and identifies likely technologies behind them.

It performs:

  • server fingerprinting
  • framework detection
  • default template identification
  • JSON/HTML classification
  • token and keyword matching
  • header pattern analysis

GitHub repository:
GitHub


How the tool works

The process is straightforward:

  1. Request a guaranteed invalid endpoint.
  2. Collect the 404 response (headers + body).
  3. Analyse the structure:
    • HTML tags
    • error messages
  4. Compare with an internal signature library.
  5. Output the most likely server or framework.

Because error pages often remain untouched even when everything else is behind a WAF, this method remains effective in many hardened environments.


Example output

Spring Boot Whitelabel 404

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
python3 404_fingerprint.py https://tomcat.apache.org --tech-only
[+] Fetching: https://tomcat.apache.org
https://tomcat.apache.org | status=200 | tech=Apache httpd (header only) | default_page=- | soft_404=No
root@vmi2791304:/home/test/recon_multi/recon-output/parts/batches# python3 404_fingerprint.py https://start.spring.io/thispagedoesnotexist

┌───────────────────────────────────────────────────────────────┐
│                           404 PROFILER                       │
│                Web Error-Page Fingerprint Scanner            │
└───────────────────────────────────────────────────────────────┘

[+] Fetching: https://start.spring.io/thispagedoesnotexist

=== HTTP Info ===
Status: 404
Title: None
Server header: cloudflare
Content-Type: text/html;charset=UTF-8
Tech fingerprint: Spring Boot

=== Fingerprints ===
[*] Soft 404 detected (template-style 404 across multiple paths)
[*] Directory listing not detected.
[*] Default server page detected: Whitelabel Error Page
[*] Detected error phrases: error, not found

=== Body Stats ===
Length: 828 bytes
Words: 40

=== Fuzzing non existing paths (root based) ===
/random123                     -> status 404, len=838 (similar to baseline)
/admin123                      -> status 404, len=837 (similar to baseline)
/asdfgh                        -> status 404, len=835 (similar to baseline)
/no-such-page-xyz              -> status 404, len=845 (similar to baseline)
/this-page-should-not-exist-404 -> status 404, len=859 (similar to baseline)

=== 404 Summary ===
- URL: https://start.spring.io/thispagedoesnotexist
- Status Code: 404
- Title: None
- Server (header): cloudflare
- Server (class): cloudflare
- Tech Stack Guess: Spring Boot
- Interesting Markers: error, not found
- Possible Soft 404: Yes
- Default Page: Whitelabel Error Page
- Directory Listing: No

Spring Boot (tech-only mode)

1
2
3
python3 404_fingerprint.py https://start.spring.io/thispagedoesnotexist --tech-only
[+] Fetching: https://start.spring.io/thispagedoesnotexist
https://start.spring.io/thispagedoesnotexist | status=404 | tech=Spring Boot | default_page=Whitelabel Error Page | soft_404=Yes

Tomcat (full analysis)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
python3 404_fingerprint.py https://tomcat.apache.org/

┌───────────────────────────────────────────────────────────────┐
│                           404 PROFILER                       │
│                Web Error-Page Fingerprint Scanner            │
└───────────────────────────────────────────────────────────────┘

[+] Fetching: https://tomcat.apache.org/

=== HTTP Info ===
Status: 200
Title: Apache Tomcat® - Welcome!
Server header: Apache
Content-Type: text/html
Tech fingerprint: Apache httpd (header only)

=== Fingerprints ===
[*] Soft 404 not detected.
[*] Directory listing not detected.
[*] Default server page detected: None
[*] Detected error phrases: exception

=== Body Stats ===
Length: 16499 bytes
Words: 1407

=== Fuzzing non existing paths (root based) ===
/random123                     -> status 404, len=196
/admin123                      -> status 404, len=196
/asdfgh                        -> status 404, len=196
/no-such-page-xyz              -> status 404, len=196
/this-page-should-not-exist-404 -> status 404, len=196

=== 404 Summary ===
- URL: https://tomcat.apache.org/
- Status Code: 200
- Title: Apache Tomcat® - Welcome!
- Server (header): Apache
- Server (class): apache
- Tech Stack Guess: Apache httpd (header only)
- Interesting Markers: exception
- Possible Soft 404: No
- Default Page: None
- Directory Listing: No

Tomcat (tech-only mode)

1
2
3
python3 404_fingerprint.py https://tomcat.apache.org/ --tech-only
[+] Fetching: https://tomcat.apache.org/
https://tomcat.apache.org/ | status=200 | tech=Apache httpd (header only) | default_page=- | soft_404=No

Mitigation

Fingerprintable 404 pages are not vulnerabilities by themselves, but they provide attackers with valuable reconnaissance data. Reducing the amount of information leaked through error pages is a simple and effective hardening step.

Replace all default error templates

Many frameworks ship with distinctive 404 pages (Spring Boot Whitelabel, Tomcat Error Report, Rails Default Error, Express JSON errors). These pages contain unique wording, structure, or metadata that make technology detection trivial.

Use a fully custom static HTML page instead of the framework’s built-in error renderer.

Keep the page minimal and generic

A custom 404 page should:

  • avoid framework-generated templates
  • avoid comments, stack traces, or debug hints
  • avoid backend-specific keywords (for example: Type Status Report, Whitelabel, Request processing failed, Powered by…)
  • avoid JSON error formats that leak routing or controller information

Ensure the 404 page behaves consistently

Inconsistent 404 responses across different paths can leak routing logic or middleware behaviour.

Aim for:

  • identical page length
  • identical structure
  • identical headers
  • no templating differences indicating dynamic backend behaviour

Final Thoughts

404 pages are more than simple error screens, they are reliable indicators of what a system is running behind the scenes. By analysing the structure, templates, and behaviour of these responses, it becomes possible to identify servers, frameworks, and routing logic with surprising accuracy.

404-Fingerprint automates this process and integrates easily into reconnaissance workflows, allowing security researchers and penetration testers to gather valuable intelligence with minimal noise.

If you try the tool, feel free to share feedback, ideas, or interesting fingerprints you encounter.

Stay curious and keep fingerprinting!

References

This post is licensed under CC BY 4.0 by the author.