Skip to content

security: replace create_function(); add path traversal guard in render()#38

Open
se7enxweb wants to merge 1 commit intozetacomponents:masterfrom
se7enxweb:security/fix-create-function-path-traversal
Open

security: replace create_function(); add path traversal guard in render()#38
se7enxweb wants to merge 1 commit intozetacomponents:masterfrom
se7enxweb:security/fix-create-function-path-traversal

Conversation

@se7enxweb
Copy link
Copy Markdown

Reported-by: CJW Network security audit 2026-03-01

Changes

src/driver/svg.phpcreate_function() removed (PHP 8.0+)

The preg_replace_callback() callback used create_function(), which was deprecated in PHP 7.2 and removed in PHP 8.0. It uses eval() internally and is an RCE vector. Replaced with a proper anonymous function (closure).

src/driver/svg.php + src/driver/gd.php — path traversal in render($file)

The render() method wrote the output image to a caller-supplied $file path without any validation. An attacker passing ../../../../var/www/evil.php could write arbitrary content outside the intended directory.

Fix applied to both drivers:

  1. Null-byte check (rejects embedded NUL in path).
  2. realpath(dirname($file)) — destination directory must exist and must resolve without escaping.
  3. Output path reconstructed as $resolvedDir . DIRECTORY_SEPARATOR . basename($file).

Security fixes

  • RCE via create_function() / eval() (CWE-94)
  • Path traversal in output file (CWE-22)

…er()

svg.php — create_function() removed (PHP 8.0+):
  preg_replace_callback() callback converted from deprecated
  create_function() to a proper anonymous function (closure).
  create_function() uses eval() internally and was removed in PHP 8.0.

svg.php render($file) + gd.php render($file) — path traversal:
  Added null-byte check + realpath(dirname($file)) validation before
  writing the output file. The destination directory must exist and must
  be reachable without '..' traversal escape. The final write path is
  reconstructed from the resolved directory + basename() to prevent any
  remaining traversal.

  Before: dom->save($file) / imagepng($image, $file) called with
  an unvalidated caller-controlled path — an attacker could pass
  '../../../../var/www/evil.php' and write arbitrary content.

Reported-by: CJW Network security audit 2026-03-01
Security-fixes: RCE via create_function (CWE-94), path-traversal (CWE-22)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant