mirror of
https://github.com/PrivateBin/PrivateBin.git
synced 2026-07-21 02:24:53 +00:00
fix: return "Invalid data." instead of HTTP 500 on malformed v2 payloads
Under strict_types on PHP 8, malformed JSON API v2 payloads triggered
uncaught TypeErrors (HTTP 500) instead of the standard JSON error
response {"status":1,"message":"Invalid data."}:
- a non-numeric `v` reached `$data['v'] + 0` in Request::getData()
- a scalar `meta` reached `count($message['meta'])` in FormatV2::isValid()
- non-array adata[0] / non-string ct fields reached base64_decode(),
strlen() and count() with the wrong types
Validate the types before the numeric coercion and before the
string/count operations, so all such inputs are rejected cleanly with
"Invalid data." instead of a fatal error. Both crashes are remotely
triggerable without authentication (availability only, no data exposure).
Adds FormatV2Test coverage for the malformed-type inputs.
Fixes #1883
This commit is contained in:
parent
886d4419d7
commit
e80efda7c2
3 changed files with 60 additions and 3 deletions
|
|
@ -56,7 +56,21 @@ class FormatV2
|
|||
return false;
|
||||
}
|
||||
|
||||
$cipherParams = $isComment ? $message['adata'] : $message['adata'][0];
|
||||
$cipherParams = $isComment ? $message['adata'] : ($message['adata'][0] ?? null);
|
||||
|
||||
// Make sure the cipher parameters are a properly sized array.
|
||||
if (!is_array($cipherParams) || count($cipherParams) < 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the ciphertext and the cipher parameters used in the
|
||||
// string operations below are actually strings, so that malformed
|
||||
// input yields "Invalid data." instead of a fatal type error.
|
||||
if (!is_string($message['ct']) ||
|
||||
!is_string($cipherParams[0] ?? null) ||
|
||||
!is_string($cipherParams[1] ?? null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure some fields are base64 data:
|
||||
// - initialization vector
|
||||
|
|
@ -119,6 +133,7 @@ class FormatV2
|
|||
|
||||
// require only the key 'expire' in the metadata of pastes
|
||||
if (!$isComment && (
|
||||
!is_array($message['meta']) ||
|
||||
count($message['meta']) === 0 ||
|
||||
!array_key_exists('expire', $message['meta']) ||
|
||||
count($message['meta']) > 1
|
||||
|
|
|
|||
|
|
@ -189,8 +189,13 @@ class Request
|
|||
foreach ($required_keys as $key) {
|
||||
$data[$key] = $this->getParam($key, $key === 'v' ? 1 : '');
|
||||
}
|
||||
// forcing a cast to int or float
|
||||
$data['v'] = $data['v'] + 0;
|
||||
// forcing a cast to int or float, but only when the value is
|
||||
// numeric; a non-numeric version is left untouched so the format
|
||||
// validator rejects it with "Invalid data." instead of a fatal
|
||||
// type error
|
||||
if (is_numeric($data['v'])) {
|
||||
$data['v'] = $data['v'] + 0;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,4 +72,41 @@ class FormatV2Test extends TestCase
|
|||
$paste = Helper::getPaste();
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'invalid meta key');
|
||||
}
|
||||
|
||||
public function testFormatV2ValidatorRejectsMalformedTypes()
|
||||
{
|
||||
// malformed input must yield "false" (Invalid data) rather than a
|
||||
// fatal type error under strict_types
|
||||
$paste = Helper::getPastePost();
|
||||
$paste['v'] = 'abc';
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'non-numeric version');
|
||||
|
||||
$paste = Helper::getPastePost();
|
||||
$paste['v'] = array();
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'array version');
|
||||
|
||||
$paste = Helper::getPastePost();
|
||||
$paste['ct'] = array('not', 'a', 'string');
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'non-string ciphertext');
|
||||
|
||||
$paste = Helper::getPastePost();
|
||||
$paste['meta'] = 'not-an-array';
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'non-array meta');
|
||||
|
||||
$paste = Helper::getPastePost();
|
||||
$paste['adata'][0] = 'not-an-array';
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'non-array cipher parameters');
|
||||
|
||||
$paste = Helper::getPastePost();
|
||||
$paste['adata'][0] = array();
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'empty cipher parameters');
|
||||
|
||||
$paste = Helper::getPastePost();
|
||||
$paste['adata'][0][0] = array();
|
||||
$this->assertFalse(FormatV2::isValid($paste), 'non-string iv');
|
||||
|
||||
$comment = Helper::getCommentPost();
|
||||
$comment['ct'] = 42;
|
||||
$this->assertFalse(FormatV2::isValid($comment, true), 'non-string comment ciphertext');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue