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:
parent
503ccd8235
commit
679aaf0939
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user