Privacy protection and quiz tools for Canvas LMS. Free, open source, runs entirely in your browser with no remote servers.
Status: Work in Progress — The core Privacy Guard is functional. The AI Answer Engine is partially working and needs further testing. Not all features are verified on live Canvas yet. Use at your own risk and test locally before relying on it.
Prevents Canvas from detecting tab-switching, window switching, and loss of focus during quizzes and tests.
- Overrides
document.visibilityStateto always return"visible" - Overrides
document.hiddento always returnfalse - Overrides
Document.prototype.hasFocus()to always returntrue - Intercepts
addEventListeneron prototypes anddocument/windowinstances to silently block registration of tracking events (focus,blur,visibilitychange,mouseleave,pagehide,paste,copy,cut,freeze,resume, and more) - Intercepts
dispatchEventto block programmatic firing of tracked events - Runs synchronously at
document_startbefore any page scripts can register listeners
If the Privacy Guard is removed, bypassed, or the page tries to unpatch the overrides, the killswitch immediately replaces the page with a fake Chrome "Aw, Snap! OUT_OF_MEMORY" crash screen. This prevents Canvas from detecting that you were ever unprotected.
Automatically fetches your previous quiz submission history from your school's Canvas API, identifies your highest-scoring answers for each question, and auto-fills them when you hover over the question.
Supported question types: Multiple choice, True/false, Fill-in-the-blank, Multiple answers, Matching, Numerical, Essay.
Injects a fake Canvas Kiosk App navigation bar at the top of your tab.
Connects to your own LLM API to answer quiz questions. Supports any OpenAI-compatible endpoint.
Three answer modes:
| Mode | Behavior |
|---|---|
| Hover Hint | Hover over a question to see the AI-highlighted correct answer |
| Right-Click | Right-click on a question to auto-fill the answer |
| Keybind Type | Hover over a question and press a key to auto-type the answer |
- Download or clone this repository
- Open Chrome and navigate to
chrome://extensions/ - Enable Developer mode (top right toggle)
- Click Load unpacked and select the
canvashackfolder - The extension icon will appear in your toolbar
If you want to use the included test page (test-page.html):
- Go to
chrome://extensions/ - Find CanvasHack and click Details
- Enable "Allow access to file URLs"
- Reload the extension
The AI feature requires an API key from an LLM provider. Recommended free option:
- Go to openrouter.ai
- Create a free account
- Go to Keys in your dashboard
- Click Create Key and copy it (starts with
sk-or-) - In the CanvasHack popup, paste the key — OpenRouter is auto-detected
- Select a free model (look for the (Free) label)
- Click Test Connection to verify
Other supported providers: OpenAI, Google Gemini, Groq, Together AI, Hugging Face, Mistral AI, DeepSeek, Cohere, Cloudflare Workers AI, and local models via Ollama.
- Click the CanvasHack extension icon to open the popup
- Click the AI Answer Engine card
- Paste your API key (provider auto-detected from key format) or select from dropdown
- Select a model
- Click Test Connection to verify
- Choose an answer mode
- Click Save AI Settings
A test page is included at test-page.html. Open it via file:// in Chrome to test:
- 10 questions of various types
- Click answers and submit for grading
- Right panel simulates what Canvas would report to a teacher
- Green = BLOCKED (guard working), Red = LEAKED (guard broken)
- Open browser console and run
testAutoType()to test auto-type mechanism - Run
testAPI()to test your API connection from the page
canvashack/
manifest.json Extension manifest (Manifest V3)
background.js Service worker — message handling, API test proxy
content.js Content script — injects guard, kiosk bar, feature scripts
inject.js MAIN world — overrides visibility/focus, blocks events
quizanswers.js MAIN world — auto-fills from Canvas API submissions
ai-answers.js MAIN world — AI-powered answer system
popup.html/js/css Extension popup dashboard
test-page.html/js Local test page mimicking Canvas quiz
README.md This file
content.js runs in the isolated content script world at document_start. It immediately (synchronously) reads inject.js via XHR and injects it into the MAIN world via script.textContent. This guarantees inject.js runs before any page scripts. Feature scripts (quizanswers.js, ai-answers.js) are injected later as <script src> elements after async settings load.
content.js (isolated, document_start)
├─ Phase 1 (sync): inject.js → MAIN world via script.textContent
└─ Phase 2 (async): quizanswers.js, ai-answers.js → MAIN world via script src
popup.js ↔ background.js (message passing for API test)
popup.js → chrome.storage.local → content.js
Settings stored in chrome.storage.local:
| Key | Default | Description |
|---|---|---|
answerSaver |
true |
Fetch and auto-fill previous best answers |
privacyGuard |
true |
Privacy guard on/off |
killswitch |
true |
Crash page if guard is removed |
kioskSpoof |
false |
Show fake kiosk browser bar |
aiMode |
"off" |
Answer mode: off, hover, rightclick, keybind |
aiProvider |
"openrouter" |
Auto-detected LLM provider |
aiApiKey |
"" |
Your API key |
aiModel |
"google/gemma-4-26b-a4b-it:free" |
Default model |
aiEndpoint |
OpenRouter URL | API endpoint |
aiKeybind |
"y" |
Key to trigger auto-type |
aiAutoTypeSpeed |
50 |
Milliseconds between characters |
blockedUrls |
[] |
URLs to skip |
showInjectedUI |
true |
Show on-page UI |
The extension makes zero connections to any external server operated by the extension authors. All features run in your browser:
- Privacy Guard overrides local browser APIs only
- Answer Saver calls your school's Canvas instance only
- Kiosk Spoof is purely local DOM injection
- AI Answers calls only the endpoint you configure
- API keys are stored in
chrome.storage.localand never sent anywhere except your chosen endpoint
Free and open source.