libvips / php-vips

php binding for libvips
MIT License
618 stars 25 forks source link

Switch to PHP::FFI #123

Closed jcupitt closed 2 years ago

jcupitt commented 3 years ago

With php 7.4, there's now a reasonable FFI mechanism in PHP:

https://www.php.net/manual/en/book.ffi.php

php 8.0 has half-deprecated chunks of pecl, and pecl makes installation challenging anyway, so the php-vips-ext C extension we currently use to interface to the platform libvips is becoming harder to maintain.

PHP::FFI is enabled by default in eg. Ubuntu 21.10. php- -i shows:

FFI

FFI support => enabled

Directive => Local Value => Master Value
ffi.enable => preload => preload
ffi.preload => no value => no value

So hopefully reimplementing php-vips-ext in pure php is now pretty simple.

jcupitt commented 2 years ago

Branch here with a mostly complete FFI implementation. A work in progress still.

https://github.com/libvips/php-vips/tree/switch-to-php-ffi

zumpixel commented 2 years ago

Hi @jcupitt, I get this error: Fatal error: Uncaught FFI\Exception: FFI API is restricted by "ffi.enable" configuration directive in /(somepathonmyserver)/vips-test/vendor/jcupitt/vips/src/Init.php:202

fff.enable is set to preload, OS is Cloudlinux, PHP 8.1

jcupitt commented 2 years ago

Hi, I think you need to set enable to true.

jcupitt commented 2 years ago

PR for this issue https://github.com/libvips/php-vips/pull/133

talisto commented 2 years ago

Are there not some serious security considerations with enabling FFI for all requests (i.e. setting ffi.enable to true)? This website, for example, says the following:

Usage of PHP FFI can lead to huge security risks as it allows virtually the same things as C. We can, for example, interface with the system on a very low level or even disable some PHP security measures by tempering the memory of the PHP interpreter through direct memory manipulation capability. As a security countermeasure, FFI is, by default, allowed only in the CLI or during script preloading. This can be changed in ffi.enable php.ini directive.

The README.md is currently instructing users to enable this on their PHP but there's no mention of the potential security risks associated with this action.

jcupitt commented 2 years ago

Hi Matt, you're right, I should mention only enabling FFI during preload. I'll update it.

I've not actually been able to test php-vips with preload, I'm hoping a php expert will fix this for me.

Of course, if an attacker is running their own PHP code on your webserver you are in pretty serious trouble anyway. But enabling FFI would perhaps make the situation even worse.

jcupitt commented 2 years ago

Now I check again I remember that there's some work to do before preloading will work with php-vips. I'll mention this too.

mld commented 2 years ago

Of course, if an attacker is running their own PHP code on your webserver you are in pretty serious trouble anyway. But enabling FFI would perhaps make the situation even worse.

This would likely be worse on (for example) shared hosting, rather than inside a docker container or a dedicated server/VM as is the more modern and (at least I think so) common use case. With that said, there's still a huge amount of PHP run on shared hosting.

jcupitt commented 2 years ago

That's true, though of course you can run native code without FFI. Just write a C source file to /tmp/my-terrible-attack.c, then compile and run it.

Sorry to ping you @chregu -- I wonder if you have an opinion on this issue?

chregu commented 2 years ago

Agree with @jcupitt, if an attacker can run any PHP code, you're toast anyway. Of course you can potentially do even worse things with "compiling" C-code, but if your OS setup is not protecting you from doing nasty things, you can achieve enough bad things with PHP alone anyway (or just download a precompiled binary from somewhere and run that). But sure, there's some more advanced vector attacks with FFI, the PHP docs are right there.

And regarding shared hosting, if they're concerned about FFI, then they won't enable it. Most of them also won't have php-vips-ext, I assume, as it's still rather exotic.

And nothing is preventing you running php-ext 1.0.x for the time being. Our https://github.com/rokka-io/imagine-vips/ library does support both actually, it's easy enough to do (once https://github.com/rokka-io/imagine-vips/pull/24 is merged, which I'll maybe to today.

But preloading support would of course be the better long term solution

chregu commented 2 years ago

BTW, we're running now the 2.0.x version with FFI on production since a few days. Seems to work totally fine. Thanks a lot for your work.

Mohammad-Khazaee commented 2 years ago

ffi really working fine thanks a lot for your work

mohsen159 commented 2 years ago

if you are using xammp like me and have the same problem my code is ' try { $exp = new Exception("my custom error qnd horrer " , 12345 ); throw $exp; } catch(Exception $e) { echo 'Message: ' .$e->getMessage() . " code " . $e->getCode(); } ' didn't work sulotion is go to C:\xampp\php\php.ini search for ;extension=ffi delet the ; and you are done