Security Model
bulletinbored is built for a single trusted administrator who installs plugins,
themes, language packs, and updates. The security model therefore assumes that
installing code is a deliberate act of trust in its source (the author / the
repository).
What is hardened
- Zip Slip is mitigated everywhere a package is extracted.
PluginManager,
ThemeManager,UpdateManager, and the sharedextract_zip()all validate every
archive entry and reject..path traversal and absolute paths before writing. - Language packs are JSON and never executed. Uploaded or installed translation
files are parsed as plain data (string → string), so a malicious language file
cannot lead to remote code execution. - User content is sanitized. HTML saved by the editor is filtered by
sanitize_html(): scripts/styles are stripped, genericdiv/span,id, inline
style, and arbitrarydata-*attributes are removed, and event handlers
(on*) are dropped. Output is served under a per-request nonce-based CSP. Social
embeds (YouTube, Twitter/X, Instagram, Facebook) are permitted only from a fixed
host allow-list. - Installer files do not re-appear after a core update.
applyCoreUpdate()
removesinstall.php,install2.php,install3.php, andapi/install.phpfrom a
deployed root once the forum is installed (config.jsonpresent). On a fresh
install (noconfig.json) the scripts are kept so setup can run.
Installing code is an act of trust
Plugins and themes are PHP code that is included by the forum. A malicious package
therefore means remote code execution. Because distribution is decentralized
(anyone can publish a plugin/theme on any Git host), there is no central signing
authority and bulletinbored does not implement cryptographic signature
verification of packages.
Consequences for the operator:
- Installing or updating a plugin/theme means you trust its author and its source.
This is by design for a decentralized ecosystem. There is no “safe” automatic path:
even when a package comes from the curated catalog, an update applies a new
package from that same source without a human re-reviewing the diff. You cannot
pre-approve updates in a meaningful way without trusting the source — doing so
would undermine the decentralized nature of the system. - As defense-in-depth, keep
plugin_verify_files/theme_verify_filesenabled
(on by default). At install time the package is checked against thefileslist in
itsmanifest.json; a package that ships files not declared in the manifest
(e.g. a dropped-in backdoor) is rejected. Note: this catches added files, not a
manifest that itself was updated to include the malicious file — so it is a guard,
not a guarantee. catalog-onlymode (allow_catalog_only) restricts installation toofficial: trueentries from the curated catalog. It reduces the set of sources to curated
ones, but it does not give you pre-approval of updates: a curated source can
still publish a new version at any time.
Curated catalog: first-party vs third-party
The catalog mixes components developed by the bulletinbored team (first-party)
and components developed by the community (third-party). The catalog UI labels
each one accordingly (“Developed by bulletinbored team” vs “Developed by third party”)
so you can see at a glance what is first-party and what is not.
Every catalog entry — first-party or third-party — is reviewed by the bulletinbored
team before being added to the catalog. Even so, bulletinbored does not assume
any responsibility for the code, security, or behavior of third-party plugins/themes:
installing one remains an act of trust in its author. If a third-party (or first-party)
component is later found to be malicious, bulletinbored will remove it from the catalog
as soon as it is reported by a user — see Reporting below.
The pre-catalog review reduces risk but is not a guarantee: a component can be
compromised after publication (e.g. via an update), and reviews are best-effort.
Keep*_verify_filesenabled and treat any installation as trusting the source.
Bottom line: only install plugins/themes/updates from sources you trust. Keep
*_verify_filesenabled, prefercatalog-onlymode if you want a smaller trusted
surface, and review third-party code before deploying it on a production forum with
untrusted users.
Hardening options in config.json
| Key | Default | Effect |
|---|---|---|
plugin_verify_files |
true |
Reject plugin packages whose extracted files don’t match manifest.json files. |
theme_verify_files |
true |
Same check for themes. |
allow_catalog_only |
false |
When true, only official: true catalog entries can be installed. |
See Configuration for details.
Reporting
If you encounter a malicious or problematic plugin/theme, report it on the official
forum: www.bulletinbored.net/forum.