Skip to content

Commit 5f5e96a

Browse files
committed
BingBot is allowed without any X-Signature #11196
1 parent 1d83a61 commit 5f5e96a

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

src/Middleware/SignedQueryMiddleware.php

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private function verify(ServerRequestInterface $request): ServerRequestInterface
5555
{
5656
$signature = $request->getHeader('X-Signature')[0] ?? '';
5757
if (!$signature) {
58-
if ($this->isAllowedIp($request)) {
58+
if ($this->isAllowedIp($request) || $this->isBingBot($request)) {
5959
return $request;
6060
}
6161

@@ -412,4 +412,52 @@ private function isGoogleBot(ServerRequestInterface $request): bool
412412

413413
return IPRange::matches($remoteAddress, $googleBotIps);
414414
}
415+
416+
private function isBingBot(ServerRequestInterface $request): bool
417+
{
418+
$remoteAddress = $request->getServerParams()['REMOTE_ADDR'] ?? '';
419+
420+
if (!$remoteAddress || !is_string($remoteAddress)) {
421+
return false;
422+
}
423+
424+
// Source is https://www.bing.com/toolbox/bingbot.json
425+
// Use this one-line command to fetch new list:
426+
//
427+
// ```bash
428+
// php -r 'echo PHP_EOL . implode(PHP_EOL, array_map(fn (array $r) => chr(39) . ($r["ipv6Prefix"] ?? $r["ipv4Prefix"]) . chr(39) . ",", json_decode(file_get_contents("https://www.bing.com/toolbox/bingbot.json"), true)["prefixes"])) . PHP_EOL;'
429+
// ```
430+
$bingBotIps = [
431+
'157.55.39.0/24',
432+
'207.46.13.0/24',
433+
'40.77.167.0/24',
434+
'13.66.139.0/24',
435+
'13.66.144.0/24',
436+
'52.167.144.0/24',
437+
'13.67.10.16/28',
438+
'13.69.66.240/28',
439+
'13.71.172.224/28',
440+
'139.217.52.0/28',
441+
'191.233.204.224/28',
442+
'20.36.108.32/28',
443+
'20.43.120.16/28',
444+
'40.79.131.208/28',
445+
'40.79.186.176/28',
446+
'52.231.148.0/28',
447+
'20.79.107.240/28',
448+
'51.105.67.0/28',
449+
'20.125.163.80/28',
450+
'40.77.188.0/22',
451+
'65.55.210.0/24',
452+
'199.30.24.0/23',
453+
'40.77.202.0/24',
454+
'40.77.139.0/25',
455+
'20.74.197.0/28',
456+
'20.15.133.160/27',
457+
'40.77.177.0/24',
458+
'40.77.178.0/23',
459+
];
460+
461+
return IPRange::matches($remoteAddress, $bingBotIps);
462+
}
415463
}

tests/Middleware/SignedQueryMiddlewareTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,5 +238,32 @@ public static function dataProviderQuery(): iterable
238238
'Invalid `X-Signature` HTTP header in signed query',
239239
'66.249.70.134',
240240
];
241+
242+
yield 'no header, BingBot is allowed, because BingBot does not seem to include our custom header in his request' => [
243+
[$key1],
244+
'{"operationName":"CurrentUser","variables":{},"query":"query CurrentUser { viewer { id }}',
245+
null,
246+
'',
247+
'',
248+
'40.77.188.165',
249+
];
250+
251+
yield 'too much in the past, even BingBot is rejected, because BingBot should not have any header at all' => [
252+
[$key1],
253+
'{"operationName":"CurrentUser","variables":{},"query":"query CurrentUser { viewer { id }}',
254+
null,
255+
'v1.1577951099.20177a7face4e05a75c4b2e41bc97a8225f420f5b7bb1709dd5499821dba0807',
256+
'Signed query is expired',
257+
'40.77.188.165',
258+
];
259+
260+
yield 'too much in the past and invalid signature, even BingBot is rejected, because BingBot should not have any header at all' => [
261+
[$key1],
262+
'{"operationName":"CurrentUser","variables":{},"query":"query CurrentUser { viewer { id }}',
263+
null,
264+
'v1.1577951099' . str_repeat('a', 64),
265+
'Invalid `X-Signature` HTTP header in signed query',
266+
'40.77.188.165',
267+
];
241268
}
242269
}

0 commit comments

Comments
 (0)