Files
bambuddy/backend
maziggy 5c1c0914f4 Explain Bambu Cloud's CAPTCHA challenge instead of repeating it (#2790)
A reporter tried to connect to Bambu Cloud and got "We need you to confirm you
    are not a robot" as an error toast, with no CAPTCHA anywhere to answer and
    nothing to click. That sentence is Bambu's, not ours. Their anti-abuse layer had
    flagged the network and was answering the sign-in with HTTP 418 and a challenge
    body: {"captchaId": "...", "error": "We need you to confirm you are not a
    robot"}.

    Bambuddy had no idea what that was. The reply is well-formed JSON, so
    _detect_cloudflare_challenge -- which triggers on an unparseable body, CF
    markers, 403+cf-mitigated or 503+cf-ray -- never fired on it, and login_request
    fell through to its generic error path, which lifts data["message"] or
    data["error"] out and hands it to the UI verbatim. The user was left to conclude
    their password was wrong or that Bambuddy was broken. Four sign-in attempts
    inside eighteen seconds appear in their log, each one more evidence for the
    thing that had flagged them.

    is_captcha_challenge matches on the 418 status plus a challenge marker in the
    body -- captchaId is the reliable one, the wording is matched too because Bambu
    has shipped it under more than one phrasing. A bare 418 with no marker is
    has shipped it under more than one phrasing. A bare 418 with no marker is
    deliberately NOT reported as a CAPTCHA: telling someone to solve a challenge
    that was never offered is the exact confusion this issue is about.

    login_request, verify_code and verify_totp now return reason="captcha" with an
    explanation covering the three things the reporter had no way to find out: the
    credentials are not the problem, the block is keyed to the public IP address
    rather than the account, and it clears by itself within a few hours.

    Sign-in requests are then held back for 300s so Bambuddy stops deepening the
    block. Keyed per origin, not per service: TOTP verification posts to
    bambulab.com while everything else posts to api.bambulab.com, and a challenge
    seen on one must not strand somebody halfway through a two-factor sign-in on the
    other. Entries expire on read, so the map cannot grow past one per region. The
    token endpoint is deliberately left ungated -- it is the way out.

    The UI shows a persistent panel rather than a toast. A toast names a problem the
    user cannot act on and then vanishes; this one stays put and carries a one-click
    route to "Use access token instead", which is the only thing that works while
    the challenge lasts, since that path does not touch the challenged endpoint.

    MakerWorld meets the same challenge from the same edge and now shares the
    detection. It used to require the literal word "robot" in the error text and
    reported any other wording as an unexplained block.

    The System Health scanner gets a bambu-cloud-captcha signature. The reporter's
    bundle came back with zero findings while their log was full of the failure.

    Its advice for a failed FTPS handshake was corrected at the same time: it still
    blamed firewalls and outdated firmware, which the #2780 investigation ruled out
    last release -- it is the printer's own file service wedging, and the fix is to
    restart the printer. The wiki said so already; the health panel did not.
2026-08-15 14:42:27 +02:00
..