From b934b386cd768aca43ef3af7937a6eabcab80b99 Mon Sep 17 00:00:00 2001 From: M Alhassoun <130248345+boxlinknet@users.noreply.github.com> Date: Sun, 8 Nov 2026 13:38:49 +0300 Subject: [PATCH] Examples: no debug mode by default, generic client errors, single-line error logs --- examples/08-flask.py | 22 ++++++++++++++-------- examples/09-fastapi.py | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/08-flask.py b/examples/08-flask.py index 2508e56..521a79f 100644 --- a/examples/08-flask.py +++ b/examples/08-flask.py @@ -22,10 +22,16 @@ from __future__ import annotations +import os import secrets import time from typing import Dict + +def _one_line(value: object) -> str: + """Log-safe text: CR and LF removed so a value cannot forge log lines (2026-11-08 example hardening).""" + return str(value).replace("\r", " ").replace("\n", " ") + # ── Flask application factory ──────────────────────────────────────────────── try: @@ -83,7 +89,9 @@ def health(): ok, balance, error = get_sms().verify() if ok: return jsonify({"ok": True, "balance": balance}) - return jsonify({"ok": False, "error": error}), 503 + # 2026-11-08 13:38 +03: details stay in the server log, the client gets a generic message (CodeQL stack-trace-exposure) + app.logger.error("kwtSMS verify failed: %s", _one_line(error)) + return jsonify({"ok": False, "error": "SMS gateway unavailable"}), 503 @app.post("/otp/send") def otp_send(): @@ -111,7 +119,7 @@ def otp_send(): if result["result"] != "OK": # Log the error server-side, but never expose raw API codes to clients - app.logger.error("kwtSMS send failed: %s", result) + app.logger.error("kwtSMS send failed: %s", _one_line(result)) # 2026-11-08 13:38 +03: no newlines in logs return jsonify({"error": "Could not send verification code. Try again."}), 500 _otp_store[phone] = { @@ -187,11 +195,9 @@ def sms_send(): "balance_after": result.get("balance-after"), }) - return jsonify({ - "ok": False, - "code": result.get("code"), - "error": result.get("description"), - }), 500 + # 2026-11-08 13:38 +03: API error details go to the server log only (CodeQL stack-trace-exposure) + app.logger.error("kwtSMS send failed: %s", _one_line(result)) + return jsonify({"ok": False, "error": "Could not send the SMS. Try again."}), 500 return app @@ -209,4 +215,4 @@ def sms_send(): print(" POST /otp/send (send OTP)") print(" POST /otp/verify (verify OTP)") print(" POST /sms/send (send arbitrary SMS)") - app.run(debug=True) + app.run(debug=os.environ.get("FLASK_DEBUG") == "1") # 2026-11-08 13:38 +03: never debug by default diff --git a/examples/09-fastapi.py b/examples/09-fastapi.py index 3498b07..1a7b92d 100644 --- a/examples/09-fastapi.py +++ b/examples/09-fastapi.py @@ -134,7 +134,7 @@ def otp_send(body: OTPSendRequest): if result["result"] != "OK": # Log full error server-side; never expose raw API codes to clients import logging - logging.error("kwtSMS send failed: %s", result) + logging.error("kwtSMS send failed: %s", str(result).replace("\r", " ").replace("\n", " ")) # 2026-11-08 13:38 +03: no newlines in logs raise HTTPException(status_code=500, detail="Could not send verification code. Try again.") _otp_store[phone] = {