For the complete documentation index, see llms.txt. This page is also available as Markdown.

Raw code in admin fields

The 'code' data type

Notes on e_admin_ui / e_admin_dispatcher behaviour that is not obvious from the documentation, and that cost time to work out. Everything below was verified against the e107 core source (e107inc/e107, 2.4.x branch); line numbers are approximate and given as a pointer, not a promise.


1. Storing raw HTML/JS in a field: 'data' => 'code'

Symptom. You paste a <script> snippet into an admin field and e107 refuses it:

You don't have permission to use <script> tags. If you believe this is an error, please ask the main administrator to grant you script access via Preferences > Content Filters.

Do not fix this by granting site-wide script access. That loosens the content filter for the entire site because of one field.

Why it happens

A field declared 'data' => 'str' goes through e107_model::sanitize() (e107_handlers/model_class.php):

case 'str':
case 'string':
case 'array':
    $ret = $tp->toDB($value, false, false, 'model', ...);

toDB() calls cleanHtml(), which consults the site-wide post_script preference and strips script tags unless the current user's userclass passes check_class().

The trap behind the trap

Granting script access still would not work for an AdSense-style snippet. The set of attributes e107 allows on a <script> tag is hardcoded in e_parse_class.php:

crossorigin is not in that list, so crossorigin="anonymous" gets stripped anyway. There is no pref that changes this.

The fix

Use the 'code' data type. It exists for exactly this purpose (model_class.php):

And in toDB() (e_parse_class.php):

The core docblock above toDB() says it directly: the 'pReFs' value is for internal use when saving prefs, to prevent sanitisation of HTML.

Security note

'code' means zero sanitisation on that field. It is stored-XSS-as-a-feature. Use it only when:

  • the field genuinely has to hold raw markup (ad code, tracking snippets, embeds), and

  • write access to the admin page is restricted to the main admin (getperms('0')).

Those two decisions depend on each other. If the permission is ever relaxed, 'code' has to go with it. Say so in a comment above the field — the next person will not know.


Last updated