1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Revert "Allow tainted numerics except for 'html' and 'has_quotes'"

This commit is contained in:
Oliver Hader 2024-02-20 13:55:31 +01:00 committed by GitHub
parent 503ccd8235
commit 679aaf0939
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 64 deletions

View File

@ -32,7 +32,6 @@ use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_merge;
use function in_array;
use function strlen;
@ -171,14 +170,6 @@ final class BinaryOpAnalyzer
$removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
if ($stmt_left_type && $stmt_left_type->parent_nodes) {
// numeric types can't be tainted html or has_quotes, neither can bool
if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph
&& $stmt_left_type->isSingle()
&& ($stmt_left_type->isInt() || $stmt_left_type->isFloat() || $stmt_left_type->isBool())
) {
$removed_taints = array_merge($removed_taints, array('html', 'has_quotes'));
}
foreach ($stmt_left_type->parent_nodes as $parent_node) {
$statements_analyzer->data_flow_graph->addPath(
$parent_node,
@ -191,14 +182,6 @@ final class BinaryOpAnalyzer
}
if ($stmt_right_type && $stmt_right_type->parent_nodes) {
// numeric types can't be tainted html or has_quotes, neither can bool
if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph
&& $stmt_right_type->isSingle()
&& ($stmt_right_type->isInt() || $stmt_right_type->isFloat() || $stmt_right_type->isBool())
) {
$removed_taints = array_merge($removed_taints, array('html', 'has_quotes'));
}
foreach ($stmt_right_type->parent_nodes as $parent_node) {
$statements_analyzer->data_flow_graph->addPath(
$parent_node,

View File

@ -60,7 +60,6 @@ use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function array_merge;
use function count;
use function explode;
use function implode;
@ -1529,19 +1528,19 @@ final class ArgumentAnalyzer
return;
}
$event = new AddRemoveTaintsEvent($expr, $context, $statements_analyzer, $codebase);
$added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
$removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
// numeric types can't be tainted html or has_quotes, neither can bool
// numeric types can't be tainted, neither can bool
if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph
&& $input_type->isSingle()
&& ($input_type->isInt() || $input_type->isFloat() || $input_type->isBool())
) {
$removed_taints = array_merge($removed_taints, array('html', 'has_quotes'));
return;
}
$event = new AddRemoveTaintsEvent($expr, $context, $statements_analyzer, $codebase);
$added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
$removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
if ($function_param->type && $function_param->type->isString() && !$input_type->isString()) {
$input_type = CastAnalyzer::castStringAttempt(
$statements_analyzer,

View File

@ -142,9 +142,14 @@ final class CastAnalyzer
}
}
$type = new Union([new TBool()], [
'parent_nodes' => $maybe_type->parent_nodes ?? [],
]);
if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph
) {
$type = new Union([new TBool()], [
'parent_nodes' => $maybe_type->parent_nodes ?? [],
]);
} else {
$type = Type::getBool();
}
$statements_analyzer->node_data->setType($stmt, $type);
@ -323,7 +328,11 @@ final class CastAnalyzer
$atomic_types = $stmt_type->getAtomicTypes();
$parent_nodes = $stmt_type->parent_nodes;
$parent_nodes = [];
if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
$parent_nodes = $stmt_type->parent_nodes;
}
while ($atomic_types) {
$atomic_type = array_pop($atomic_types);
@ -509,7 +518,11 @@ final class CastAnalyzer
$atomic_types = $stmt_type->getAtomicTypes();
$parent_nodes = $stmt_type->parent_nodes;
$parent_nodes = [];
if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
$parent_nodes = $stmt_type->parent_nodes;
}
while ($atomic_types) {
$atomic_type = array_pop($atomic_types);

View File

@ -177,6 +177,23 @@ class TaintTest extends TestCase
}
}',
],
'untaintedInputAfterIntCast' => [
'code' => '<?php
class A {
public function getUserId() : int {
return (int) $_GET["user_id"];
}
public function getAppendedUserId() : string {
return "aaaa" . $this->getUserId();
}
public function deleteUser(PDO $pdo) : void {
$userId = $this->getAppendedUserId();
$pdo->exec("delete from users where user_id = " . $userId);
}
}',
],
'specializedCoreFunctionCall' => [
'code' => '<?php
$a = (string) ($data["user_id"] ?? "");
@ -681,6 +698,21 @@ class TaintTest extends TestCase
$value = $_GET["value"];
$result = fetch($value);',
],
'NoTaintForIntTypeCastUsingAnnotatedSink' => [
'code' => '<?php // --taint-analysis
function fetch($id): string
{
return query("SELECT * FROM table WHERE id=" . (int)$id);
}
/**
* @return string
* @psalm-taint-sink sql $sql
* @psalm-taint-specialize
*/
function query(string $sql) {}
$value = $_GET["value"];
$result = fetch($value);',
],
'dontTaintArrayWithDifferentOffsetUpdated' => [
'code' => '<?php
function foo() {
@ -852,40 +884,6 @@ class TaintTest extends TestCase
}',
'error_message' => 'TaintedSql',
],
'taintedInputAfterIntCast' => [
'code' => '<?php
class A {
public function getUserId() : int {
return (int) $_GET["user_id"];
}
public function getAppendedUserId() : string {
return "aaaa" . $this->getUserId();
}
public function deleteUser(PDO $pdo) : void {
$userId = $this->getAppendedUserId();
$pdo->exec("delete from users where user_id = " . $userId);
}
}',
'error_message' => 'TaintedSql',
],
'TaintForIntTypeCastUsingAnnotatedSink' => [
'code' => '<?php // --taint-analysis
function fetch($id): string
{
return query("SELECT * FROM table WHERE id=" . (int)$id);
}
/**
* @return string
* @psalm-taint-sink sql $sql
* @psalm-taint-specialize
*/
function query(string $sql) {}
$value = $_GET["value"];
$result = fetch($value);',
'error_message' => 'TaintedSql',
],
'taintedInputFromReturnTypeWithBranch' => [
'code' => '<?php
class A {