Cyberlium

Web › Module 10 › Lesson 2

BeginnerModule 10Lesson 2/5

Error Messages That Leak

Clients get safe messages; details go to logs you control — not stack traces to the world.

15 min+40 XP3 quiz
Module progress2 of 5

Visual · error_messages_leak

User sees “something went wrong #abc”; ops see stack in private logs. — router STOP — SAFE Own apps only.

Opening

Verbose errors help attackers map your stack — A10 includes leaky exceptions.

OWASP Top 10:2025 A10 Mishandling of Exceptional Conditions includes returning stack traces, SQL fragments, absolute paths, secret material, or account-oracle detail to untrusted clients. Attacker goal: reconnaissance from your crashes. Cyberlium: separate public message vs private log on apps YOU own — 0.0.1:8775. Not scrape stranger error pages for a portfolio. Next: unexpected states and recovery. Today: leaky errors.

1. Public vs private: correlation id pattern

Return a generic message plus a correlation id the user can quote. Log the full exception server-side with that id (still redacting secrets — A09). Never return Exception.toString() from production APIs you ship. The 8775 toy contrasts /broken/error vs /fixed/error.

Debug mode that prints stacks belongs only on local profiles — never default prod.

Command guide

A10 Exceptions — Public vs private

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl

macOS: Built-in

Windows: Built-in (PowerShell: Invoke-WebRequest)

═══ COMMANDS ═══

Command — copy this

SAFE="http://127.0.0.1:8775"

Command — copy this

curl -sS -m 3 -D - "$SAFE/fixed/error" | head -n 20

2. Oracles: existence and validation detail

“User not found” vs “bad password,” raw validator dumps, and framework 500 bodies that reveal routes/files are oracles. Choose conscious product tradeoffs; default to less detail on auth. Document YOUR choice.

Dependency error strings often include hostnames and versions — strip before client response.

Command guide

A10 Exceptions — Oracles

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl

macOS: Built-in

Windows: Built-in (PowerShell: Invoke-WebRequest)

═══ COMMANDS ═══

Command — copy this

SAFE="http://127.0.0.1:8775"

Command — copy this

curl -sS -m 3 "$SAFE/broken/error" | head -n 16

3. Secrets in exceptions: connection strings and tokens

Libraries sometimes embed credentials in exception messages. Scrub before log and never before client. Rotate if a secret ever leaked to a client response on a system you own.

Do not paste live connection strings into cyberlium-lab notes.

Command guide

A10 Exceptions — Secrets in exceptions

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl

macOS: Built-in

Windows: Built-in (PowerShell: Invoke-WebRequest)

═══ COMMANDS ═══

Command — copy this

SAFE="http://127.0.0.1:8775"

Command — copy this

curl -sS -m 3 -D - "$SAFE/broken/error" | head -n 14

4. Own-lab proof: broken vs fixed local handler

A tiny local HTTP handler on 127.0.0.1:8775 shows leaky vs safe messages. Writeups cite http://192.168.0.1/ as the demo asset. No foreign targets. No hydra. Cite A10. Original Cyberlium — not official OWASP certification.

chmod 600 notes.

5. Wrong vs right: stack to client vs id + private log

Same word “error,” opposite exposure.

  • Wrong

    Return stacks/SQL/paths to clients. Leave debug=True in prod. Harvest stranger 500 pages. Hydra the router. nmap the LAN.

  • Right

    Identify DEMO; router → SAFE. Generic client message + correlation id; detail in private logs; lock error-leak-notes.txt. Next: Unexpected States and Recovery.

6. Hands-on: safe-error toy on 8775 + error-leak-notes.txt

Start a10_safe_error_toy.py (127.0.0.1:8775). Compare /broken/error vs /fixed/error. Record the pattern in notes.

Command guide

error_leak_notes.sh — DEMO identify + public vs private error toy

═══ INSTALL ═══

Linux (Debian/Ubuntu):

Command — copy this

sudo apt install curl
sudo apt install nmap
sudo apt install python3

macOS:

Command — copy this

brew install nmap
brew install python3

Windows: Built-in (PowerShell: Invoke-WebRequest)

Command — copy this

choco install nmap  # or download https://nmap.org/download.html

Download https://python.org/downloads/

═══ COMMANDS ═══

Command — copy this

cd "$HOME/cyberlium-lab"

Command — copy this

cat > a10_safe_error_toy.py << 'PY'
"""Leaky vs safe client errors. Bind loopback only."""
import uuid
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse

HOST = "127.0.0.1"  # bind only — never 0.0.0.0, never argv
PORT = 8775
if HOST != "127.0.0.1":
raise SystemExit("refusing non-loopback bind")

class Handler(BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
    print("[demo]", fmt % args)

def _send(self, code: int, body: str):
    data = body.encode("utf-8")
    self.send_response(code)
    self.send_header("Content-Type", "text/plain; charset=utf-8")
    self.send_header("Content-Length", str(len(data)))
    self.end_headers()
    self.wfile.write(data)

def do_GET(self):
    p = urlparse(self.path).path
    if p == "/broken/error":
        return self._send(
            500,
            "RuntimeError: SQLSTATE boom at /secret/path with token=do-not-return",
        )
    if p == "/fixed/error":
        cid = str(uuid.uuid4())
        print("PRIVATE_LOG", cid, "RuntimeError redacted")
        return self._send(500, f"something went wrong correlation_id={cid}")
    return self._send(
        200,
        "Cyberlium A10 safe-error toy. DEMO writeup: http://192.168.0.1/ "
        "GET /broken/error  GET /fixed/error",
    )

print("bind", HOST, PORT)
print("demo_writeup_url http://192.168.0.1/")
print("if 192.168.0.1 is a router, curl", f"http://{HOST}:{PORT}/")
HTTPServer((HOST, PORT), Handler).serve_forever()
PY

Command — copy this

cat > a10_l02_practical_commands.sh << 'SH'

echo; cat /tmp/a10_leak.body; echo

echo; cat /tmp/a10_safe.body; echo

SH

Command — copy this

{

Mission: error-leak-notes.txt (mode 600)

1) 0.0.1:8775 after starting a10_safe_error_toy.py.2) Compare broken vs fixed error curls. Document public vs private error handling. Confirm debug stacks are off in prod profiles. 3) chmod 600 $HOME/cyberlium-lab/error-leak-notes.txt. No foreign 500 harvesting. No hydra. No nmap.

Stuck? Ask Cyberlium AI Mentor

If “helpful errors” still means “return the stack,” ask for a hint. Try: "Hint only: correlation id pattern; what never returns to clients; why 192.168.0.1 router login is OUT OF SCOPE; where notes live?"

Leaky exceptions are free recon. A10. Original Cyberlium — not official OWASP certification. Next — Unexpected States and Recovery.

Knowledge Check

1

APPLY: API returns full stack with DB path on 500. Fix shape?

Multiple choice

Knowledge Check

2

APPLY: True or False: Production should ship with framework debug pages enabled.

True or False

Knowledge Check

3

APPLY: curl of http://192.168.0.1/ is router admin. Harvest its 500 page for A10?

Multiple choice

← Previous

Answer all 3 knowledge checks to continue. (0/3 answered)