Overview
Question Hub (qbank_questionhub) is a plugin for the Moodle question bank. You use it to find question packages on the Question Hub, import them into your course with a preview, and publish your own categories as packages that other teachers can bring into their Moodle.
The Question Hub at hub.cblum.ch is a separate service, also run by Cyril Blum. The plugin is aimed at teachers at Swiss upper secondary schools (Gymnasium) and needs Moodle 4.5 or later. It is tested with Moodle 4.5 and 5.0.
Screenshots
These are the same two images as in the Moodle plugins directory. Cyril Blum took them on 14.10.2026 on a Moodle test site, in the test course DEMO101 with the test account «Admin User». The questions shown come from his own question collection. No student data is visible.
The captures show an older plugin version. Some labels have changed since, for example the status «Synchronised» is now called «Linked». Select an image to preview it on this page and use the arrows to move between the captures.
Detailed description
Built into the question bank
The plugin adds a «Question Hub» tab to the question bank with the areas «Browse», «My library» and «My packages». The question list gets an action to export single questions, a bulk action to publish selected questions and a «Hub» column. It shows whether a question matches the linked version on the Hub, was modified since, or is new.
Finding and importing packages
Packages can be filtered by keyword, subject, course level (GF, SF, EF, FF) and canton. If the author allows it, the Hub shows a preview of the questions without model answers and feedback. Before every import you see which questions will be added, updated or skipped. Questions changed both on the Hub and in your Moodle appear as conflicts, and you decide for each question which version applies or whether to keep both. If you take the Hub version, your version stays in the question’s version history. Without a linked Hub account you can browse and import public packages.
Publishing your own categories
A question bank category is published with its subcategories as a package in Moodle XML format. You enter a title, summary, release note, tags, subject, level and canton and choose a licence (CC BY 4.0, CC BY-SA 4.0 or CC0) and the visibility. Public packages are open educational resources. Private ones are visible only to people whose access request you approve. Optionally, the Hub also commits every version to a GitHub repository.
Versions, push and pull
Version numbers follow the pattern 1.2.3 and cannot be changed. «Push» publishes local changes as a new version, «Pull» brings in a newer version from the Hub. Before a push, the plugin shows the changed questions line by line. Under «Review changes» you keep or discard local changes one by one. Older versions can be restored with a preview, and you can withdraw single versions or a whole package from the Hub. Questions already imported stay in the other Moodle sites.
Variants and change proposals
From an imported package you can create your own variant on the Hub. Your category is then linked to the variant, and you propose your changes to the original through the Hub. A variant keeps the licence of the original and names it as its source. «Switch variant» links a category to the original or another variant after a preview.
Cleaning up
The plugin finds identical duplicates and keeps the oldest question of each group. Questions with the same name but different content in one category are listed for comparison. Questions used in a quiz are never deleted.
Permissions and backup
By default, teachers may browse and export, while editing teachers and managers may also import and publish. A Moodle backup with questions includes the links to the Hub, so they survive a restore. How accounts are linked and how imports are checked is shown under Data flows and Security.
Architecture
Question Hub consists of the plugin and the Hub. The plugin is the only component installed in a school Moodle. The Hub at hub.cblum.ch is a separate web platform with an API that stores accounts and question packages in versions. Every Moodle with the plugin can publish and import packages.
Plugin qbank_questionhub
«Question Hub» tab in the question bank, «Hub» column in the question list, import with preview and publishing. In its own tables it stores tokens, a log and the mapping of questions to package versions.
Question Hub
Website and API for accounts, packages, versions, variants and change proposals. Public packages can be browsed and imported without an account. You need a Hub account to publish or to use private packages.
GitHub mirror
Whoever manages a package can link it to their own GitHub repository. The Hub then stores every new version there as an XML file and sets a version tag. The plugin itself never connects to GitHub.
Data flows
Publishing and push
- You choose a category or single questions and enter the package details.
- The plugin exports the questions as Moodle XML and checks the package first.Check in the plugin
- Moodle sends the package with your token to the Hub.HTTPSToken
- The Hub checks XML, size, question types and media and stores a new, immutable version.SHA-256
- If the package is linked to GitHub, the Hub also commits the version to the repository.optional
Import and pull
- You look for a package. Public packages are available without a linked account.
- Moodle downloads the chosen version from the Hub.HTTPS
- The plugin checks the package and removes active content if the setting is on.Check in the plugin
- The preview shows new, updated and skipped questions as well as conflicts.
- After you confirm, the questions go into the question bank. The previous version of an updated question stays in its version history.
Both sequences show where the questions go. Moodle opens the connection on import too.
Sign-in: linking a Moodle account to a Hub account
To publish, push or use private packages, each teacher links their Moodle account to their Hub account. There are two ways. The Moodle password never goes to the Hub, and the Hub password is never entered in Moodle.
OAuth 2.0 with PKCE
You choose «Connect Question Hub Account» in the plugin and sign in directly on hub.cblum.ch. Moodle receives a token that is valid for 30 days. The address of your Moodle has to be approved on the Hub. On disconnect, the Hub revokes the token.
Personal access token
You create a token on the Hub with a lifetime of your choice and paste it into the plugin. This works without approval of your Moodle. The Hub stores only a SHA-256 hash of the token. On disconnect, the plugin deletes the token in Moodle; you delete it on the Hub yourself.
The setting «Allow Teacher Account Linking» lets administrators switch linking off. Teachers can then only browse and import public packages.
Security and encryption
The cards show how the plugin and the Hub protect connections, credentials and packages. The yellow card names what is deliberately not used.
Transport
The plugin and the browser talk to the Hub over HTTPS, and the default Hub address is https://hub.cblum.ch. The Hub accepts only TLS 1.2 and 1.3, redirects HTTP to HTTPS and sends HSTS (checked on 12.11.2026).
Tokens
OAuth tokens are valid for 30 days and are revoked on the Hub on disconnect. The Hub stores personal access tokens only as a SHA-256 hash. In the Moodle database the token is stored without extra encryption, so it is as safe as the database itself.
Hub accounts
The Hub stores passwords as scrypt hashes with their own salt. Sign-in and registration need a captcha and are rate-limited per client. A password reset link is valid for one hour and only once, and only its SHA-256 hash is stored.
GitHub token
Using the GitHub mirror means storing a GitHub token on the Hub. The Hub keeps it encrypted with AES-256-GCM and uses it only for commits through the GitHub API over HTTPS.
Package versions
Published versions are immutable, and a correction gets a new version number. The Hub computes a SHA-256 checksum for every version and sends it along with the download. The plugin detects changed questions through its own SHA-256 values of the question content.
XML checks
The plugin and the Hub reject XML with DOCTYPE, ENTITY or XInclude declarations. The checks cover, among others, multiple choice, true/false, short answer, numerical, matching, embedded answers (Cloze) and essay questions, embedded images and files, size limits (50 MB per package, 10 MB per file) and scripts in SVG files.
Active content
Because anyone can publish on the Hub, the plugin removes active content such as scripts and embedded frames by default, using Moodle’s HTML cleaning. Administrators can switch on an exception for CodeRunner questions. If active content is kept, the teacher has to confirm the import explicitly. Scripts created only at run time are not detected.
Code review
A self-review on 26.10.2026 with AI support and standard tools found seven issues, fixed in version 1.0.33. Every change runs tests with Moodle 4.5 and 5.0, the Moodle coding style check and Semgrep on GitHub. There has been no independent audit or penetration test.
Not used
Packages carry no digital signature. The checksum shows whether a file was changed, but does not protect against a tampered Hub. E-mails from the Hub are encrypted only on the way to the mail server (STARTTLS), not end to end.
Installation and configuration
Install the plugin from the Moodle plugins directory or put the source from GitHub into the folder question/bank/questionhub of your Moodle site:
git clone https://github.com/CyrilBlum/moodle-qbank_questionhub.git question/bank/questionhub
php admin/cli/upgrade.php --non-interactive
php admin/cli/purge_caches.php
The settings are under Site administration, Plugins, Question bank plugins, Question Hub:
- Hub base URL, default
https://hub.cblum.ch. - OAuth 2.0 client ID, default
moodle-plugin-client. Change it only if the Hub operator asks you to. - Allow teacher account linking (on). When it is off, teachers can only browse and import public packages.
- Remove active content on import (on).
- Keep active content in CodeRunner questions (off), an exception to the previous setting.
«Test connection» checks whether the Hub is reachable and your own linked account is valid. For teachers to link their account with OAuth, the address of your Moodle has to be approved on the Hub. Write to apps@cblum.ch for this. You create a Hub account at hub.cblum.ch.
Files
The plugin follows the usual layout of a Moodle plugin:
Basics
version.php: name, version and required Moodle version.settings.php: settings in site administration.
Pages
view.php: Hub view with search, import, library and your own packages.publish.php: export and publish categories and questions.review.php: review local changes since the linked version.variants.php: compare questions with the same name but different content.oauth_callback.phpanddisconnect.php: link and disconnect a Hub account.testconnection.php: connection test from the settings.
Program logic
classes/: program logic, including the Hub client (api_client.php), sign-in and tokens (auth_manager.php), export (package_exporter.php), import (package_importer.php,qformat_xml_importer.php), the import check (preflight_validator.php), version comparison and links (release_diff.php,local_changes.php,publication_tracker.php), duplicates (duplicate_manager.php), the question bank integration (plugin_feature.php,navigation.php,question_action.php,bulk_publish_action.php,question_sync_column.php) and the privacy API (privacy/provider.php).
Database and backup
db/: capabilities (access.php), database tables (install.xml) and upgrade steps (upgrade.php).backup/moodle2/: backup and restore of the Hub links.
Interface
templates/: Mustache templates of the interface.amd/src/andamd/build/: JavaScript modules and their minified builds.lang/en/andlang/de/: English and German strings.pix/,styles.css: icon and styling.
Tools and tests
cli/: command-line export, import and self-test.tests/and.github/workflows/: automated tests that run on GitHub with Moodle 4.5 and 5.0.
Privacy
Plugin tables
- Hub access token for each linked person, with Hub user ID, email address and display name of the Hub account
- log of imports and publications with Moodle user ID, package ID, version, action and time
- mapping of imported questions to package versions
Moodle’s privacy API can export and delete this data.
What the plugin sends
- the access token, but not the Moodle username, name or email address
- questions and package details only when someone publishes, pushes, forks or edits a package
- for OAuth linking, the address of the Moodle site as the redirect address
Separate service
- Hub account with email address, name, school, canton and password hash
- packages with all versions, contributors and access requests
The Hub is a separate service with its own data processing.
No personal data in questions
Questions must not contain personal data, so no student names or grades, also not in images or feedback. The plugin points this out but cannot prevent it technically. The plugin never transfers quiz attempts, answers, grades or participant lists.
Use and liability
The Hub may be unavailable at times, and authors can withdraw packages. Questions already imported stay in your Moodle. You are responsible for content you publish, including copyright and the licence you choose. Back up your course or question bank before larger imports.
Use is at your own risk. To the extent permitted by law, the plugin is provided without warranty of accuracy, completeness, availability or fitness for a particular purpose. To the extent permitted by law, liability for damage from use or unavailability is excluded, in particular for data loss, lost profit and consequential damage. Mandatory statutory rights and liability remain unaffected, in particular for intent or gross negligence and where liability for personal injury cannot be excluded. The source code is licensed under the GNU General Public License v3 or later.
Feedback and development
Found a problem or have an idea for Question Hub? Open an entry in the plugin’s GitHub issues or write to apps@cblum.ch.
The issues are public and can be read without logging in. A new entry needs a GitHub account. Do not post personal data there.
Source code and links
Repository: public. The source code is licensed under the GNU General Public License v3 or later.
The source code of the Hub is in its own repository, which is also public: Moodle-Question-Hub-Marketplace.
Repository status and links checked on 12.11.2026. Published in the Moodle plugins directory on 11.11.2026. Back to the project overview