New module: Code Snippets – run PHP snippets from the Omeka S admin

Hi everyone,

I’d like to share Code Snippets, a new module that lets a global administrator create and run small PHP snippets directly from the Omeka S admin interface, without editing a theme or writing a full module for every small change.

It is inspired by the WordPress Code Snippets plugin as a functional and UX reference.

Editing a snippet in the Omeka S admin interface

What it does:

  • Create, edit, enable, disable, prioritize and delete PHP snippets from the admin
  • Run location per snippet: everywhere, only in the administration area, or only on the public site
  • Priority to control execution order
  • Editor with PHP syntax highlighting and line numbers (CodeJar, vendored locally, no CDN calls)
  • Syntax is checked before a snippet can be activated, so broken code is never stored as active
  • Runtime errors are captured and shown next to the snippet instead of breaking the page
  • Ships with example snippets, all inactive, ported from well-known WordPress demos
  • Optional REST API at /api/code_snippets (reads only by default; writes must be enabled explicitly)

Safety and recovery:

Snippets run with the privileges of the Omeka S PHP process, so only the global_admin role can manage them, enforced with the Omeka ACL rather than by hiding the UI. If an active snippet ever breaks the site, there is a safe mode: a URL parameter that skips snippets for a single request, and a global constant / environment variable kill switch that disables all of them. The module does not sandbox PHP.

Try it in your browser (no installation, runs on WASM):

Repository: GitHub - ateeducacion/omeka-s-CodeSnippets: Manage and execute trusted PHP snippets from the Omeka S admin interface · GitHub
Latest release: Release 1.0.0 · ateeducacion/omeka-s-CodeSnippets · GitHub

Also available in the Omeka-S module directory.

Feedback, contributions, and bug reports welcome!

Cheers,
Ernesto
GitHub: @erseco

1 Like

Hi, I think this tool is not intended for experienced developers, who would more likely write a module, even for specific custom code, which also requires sufficient rights to access the file system. I am afraid that allowing an admin to inject PHP could represent an additional source of worry for site maintainers and a security breach :thinking:

Thanks for the feedback. The module is actually intended for advanced administrators who occasionally need to perform specific operations without creating and deploying a full module each time.

It is inspired by the WordPress Code Snippets plugin: Code Snippets – WordPress plugin | WordPress.org

Not every customization justifies a dedicated module. Sometimes you need to inject a specific header, apply a small temporary change, or quickly adjust some behavior. This module makes those tasks easier for administrators who understand the implications and risks involved.

At least in our case, this is a very useful workflow.

Well yes, I know the WP module which inspired yours, and I also know the damage this module can cause and the additional time maintainers spend debugging code poorly written because “don’t worry, this is just for testing” and quietly multiply themselves like invasive plants in a garden. A pure maintainer’s nightmare.

I understand that concern, and I think we are discussing two slightly different things now.

What you describe is mainly a governance and maintenance problem: snippets can certainly become technical debt if administrators use them without discipline. The module does not try to prevent a trusted administrator from writing bad PHP, just as filesystem access does not prevent a developer from doing so.

What it does try to address are the risks specific to providing this workflow: access is restricted by ACL, state-changing actions are CSRF-protected, active code is syntax-validated, REST writes are disabled by default, runtime errors are isolated where PHP allows it, and there are both request-level and global safe modes for recovery. These behaviours are also covered by the test suite.

The security model explicitly states that snippets are trusted PHP and are not sandboxed.

So I agree that this is not a tool for every installation or every administrator. It is intended for environments where trusted advanced administrators already need this capability. For us, that trade-off is useful.

If you find a concrete security or implementation issue in the module, I would of course be very interested in it.

Hi Ernesto! I share the concerns of @boregar here. I understand the benefits of this module, having a simple and convenient way to tweak or update Omeka. But it opens some attack vectors I would not want to risk on a production site. For example: the snippets are stored in the database. Anyone who gets access to the database can update the snippet code.

Omeka S modules are not checked by a security team, but you can be sure there are some hidden issues that are future CVEs, we just don’t know them yet.

It would feel safer if snippet code did not have access to the Omeka service manager, but that would cripple the module’s features.

1 Like

Thanks @flamsens I think your database-write scenario was a fair point, and it was useful feedback.

I have addressed that case in version 1.0.2 with an optional hardened integrity mode.

When a signing key is configured outside the database, in Omeka’s config/local.config.php or through an environment variable, active snippets are authenticated with HMAC-SHA256 before execution. The signature covers the executable state of the snippet, including its ID, code, active state, priority and execution scope.

So if somebody modifies a snippet directly in the database, inserts a new active row, changes its code, or simply changes an inactive snippet to active, the signature no longer validates and the snippet is not executed.

The feature is deliberately optional and disabled by default. Existing installations therefore keep the normal snippet-manager trust model unless the administrator explicitly enables this additional protection. Existing unsigned snippets are not automatically trusted when hardened mode is enabled; they must be reviewed and saved again.

The implementation and threat model are documented in 1.0.2, including the important boundary that this protects against direct snippet-table tampering, not against an attacker who has compromised Omeka’s wider authentication/authorization system or obtained the external signing secret.

For context, the WordPress Code Snippets plugin that inspired this module has more than one million active installations and, in the current implementation I reviewed, does not appear to authenticate stored PHP snippets with equivalent per-snippet HMAC signatures. That is not a criticism of its security model, just an indication that this is an additional defense for installations with stricter requirements.

So thanks for raising the specific case, it resulted in a useful additional safeguard :heart_eyes:.

And, ultimately, if minimizing executable attack surface is the overriding security requirement, the safest option is not to install a PHP snippet runner at all. This module is intended for trusted-administrator environments where development agility and the ability to make small, controlled adjustments are part of the trade-off.

Of course I am not questionning the good intention behind your work, and I’m sure you are mindful of the potential consequences of impropre use of that “Swiss Army knife of code”.

Yeah, everyone knows how confident you can rely on an admin’s discipline over time, and especially how clear and up-to-date is the documentation of their hacks :grin:

This is probably the origin of the discussion. When you’re on the road, safety is not relative to distance: whether your route is 100m or 1000km long, the same safety measures and driving rules apply. So it’s worth not taking the easy way, I would better create a multi-purpose module which you can add new fonctionnalities to over time, like Daniel-KM’s Easy Admin module for example (even if this is a somewhat extreme case :sweat_smile:).

I would rather make a suggestion: prevention is the best form of protection, so you could add some guidelines/best practices/code of conduct highlighting the responsibility of a snippet’s author.