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

修复count和group同时使用时,count的sql注入问题 #335

Merged
merged 4 commits into from Mar 22, 2022
Merged

修复count和group同时使用时,count的sql注入问题 #335

merged 4 commits into from Mar 22, 2022

Conversation

augushong
Copy link
Contributor

用法如下时:

        $title = FacadeRequest::get('title');
        $field = FacadeRequest::get('field');       // id  AND (SELECT 1555 FROM (SELECT(SLEEP(4)))Tfbh)

        $fqModel = new MallGoods();
        $result = $fqModel->where(['title' => $title])
        ->group('cate_id')
        ->count($field);

传入的filed会被注入:

public function count(string $field = '*'): int
    {
        if (!empty($this->options['group'])) {
            // 支持GROUP

            if (!preg_match('/^[\w\.\*]+$/', $field)) {
                throw new DbException('not support data:' . $field);
            }

            $options = $this->getOptions();
            $subSql  = $this->options($options)
                ->field('count(' . $field . ') AS think_count')
                ->bind($this->bind)
                ->buildSql();

            $query = $this->newQuery()->table([$subSql => '_group_count_']);

            $count = $query->aggregate('COUNT', '*');
        } else {
            $count = $this->aggregate('COUNT', $field);
        }

        return (int) $count;
    }

其他聚合方法传入的数据最终都会被builderparseKey方法检查,但是count与group一同使用时,使用的子查询并没有验证字段.

AggregateQuery:
    public function sum($field): float
    {
        return $this->aggregate('SUM', $field, true);
    }
    protected function aggregate(string $aggregate, $field, bool $force = false)
    {
        return $this->connection->aggregate($this, $aggregate, $field, $force);
    }
....
PDO:
    public function aggregate(BaseQuery $query, string $aggregate, $field, bool $force = false)
    {
        if (is_string($field) && 0 === stripos($field, 'DISTINCT ')) {
            [$distinct, $field] = explode(' ', $field);
        }

        $field = $aggregate . '(' . (!empty($distinct) ? 'DISTINCT ' : '') . $this->builder->parseKey($query, $field, true) . ') AS think_' . strtolower($aggregate);

        $result = $this->value($query, $field, 0);

        return $force ? (float) $result : $result;
    }

@codecov-commenter
Copy link

Codecov Report

Merging #335 (9412086) into 2.0 (2959b82) will decrease coverage by 0.00%.
The diff coverage is 0.00%.

@@             Coverage Diff              @@
##                2.0     #335      +/-   ##
============================================
- Coverage     11.84%   11.84%   -0.01%     
- Complexity     2883     2884       +1     
============================================
  Files            63       63              
  Lines          6779     6781       +2     
============================================
  Hits            803      803              
- Misses         5976     5978       +2     
Flag Coverage Δ
unittests 11.84% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/db/concern/AggregateQuery.php 0.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2959b82...9412086. Read the comment docs.

@augushong augushong closed this Mar 21, 2022
@augushong augushong reopened this Mar 21, 2022
@liu21st liu21st merged commit ccdbf7e into top-think:2.0 Mar 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants