Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions examples/08-flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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():
Expand Down Expand Up @@ -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] = {
Expand Down Expand Up @@ -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

Expand All @@ -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
2 changes: 1 addition & 1 deletion examples/09-fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -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] = {
Expand Down
Loading