#14582·omi

[Bounty proposal] security(ms365): reflected HTML injection in setup uid and OAuth error page ($50 proposed)

Author: AllProjectschatCreated Sep 18, 2026Updated Sep 18, 2026

Summary

Current main in plugins/omi-ms365-app/main.py renders two query parameters into HTML without context-appropriate escaping.

  1. GET /setup/ms365?uid=... builds redirect = f"/auth/microsoft?uid={uid}" and interpolates it directly into an href attribute.
  2. GET /auth/microsoft/callback?error=...&error_description=... returns both values directly inside a <pre> element before any OAuth state/code validation.

This creates reflected HTML/script-injection sinks on unauthenticated routes. I found this by source review; I did not probe a deployed service.

Source evidence

At current main commit 9a83442 from a fresh clone:

python
redirect = f"/auth/microsoft?uid={uid}"
...
<p><a href="{redirect}"

and:

python
if error:
    return HTMLResponse(
        f"<h3>Authorization failed</h3><pre>{error}: {error_description}</pre>",
        status_code=400,
    )

The callback error branch is reached before code/state validation, so no valid OAuth session is required for the sink.

Duplicate check

I searched this repository's issues for ms365 XSS, ms365 Authorization failed, and PRs for ms365 escape; no matching report appeared. This is distinct from the recent escaping work in other plugin apps.

Proposed fix / acceptance criteria

  • HTML-escape error and error_description before rendering.
  • Percent-encode uid when it becomes a query-string value and HTML-escape the final attribute value (or build the URL with a safe URL helper).
  • Add hermetic regression tests covering quote/tag payloads plus ordinary uid=abc123 and error=access_denied.
  • Preserve current successful OAuth behavior.

Bounty proposal

Would you approve a US$50 bounty for a tested fix + regression suite under Omi's contribution/bounty-suggestion process? This is a proposal only; no approval or payment is assumed.

Disclosure: source review and report preparation were performed with AI assistance on behalf of the account owner. No live target was exploited or modified.