Skip to content

improve macros security #9

Open
@belamov

Description

@belamov

currently macros are registered like that:

Builder::macro(
    "where{$operatorName}",
    fn ($left, $right) => $this->whereRaw(
        sprintf('%s %s %s',
            $left instanceof Range ? $left->forSql() : $left,
            $operator,
            $right instanceof Range ? $right->forSql() : $right
        )
    )
);

https://github.com/belamov/postgres-range/blob/master/src/Macros/QueryBuilderMacros.php#L25

it is not sanitized in any way, so there's potential sql injection scenario, if you're using macros with unvalidated parameters

the better approach is to use PDO's bindings, like so:

Builder::macro(
    "where{$operatorName}",
    fn ($left, $right) => $this->whereRaw(
        "? $operator ?", [
            $left instanceof Range ? $left->forSql() : $left,
            $right instanceof Range ? $right->forSql() : $right 
        ]            
    )
);

or

Builder::macro(
    "where{$operatorName}",
    fn ($left, $right) => $this->where(
            $left instanceof Range ? $left->forSql() : $left,
            $operator
            $right instanceof Range ? $right->forSql() : $right             
    )
);

macros are tested like this:

$query = "where$macroMethod";
$items = Range::$query($columnName, $rangeObject)->get();

https://github.com/belamov/postgres-range/blob/master/tests/Feature/MacrosTest.php#L59

with current implementation there is no errors and every macro is working as expected

but with whereRaw and bindings approach we get sql generated like so:

select * from "ranges" where timestamp_range @> '[2020-04-24 06:52:19,2020-04-25 06:52:19)'::tsrange

and Ambiguous function: 7 ERROR:

operator is not unique: unknown @> unknown

and with where approach we get sql generated like so:

select * from "ranges" where "timestamp_range" @> '[2020-04-24 06:48:52,2020-04-25 06:48:52)'::tsrange

and Invalid text representation: 7 ERROR:

malformed range literal: "'[2020-04-24 06:48:52,2020-04-25 06:48:52)'::tsrange"

in both cases range is transformed as expected and if we run this generated queries with sql, there is no errors. so my guess is that somewhere in value binding to pdo statement this parameters are transformed in some way that pdo driver is not correctly casting types

would be great if somebody know what's the issue is and can help me out with this

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions