Statement on glibc/iconv Vulnerability – PHP: Hypertext Preprocessor

EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.Recently, a bug in glibc version 2.39 and older (CVE-2024-2961) was uncovered where a buffer overflow in character set conversions to the ISO-2022-CN-EXT character set can result in remote code execution. This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the iconv extension. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely. The bug is exploitable, if and only if, the PHP application calls iconv functions or filters with user-supplied character sets. Applications are not vulnerable if: Glibc security updates from the distribution have been installedOr the iconv extension is not loadedOr the vulnerable character set has been removed from gconv-modules-extra.confOr the application passes only specifically allowed character sets to iconv. Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the array_search() function to check the encoding before passing it to iconv. For example: array_search($charset, $allowed_list, true) There are numerous reports online with titles like “Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)” or “PHP Under Attack”. These titles are misleading as this is not a bug in PHP itself. If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. Debian, CentOS, and others, have already done so, and please upgrade as soon as possible. Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library. If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in GLIBC Vulnerability on Servers Serving PHP which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.PHP users on Windows are not affected.There will therefore also not be a new version of PHP for this vulnerability.

Moving on from Mocha, Chai and nyc. – Evert Pot

I’m a maintainer of several small open-source libraries. It’s a fun activity.
If the scope of the library is small enough, the maintenance burden is
typically fairly low. They’re usually mostly ‘done’, and I occasionally just need to
answer a few questions per year, and do the occasional release to bring it
back up to the current ‘meta’ of the ecosystem.

Also even though it’s ‘done’, in use by a bunch of people and well tested,
it’s also good to do a release from time to time to not give the impression
of abandonment.

This weekend I released a 2.0 version of my bigint-money library, which
is a fast library for currency math.

I originally wrote this in 2018, so the big BC break was switching everything
over to ESM. For a while I tried to support both CommonJS and ESM
builds for my packages, but only a year after all that effort it frankly no
longer feels needed. I was worried the ecosystem was going to
split, but people stuck on (unsupported) versions of Node that don’t
support ESM aren’t going to proactively keep their other dependencies updated,
so CommonJS is for (and many others) in the past now. (yay!)

Probably the single best way to keep maintenance burden for packages low is
to have few dependencies. Many of my packages have 0 dependencies.

Reducing devDependencies also helps. If you didn’t know, node now has a
built-in testrunner. I’ve been using Mocha + Chai for many many
years. They were awesome and want to thank the maintainers, but node --test
is pretty good now and has pretty output.

It also:

  • Is much faster (about twice as fast with Typescript and code coverage
    reporting, but I suspect the difference will grow with larger code bases).
  • Easier to configure (especially when you’re also using Typescript. Just use tsx --test).
  • It can output test coverage with (--experimental-test-coverage).

Furthermore, while node:assert doesn’t have all features of Chai, it has
the important ones (deep compare) and adds better Promise support.

All in all this reduced my node_modules directory from a surprising 159M
to 97M, most of which is now Typescript and ESLint, and my total dependency
count from 335 to 141 (almost all of which is ESLint).

Make sure that Node’s test library, coverage and assertion library is right
for you. It may not have all the features you expect, but I keep my testing
setup relatively simple, so the switch was easy.

Concealing Cacophony – Derick Rethans

Concealing Cacophony

Over the last few weeks I have been publishing a series of videos on writing PHP extensions.

I record these videos through OBS, and then slice and dice them with Kdenlive. This editing is necessary to make up for my mistakes, shorten the time we wait for things to compile, and to remove the noise of me hammering away on my keyboard.

Editing takes a lot of time, and I still wasn’t always pleased with the result as there was still a fair amount of noise while I am talking.

For the PHP Internals News podcast, I used a set of noise cancellation filters, which worked wonders. But it turns out that Kdenlive does not come with one built in.

I had a look around on the Internet, and learned that there is a LADSPA Noise Suppressor for Voice plugin. LADSPA is an open API for audio filters and audio signal processing effects. LADSPA plugins can be used with Kdenlive.

Some Linux distributions have a package for this LADSPA Noise Suppressor for Voice, but my Debian distribution bookworm does not.

I found instructions that explain how to build the plugin from source. These instructions worked after some tweaks. I ended up creating the following script:

#!/bin/bash sudo apt install cmake ninja-build pkg-config libfreetype-dev libx11-dev libxrandr-dev libxcursor-dev
git clone https://github.com/werman/noise-suppression-for-voice /tmp/noise
cd /tmp/noise
cmake -Bbuild-x64 -H. -GNinja -DCMAKE_BUILD_TYPE=Release
sudo ninja -C build-x64 install 

After running this script, and restarting Kdenlive, I found the installed plugin when I searched for it.

With the plugin loaded, I now have much clearer sound, and I also don’t have to edit the sections where I am typing, as the plugin automatically handles this.

I will still have to edit out my mistakes.

I then also had a look at how it worked. It turns out that this plugin uses neural networks to cancel the noise.

In the background, it uses the RNNoise library which implements an algorithm by Jean-Marc Valin, as outlined in this paper. There is an easier to read version of how the algorithm works on his website.

The data to train the model is also freely available, and uses resources from the OpenSLR project. Noise data is also available there. From what I can tell, all this data was contributed under reasonable conditions, and not scraped from the internet without consent. That is important to me.

Hopefully, from the third video in the series, you will find the sound quality much better.

Tukio 2.0 released – Event Dispatcher for PHP – Larry Garfield

Tukio 2.0 released – Event Dispatcher for PHP

I’ve just released version 2.0 of Crell/Tukio! Available now from your favorite Packagist.org. Tukio is a feature-complete, easy to use, robust Event Dispatcher for PHP, following PSR-14. It began life as the PSR-14 reference implementation.

Tukio 2.0 is almost a rewrite, given the amount of cleanup that was done. But the final result is a library that is vastly more robust and vastly easier to use than version 1, while still producing near-instant listener lookups.

Some of the major improvements include:

Larry
14 April 2024 – 2:24pm

Check licenses of composer dependencies – Rob Allen

With some commercial projects, it can be useful to know that all your dependencies have licences that your organisation deems acceptable.

I had this requirement for a few clients now and came up with this script that we ran as part of our CI which would then fail if a dependency used a license that wasn’t allowed.

This proved to be reasonably easy as composer licenses will provide a list of all packages with their license, and more usefully, the -f json switch will output the list as JSON. With a machine-readable format, the script just came together!

At some point, we discovered that we needed to allow exceptions for specifically authorised packages, so I added that and haven’t changed it since.

check-licenses.php

<?php $allowedLicenses = ['Apache-2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'ISC', 'MIT', 'MPL-2.0', 'OSL-3.0'];
$allowedExceptions = [ 'some-provider/some-provider-php', // Proprietary license used by SMS provider
]; $licences = shell_exec('composer licenses -f json');
if ($licences === null || $licences === false) { echo "Failed to retrieve licenses\n"; exit(1);
} try { $data = json_decode($licences, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) { echo "Failed to decode licenses JSON: " . $e->getMessage() . "\n"; exit(1);
} // Filter out all dependencies that have an allowed license or exception
$disallowed = array_filter( $data['dependencies'], fn(array $info, $name) => ! in_array($name, $allowedExceptions) && count(array_diff($info['license'], $allowedLicenses)) === 1, ARRAY_FILTER_USE_BOTH
);
if (count($disallowed)) { $disallowedList = array_map( fn(string $k, array $info) => sprintf("$k (%s)", implode(',', $info['license'])), array_keys($disallowed), $disallowed ); printf("Disallowed licenses found in PHP dependencies: %s\n", implode(', ', $disallowedList)); exit(1);
} exit(0);

Running check-licenses.php

If all dependencies are allowed, then check-licenses will output nothing and exit with status code 0:

$ php bin/check-licenses.php
$ echo $?
0

If at least one dependency is not allowed, then check-licenses will list the packages that have licenses that ar not allowed and exit with status code 1:

$ php bin/check-licenses.php
Disallowed licenses found in PHP dependencies: foo/bar (GPL-3.0)
$ echo $?
1

Maybe it’s useful to others too. If you use it, put it in your CI system.