Skip to the content
Documentation
Manuals

Evaluating an old extension before you use it

A checklist with commands to judge an extension you did not write: license, PHP 8 syntax, removed functions, access checks, escaping, SQL, inline scripts and database changes.

  • Topic type: Concept
  • For: Visitors Developers Designers Application creators
  • doc.help.extension-development.part-1-from-user-to-developer.evaluating-c85dcec8
  • Last changed
  • JSON
On this page

Part 1, chapter 17. An extension runs with the full rights of the kernel: it can read every table, every file the web server can read, and every visitor's request. Before you install one you did not write, or decide to adopt one, spend half an hour with this checklist. All commands run on a development installation, with the extension unpacked but not yet switched on.

1. License and origin (5 minutes)

  • To do: A license file exists and allows what you plan to do (Reading licenses before you reuse anything).
  • To do: ezinfo.php and extension.xml agree on name, version and license.
  • To do: You know where it came from: a repository with history, a Packagist package, a project page.

2. Does it parse on PHP 8? (2 minutes)

find extension/<name> -name '*.php' -print0 | xargs -0 -n1 php -l | grep -v '^No syntax errors'

No output means every file parses. Any line printed is a file PHP 8 refuses; typical causes are listed in PHP 8 errors that stop old code.

3. Removed and deprecated functions (5 minutes)

grep -rnE '\b(each|create_function|split|ereg|eregi|mysql_[a-z_]+|money_format|get_magic_quotes_gpc|utf8_decode|utf8_encode)\s*\(' extension/<name> --include=*.php
grep -rnE 'function\s+([A-Za-z_]+)\s*\(' extension/<name> --include=*.php | head -50

The first search finds functions PHP 8 removed or deprecates; each has a replacement in Removed PHP functions and their replacements. The second lists the methods, so you can spot old-style constructors: a method with the same name as its class. PHP 8 no longer calls such a method as a constructor, so the object is created without being set up. The template operator extension str_replace, still in its original 2005 shape in the kernel tree, is exactly that case: its operator class sets its operator list in function MyStrReplaceOperator(), which PHP 8 never calls, and the template engine reports "Object problem with operator 'ezstr_replace'". The fix is one line, shown in Old-style constructors and static calls.

4. Can every class load? (2 minutes, after switching it on in development)

php bin/php/ezpgenerateautoloads.php -e
php bin/php/checkclasses.php --quiet-ok

checkclasses.php loads every class of the installation in a child process and names the ones PHP refuses. Add --allow-root-user when you run it as root.

5. Access control (5 minutes)

Open every modules/<module>/module.php:

grep -n "ViewList\|'functions'\|FunctionList" extension/<name>/modules/*/module.php
  • To do: Every view that shows or changes data names a 'functions' entry.
  • To do: $FunctionList declares those functions, so they can be granted through roles.
  • To do: Views that change data only act on POST and check the form token (see ezformtoken and CSRF protection).

A view without 'functions' can be opened by anyone who can reach the site.

6. Escaping in templates (5 minutes)

grep -rnE '\{\$[a-zA-Z_.]+\}' extension/<name>/design | grep -v '|wash' | head -30

Variables printed without |wash are a cross-site scripting risk when their value can come from a visitor (a view parameter, a form field, a search word). Not every hit is a bug (a number from the kernel is safe), but each one deserves a look. See Security in extensions.

7. SQL (5 minutes)

grep -rnE '(query|arrayQuery)\s*\(' extension/<name> --include=*.php | head -30

For each query built from variables:

  • To do: strings go through $db->escapeString(),
  • To do: numbers are cast with (int),
  • To do: or better, the code uses eZPersistentObject instead of hand-written SQL.

8. Inline scripts and styles (2 minutes)

grep -rnE '<script[^>]*>[^<]|on(click|change|submit|load)=|javascript:|style="' extension/<name>/design | head -30

The administration enforces a Content Security Policy: inline scripts, on...= handler attributes and javascript: links do not run there. Every hit is work for Part 4 before the extension's admin pages work.

9. What it changes in the system (5 minutes)

  • To do: ls extension/<name>/settings/ and read each file: which settings does it change? Does it override a kernel class (ezpkerneloverride-style autoloads), replace a module, or add event listeners?
  • To do: share/, sql/, update/: does it create tables? Do they have upgrade scripts?
  • To do: cronjobs/: does it run anything on a schedule?
  • To do: Does it send mail, call external services, write files outside var/?

10. Decide

FindingsDecision
License fine, parses, access checks present, escaping fineUse it; keep notes of what you checked
License fine, small PHP 8 or CSP problemsBring it up to date with Part 4, then offer the fixes to its author
No access checks, unescaped output, SQL from request valuesDo not use it on a live site until fixed
No licenseDo not copy it; take only the idea

Write your findings down. If you adopt or fix the extension, they become the first issue in its tracker.

Become an Exponential Partner. Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster. Start with Partners: start here and How to apply.

Was this helpful?

Only your answer is kept, not who you are.

Something wrong on this page? Report an error