Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add taint sinks on the DBAL Connection #61

Merged
merged 1 commit into from
Sep 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions stubs/Connection.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Doctrine\DBAL;

use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\Statement as DriverStatement;

class Connection implements DriverConnection
{
Expand Down Expand Up @@ -38,4 +39,43 @@ class Connection implements DriverConnection

/** @var int */
public const ARRAY_PARAM_OFFSET = 100;

/**
* @throws DBALException
* @psalm-taint-sink sql $statement
*/
public function prepare(string $statement): DriverStatement {}

/**
* @psalm-taint-sink sql $statement
*/
public function exec(string $statement): int {}

/**
* @psalm-param string[] $query The SQL query parts.
*
* @throws DBALException
* @psalm-taint-sink sql $query
*/
public function query(...$query): DriverStatement {}

/**
* @psalm-param scalar[] $params The query parameters.
* @psalm-param int[]|string[] $types The parameter types.
*
* @throws DBALException
* @psalm-taint-sink sql $query
*/
public function executeUpdate(string $query, array $params = [], array $types = []): int {}

/**
* @psalm-pure
*
* @psalm-param scalar $input
* @psalm-return string
*
* @psalm-taint-escape sql
* @psalm-flow ($input) -> return
*/
public function quote($input, int $type = ParameterType::STRING);
}
63 changes: 63 additions & 0 deletions tests/acceptance/Tainting.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Feature: Tainting
In order to prevent SQL injection when using Doctrine
As a Psalm user
I need Psalm to spot taint sources and sinks

Background:
Given I have Psalm newer than "3.12" (because of "taint analysis")
And I have the following config
"""
<?xml version="1.0"?>
<psalm totallyTyped="true">
<projectFiles>
<directory name="."/>
</projectFiles>
<plugins>
<pluginClass class="Weirdan\DoctrinePsalmPlugin\Plugin" />
</plugins>
</psalm>
"""
And I have the following code preamble
"""
<?php
use Doctrine\DBAL\Connection;

/**
* @psalm-suppress InvalidReturnType
* @return Connection
*/
function connection() {}

"""

@Connection::prepare
@Connection::exec
@Connection::query
@Connection::executeUpdate
Scenario Outline: Using user input on Connection's query methods
Given I have the following code
"""
$sql = 'INSERT INTO sometable (item_name) VALUES ("'.$_GET['untrusted'].'")';
connection()-><method>($sql);
"""
When I run Psalm with taint analysis
Then I see these errors
| Type | Message |
| TaintedInput | Detected tainted sql |
And I see no other errors
Examples:
| method |
| prepare |
| exec |
| query |
| executeUpdate |

@Connection::quote
Scenario: Using Connection's quote method on user input
Given I have the following code
"""
$sql = 'SELECT * FROM sometable WHERE id=' . connection()->quote($_GET['untrusted']);
connection()->query($sql);
"""
When I run Psalm with taint analysis
Then I see no errors