Skip to content

Commit 30191d5

Browse files
authored
Merge pull request #37 from teacoder-team/dev
fix(webhook): allow single IPs in CIDR matcher
2 parents 7a9d036 + fb17c61 commit 30191d5

4 files changed

Lines changed: 77 additions & 16 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"axios": "^1.7.9",
4848
"base64url": "^3.0.1",
4949
"bullmq": "^5.51.1",
50+
"cidr-matcher": "^2.1.1",
5051
"class-transformer": "^0.5.1",
5152
"class-validator": "^0.14.1",
5253
"date-fns": "^4.1.0",

src/api/payment/webhook/webhook.controller.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common'
1+
import {
2+
Body,
3+
Controller,
4+
HttpCode,
5+
HttpStatus,
6+
Ip,
7+
Post
8+
} from '@nestjs/common'
29
import { ApiOkResponse, ApiOperation } from '@nestjs/swagger'
310

411
import { ClientIp } from '@/common/decorators'
@@ -21,7 +28,7 @@ export class WebhookController {
2128
})
2229
@Post('yookassa')
2330
@HttpCode(HttpStatus.OK)
24-
public async yookassaWebhook(@Body() payload: any, @ClientIp() ip: string) {
31+
public async yookassaWebhook(@Body() payload: any, @Ip() ip: string) {
2532
console.log('YOOKASSA WEBHOOK IP: ', ip)
2633

2734
this.webhookService.verifyWebhook(ip)

src/api/payment/webhook/webhook.service.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import {
44
UnauthorizedException
55
} from '@nestjs/common'
66
import { PaymentStatus } from '@prisma/generated'
7+
import CidrMatcher from 'cidr-matcher'
78
import { addMonths } from 'date-fns'
8-
import CIDR from 'ip-cidr'
99
import { YookassaService } from 'nestjs-yookassa'
1010

1111
import { IS_DEV_ENV } from '@/common/utils'
@@ -14,6 +14,7 @@ import { PrismaService } from '@/infra/prisma/prisma.service'
1414
@Injectable()
1515
export class WebhookService {
1616
private readonly ALLOWED_IPS: string[]
17+
private readonly matcher: CidrMatcher
1718

1819
public constructor(
1920
private readonly prismaService: PrismaService,
@@ -23,11 +24,13 @@ export class WebhookService {
2324
'185.71.76.0/27',
2425
'185.71.77.0/27',
2526
'77.75.153.0/25',
26-
'77.75.156.11',
27-
'77.75.156.35',
27+
'77.75.156.11/32',
28+
'77.75.156.35/32',
2829
'77.75.154.128/25',
2930
'2a02:5180::/32'
3031
]
32+
33+
this.matcher = new CidrMatcher(this.ALLOWED_IPS)
3134
}
3235

3336
public async handleYookassa(payload: any) {
@@ -42,17 +45,8 @@ export class WebhookService {
4245
}
4346

4447
public verifyWebhook(ip: string) {
45-
if (IS_DEV_ENV) return
46-
47-
for (const range of this.ALLOWED_IPS) {
48-
if (range.includes('/')) {
49-
const cidr = new CIDR(range)
50-
51-
if (cidr.contains(ip)) return
52-
} else if (ip === range) return
53-
}
54-
55-
throw new UnauthorizedException(`Invalid IP: ${ip}`)
48+
if (!this.matcher.contains(ip))
49+
throw new UnauthorizedException(`Invalid IP: ${ip}`)
5650
}
5751

5852
public async handleCrypto(payload: any) {

yarn.lock

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3787,6 +3787,11 @@ assert-never@^1.2.1:
37873787
resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.4.0.tgz#b0d4988628c87f35eb94716cc54422a63927e175"
37883788
integrity sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==
37893789

3790+
assert-plus@1.0.0, assert-plus@^1.0.0:
3791+
version "1.0.0"
3792+
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
3793+
integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
3794+
37903795
async@^2.6.4:
37913796
version "2.6.4"
37923797
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
@@ -4250,6 +4255,13 @@ ci-info@^3.2.0, ci-info@^3.8.0:
42504255
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4"
42514256
integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==
42524257

4258+
cidr-matcher@^2.1.1:
4259+
version "2.1.1"
4260+
resolved "https://registry.yarnpkg.com/cidr-matcher/-/cidr-matcher-2.1.1.tgz#01a489f291bfbc7a3a14358120a6d839a98b1c90"
4261+
integrity sha512-QPJRz4HDQxpB8AZWEqd6ejVp+siArXh3u1MYaUFV85cd293StGSMb87jVe0z9gS92KsFwxCxjb3utO3e5HKHTw==
4262+
dependencies:
4263+
ip6addr "^0.2.2"
4264+
42534265
cjs-module-lexer@^1.0.0:
42544266
version "1.4.3"
42554267
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d"
@@ -4511,6 +4523,11 @@ cookiejar@^2.1.4:
45114523
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b"
45124524
integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==
45134525

4526+
core-util-is@1.0.2:
4527+
version "1.0.2"
4528+
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
4529+
integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
4530+
45144531
core-util-is@^1.0.3, core-util-is@~1.0.0:
45154532
version "1.0.3"
45164533
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@@ -5394,6 +5411,16 @@ external-editor@^3.0.3, external-editor@^3.1.0:
53945411
iconv-lite "^0.4.24"
53955412
tmp "^0.0.33"
53965413

5414+
extsprintf@1.3.0:
5415+
version "1.3.0"
5416+
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
5417+
integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
5418+
5419+
extsprintf@^1.2.0:
5420+
version "1.4.1"
5421+
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
5422+
integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
5423+
53975424
fast-deep-equal@^2.0.1:
53985425
version "2.0.1"
53995426
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
@@ -6188,6 +6215,14 @@ ip-cidr@^4.0.2:
61886215
dependencies:
61896216
ip-address "^9.0.5"
61906217

6218+
ip6addr@^0.2.2:
6219+
version "0.2.5"
6220+
resolved "https://registry.yarnpkg.com/ip6addr/-/ip6addr-0.2.5.tgz#06e134f44b4e1a684fd91b24035dca7a53b8f759"
6221+
integrity sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==
6222+
dependencies:
6223+
assert-plus "^1.0.0"
6224+
jsprim "^2.0.2"
6225+
61916226
ipaddr.js@1.9.1:
61926227
version "1.9.1"
61936228
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
@@ -6858,6 +6893,11 @@ json-schema-traverse@^1.0.0:
68586893
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
68596894
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
68606895

6896+
json-schema@0.4.0:
6897+
version "0.4.0"
6898+
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
6899+
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
6900+
68616901
json-stable-stringify-without-jsonify@^1.0.1:
68626902
version "1.0.1"
68636903
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
@@ -6887,6 +6927,16 @@ jsonfile@^6.0.1:
68876927
optionalDependencies:
68886928
graceful-fs "^4.1.6"
68896929

6930+
jsprim@^2.0.2:
6931+
version "2.0.2"
6932+
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d"
6933+
integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==
6934+
dependencies:
6935+
assert-plus "1.0.0"
6936+
extsprintf "1.3.0"
6937+
json-schema "0.4.0"
6938+
verror "1.10.0"
6939+
68906940
jstransformer@1.0.0:
68916941
version "1.0.0"
68926942
resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3"
@@ -9673,6 +9723,15 @@ vary@^1, vary@~1.1.2:
96739723
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
96749724
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
96759725

9726+
verror@1.10.0:
9727+
version "1.10.0"
9728+
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
9729+
integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==
9730+
dependencies:
9731+
assert-plus "^1.0.0"
9732+
core-util-is "1.0.2"
9733+
extsprintf "^1.2.0"
9734+
96769735
void-elements@^3.1.0:
96779736
version "3.1.0"
96789737
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"

0 commit comments

Comments
 (0)