Is Canvas Quiz Loader safe?

Medium risk

Quiz Loader is medium risk. Canvas Quiz Loader can send a debug bundle from quiz pages to quiz-loader-production.fly.dev when an error matches debug-config patterns. The bundle holds page HTML, the Canvas ENV object, and log messages: quiz content plus page context.

Alex Shnyrovv0.5.4Chrome Web Store
45Risk
Who publishes it

Alex Shnyrov - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Alex Shnyrov

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Canvas quiz debug bundles sent to external host

Canvas Quiz Loader can send a debug bundle from quiz pages to quiz-loader-production.fly.dev when an error matches debug-config patterns.

The bundle holds page HTML, the Canvas ENV object, and log messages: quiz content plus page context.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You are using a Canvas quiz page when the extension logs a matching error.

The match depends on error patterns loaded from the extension's debug-config endpoint.

The extension did this

The extension builds a text bundle from the page and sends it to quiz-loader-production.fly.dev.

The source includes the page HTML, Canvas environment object, and stored log messages in that bundle.

02EvidenceFIELD TABLE
Fields assembled into the debug bundle
FieldValueWhy it matters
Full quiz page HTML
<html><body><div id="questions"><div class="question_text">Which function describes velocity?</div></div></body></html> (illustrative)This can include quiz text, answer choices, course page structure, and identifiers present in the loaded page.
Canvas environment data
{"COURSE_ID":"18442","QUIZ":{"id":"73109"},"current_user_id":"902144"} (illustrative)This can include the Canvas account, course, quiz, and user context that the page exposes to scripts.
Captured log messages
{"timestamp":"2026-07-12T10:52:05.633Z","type":"error","message":["Unhandled Error:",{"source":"https://school.instructure.com/courses/18442/quizzes/73109/take"}]} (illustrative)Errors and extension logs can reveal what happened on the quiz page and may include source URLs from the failing script.
03EvidenceNETWORK CAPTURE
Captured request
POSThttps://quiz-loader-production.fly.dev/api/v1/debug/bundle
Headers
Content-Typetext/plain
04EvidenceCODE COMPARE
The code that does this

The bundle builder, trigger, and POST request in shipped code

What it actually does
POST helper in deobfuscated codedeobfuscated/quiz-loader/index.js
postDebugBundle(e) {
  return Jn(this, void 0, void 0, (function*() {
    const t = `${this.baseUrl}/api/v1/debug/bundle`,
      n = {
        method: "POST",
        headers: {
          "Content-Type": "text/plain"
        },
        body: function(e) {
          return "function" == typeof e.then
        }(e) ? yield e : e
      },
      o = yield fetch(t, n);
    if (!o.ok) throw new Error(`API request failed: ${o.status} ${o.statusText}`);
    return o.text()
  }))
}
Bundle builder in deobfuscated codedeobfuscated/quiz-loader/index.js
getLogBungle() {
  return Qn(this, void 0, void 0, (function*() {
    const e = [];
    return e.push("--------------- HTML SECTION START ---------------\n"), e.push(document.documentElement.outerHTML), e.push("\n--------------- HTML SECTION END ---------------\n\n"), e.push("--------------- CANVAS ENV SECTION START ---------------\n"), e.push(JSON.stringify(yield this.getQuizEnv(), null, 2)), e.push("\n--------------- CANVAS ENV SECTION END ---------------\n\n"), e.push("--------------- LOGS SECTION START ---------------\n"), e.push(JSON.stringify(this.getLogs(), null, 2)), e.push("\n--------------- LOGS SECTION END ---------------\n\n"), e.join("")
  }))
}
Error-triggered upload in deobfuscated codedeobfuscated/quiz-loader/index.js
error(...e) {
  const n = e.find((e => e instanceof Error));
  this._storeLog("error", ...e.map(t));
  const o = e.join(" ");
  if (-1 !== this.debugConfig.saveBundleErrorPattern.findIndex((e => o.includes(e)))) {
    let e;
    Vn.postDebugBundle(this.getLogBungle()).then((t => e = t)).catch((e => {
      console.error(e), this._storeLog("error", t(e)), Wn.logger.error(e.message, null, e)
    })).finally((() => Wn.logger.error(`${o} bundleId: ${e}`, null, n)))
  } else Wn.logger.error(o, null, n);
  console.error(...e)
}
05EvidenceTHIRD PARTY LIST
External services involved in the debug path
  • quiz-loader-production.fly.dev

    Receives the debug configuration request and the text debug bundle POST.

  • us3.datadoghq.com

    Receives Datadog log events from the same logger; the debug bundle itself is posted to quiz-loader-production.fly.dev.

Updated 30 September 2026pfagnepdndhkmilceinbebdfbmiddagl