Forums Bug Reports Thread

LTI login forwards attacker-controlled target_link_uri as OIDC redirect_uri without validating it against the registered tool URLs

Patrick Bass · Jun 6 · 11 · 1 Locked
[Minor] [Normal Priority] [Bug Fixed] [Always Reproduces]
🚀 OP Jun 6, 2026 6:45pm

Area: mobieusLearn (audit p8) · Surface: GET|POST /lti/login · Dimension: security · Severity: minor

LTI 1.3 §5.1.1.1 requires the tool to ensure target_link_uri matches a registered redirect URI before using it. Here the platform's auth_login_url (trusted) is the redirect target, so the immediate browser navigation stays on the LMS; the risk is that the redirect_uri we hand the LMS is attacker-chosen, which (a) can confuse/mis-route the eventual id_token form_post depending on the LMS's own redirect_uri validation, and (b) is a deviation from spec that some LMSs will reject and others will honor. Practical exploitability depends on the LMS, so this is minor rather than a confirmed open redirect, but it is an unvalidated-redirect-parameter pattern.

Evidence

platform/src/Controllers/Learn/LearnLtiController.php:58 `$targetLinkUri = (string)($params['target_link_uri'] ?? '');` then line 103 inside http_build_query: `'redirect_uri' => $targetLinkUri,` — the value is taken straight from untrusted GET/POST and placed into the OIDC auth request as redirect_uri, with the only validation being the non-empty check at line 62. There is no allowlist tying target_link_uri to the tenant's own /lti/launch URL or the registered platform's expected tool URLs.

Suggested fix. Validate target_link_uri before building the auth request: require it to be an https URL whose host equals the tenant's canonical host (the same tenantHost()/MOBIEUS_TENANT_HOST pinning used elsewhere in this controller) and whose path is an allowed tool launch path (e.g. /lti/launch). Reject otherwise via loginError('invalid_target_link_uri', ...).

Filed by the automated tenant-app audit and adversarially evidence-verified. Status: verified. Open — not yet actioned.


Patrick Bass
@mobieus

🚀 Jun 7, 2026 5:44am

Resolved — fixed and deployed. Commit 059d6bf29b6f, shipped dev-first then to all tenants on 2026-06-06.

Added isAllowedTargetLinkUri() guard called in login() before building the OIDC auth request. The LMS-controlled target_link_uri (which becomes redirect_uri) is now rejected unless it is an https URL whose host case-insensitively equals tenantHost() and whose path is the allowed /lti/launch tool launch path; port/query/fragment/userinfo are also rejected.

Status: fixed. Thread closed and locked.


Patrick Bass
@mobieus

Log in or register to reply to this thread.