mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-12 06:48:55 +00:00
e187513cdd
`env()` recognises the words "true" and "false" and returns everything
else as the string it was — and every non-empty string is truthy in PHP.
So `(bool) env('PROJECTSEND_CAPTCHA_DISABLED')` read all of these as "yes,
disabled":
PROJECTSEND_CAPTCHA_DISABLED=no
PROJECTSEND_CAPTCHA_DISABLED=off
PROJECTSEND_CAPTCHA_DISABLED=fasle
An operator who meant to say no took the bot protection off their login
and registration forms and had nothing to tell them so — the setting
screen still shows the CAPTCHA configured, because this is the escape
hatch that runs ahead of it.
For most settings the cast is a shrug: somebody notices the feature is on
and fixes the line. It stops being a shrug when the wrong answer is the
unsafe one, and this is one of those. EnvFlag lists what counts as yes —
`true` and `1`, either case, either type — and reads everything else,
recognised or not, as no. A value typed as `disabled` turns nothing off:
a configuration mistake to be found rather than guessed at.
Found while fixing the same bug in a new cloud-modules flag, where the
unsafe direction was publishing a customer's files rather than dropping a
CAPTCHA. Two of the four remaining `(bool) env()` casts are left alone on
purpose: a wrong S3 path-style value breaks storage loudly, and the
migration tool's direct mode defaults to true anyway, so neither fails
into an unsafe state.
52 lines
1.5 KiB
PHP
52 lines
1.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support;
|
|
|
|
/**
|
|
* Reading an on/off environment variable strictly.
|
|
*
|
|
* `env()` recognises the words `true` and `false` and hands back
|
|
* everything else as the string it was — and every non-empty string is
|
|
* truthy in PHP. So the obvious `(bool) env(...)` reads `no`, `off` and
|
|
* a typo as **on**:
|
|
*
|
|
* SOMETHING=no -> on
|
|
* SOMETHING=off -> on
|
|
* SOMETHING=enabld -> on
|
|
*
|
|
* For most settings that is a shrug — somebody notices the feature is on
|
|
* and fixes the line. It stops being a shrug when the wrong answer is the
|
|
* unsafe one, which is every flag that switches a protection *off* or a
|
|
* disclosure *on*. Those have to fail the other way, so this lists what
|
|
* counts as yes and reads everything else — including anything it does
|
|
* not recognise — as no.
|
|
*
|
|
* The list is deliberately short. Nothing an operator might have meant as
|
|
* "no" is in it, which is the point; a value typed as `enabled` turns
|
|
* nothing on and is a configuration mistake to be found rather than
|
|
* guessed at.
|
|
*/
|
|
final class EnvFlag
|
|
{
|
|
private const TRUE_VALUES = ['1', 'true'];
|
|
|
|
/**
|
|
* @param mixed $value whatever `env()` returned
|
|
*/
|
|
public static function isTrue(mixed $value): bool
|
|
{
|
|
if (is_bool($value)) {
|
|
return $value;
|
|
}
|
|
|
|
if (is_int($value)) {
|
|
return $value === 1;
|
|
}
|
|
|
|
return is_string($value)
|
|
&& in_array(strtolower(trim($value)), self::TRUE_VALUES, true);
|
|
}
|
|
}
|