Skip to content

Commit 6c2980c

Browse files
Added: Sql Sanitization (#10)
1 parent 25e2567 commit 6c2980c

File tree

5 files changed

+107
-1
lines changed

5 files changed

+107
-1
lines changed

src/ConfigProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Hyperf\Metric\Aspect\MongoCollectionMetricAspect;
2020
use Hyperf\Metric\Aspect\RedisMetricAspect;
2121
use Hyperf\Metric\Contract\MetricFactoryInterface;
22+
use Hyperf\Metric\Contract\SqlSanitizerInterface;
2223
use Hyperf\Metric\Listener\DbQueryExecutedMetricListener;
2324
use Hyperf\Metric\Listener\OnBeforeHandle;
2425
use Hyperf\Metric\Listener\OnCoroutineServerStart;
@@ -27,6 +28,7 @@
2728
use Hyperf\Metric\Listener\OnWorkerStart;
2829
use Hyperf\Metric\Middleware\MetricMiddleware;
2930
use Hyperf\Metric\Process\MetricProcess;
31+
use Hyperf\Metric\Support\SqlSanitizer;
3032
use InfluxDB\Driver\DriverInterface;
3133
use InfluxDB\Driver\Guzzle;
3234
use Prometheus\Storage\Adapter;
@@ -42,6 +44,7 @@ public function __invoke(): array
4244
Adapter::class => InMemory::class,
4345
Connection::class => StatsDConnection::class,
4446
DriverInterface::class => Guzzle::class,
47+
SqlSanitizerInterface::class => SqlSanitizer::class,
4548
],
4649
'aspects' => [
4750
CounterAnnotationAspect::class,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf + OpenCodeCo
6+
*
7+
* @link https://opencodeco.dev
8+
* @document https://hyperf.wiki
9+
* @contact [email protected]
10+
* @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE
11+
*/
12+
namespace Hyperf\Metric\Contract;
13+
14+
interface SqlSanitizerInterface
15+
{
16+
public function sanitize(string $sql): string;
17+
}

src/Listener/DbQueryExecutedMetricListener.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
use Hyperf\Database\Events\QueryExecuted;
1515
use Hyperf\Event\Contract\ListenerInterface;
1616
use Hyperf\Metric\Contract\MetricFactoryInterface;
17+
use Hyperf\Metric\Contract\SqlSanitizerInterface;
1718

1819
use function Hyperf\Support\make;
1920

2021
class DbQueryExecutedMetricListener implements ListenerInterface
2122
{
23+
public function __construct(private SqlSanitizerInterface $sqlSanitizer)
24+
{
25+
}
26+
2227
public function listen(): array
2328
{
2429
return [QueryExecuted::class];
@@ -32,7 +37,7 @@ public function process(object $event): void
3237

3338
$labels = [
3439
'system' => 'mysql',
35-
'operation' => $event->sql,
40+
'operation' => $this->sqlSanitizer->sanitize($event->sql),
3641
];
3742

3843
$histogram = make(MetricFactoryInterface::class)

src/Support/SqlSanitizer.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf + OpenCodeCo
6+
*
7+
* @link https://opencodeco.dev
8+
* @document https://hyperf.wiki
9+
* @contact [email protected]
10+
* @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE
11+
*/
12+
namespace Hyperf\Metric\Support;
13+
14+
use Hyperf\Metric\Contract\SqlSanitizerInterface;
15+
16+
class SqlSanitizer implements SqlSanitizerInterface
17+
{
18+
public function sanitize(string $sql): string
19+
{
20+
$patterns = [
21+
'/(?<=\()\d+(?=\))/',
22+
'/(?<=\()\d+(?=,\s)/',
23+
'/(?<=,\s)\d+(?=,\s)/',
24+
'/(?<=,\s)\d+(?=\))/',
25+
];
26+
27+
return preg_replace($patterns, array_fill(0, count($patterns), '?'), $sql);
28+
}
29+
}

tests/Cases/SqlSanitizerTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf + OpenCodeCo
6+
*
7+
* @link https://opencodeco.dev
8+
* @document https://hyperf.wiki
9+
* @contact [email protected]
10+
* @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE
11+
*/
12+
namespace HyperfTest\Metric\Cases;
13+
14+
use Hyperf\Metric\Support\SqlSanitizer;
15+
use PHPUnit\Framework\TestCase;
16+
17+
/**
18+
* @internal
19+
* @coversNothing
20+
*/
21+
final class SqlSanitizerTest extends TestCase
22+
{
23+
public function testSanitizeNumericIds(): void
24+
{
25+
$sanitizer = new SqlSanitizer();
26+
27+
self::assertSame(
28+
'select * from `users` where `id` in (?)',
29+
$sanitizer->sanitize('select * from `users` where `id` in (200093484)')
30+
);
31+
32+
self::assertSame(
33+
'select * from `bin_codes` where `bin_codes`.`bin` in (?)',
34+
$sanitizer->sanitize('select * from `bin_codes` where `bin_codes`.`bin` in (?)')
35+
);
36+
37+
self::assertSame(
38+
'select * from `card_tokens` where (`card_id` = ?)',
39+
$sanitizer->sanitize('select * from `card_tokens` where (`card_id` = ?)')
40+
);
41+
42+
self::assertSame(
43+
'select * from `cards` where `owner_id` not in (?, ?)',
44+
$sanitizer->sanitize('select * from `cards` where `owner_id` not in (1260361, 903023958)')
45+
);
46+
47+
self::assertSame(
48+
'select * from `cards` where `owner_id` not in (?, ?, ?)',
49+
$sanitizer->sanitize('select * from `cards` where `owner_id` not in (1260361, 903023958, 880427302)')
50+
);
51+
}
52+
}

0 commit comments

Comments
 (0)