Skip to content

Commit b67b0f3

Browse files
Jimmy Gaussenrix0rrr
authored andcommitted
feat(ec2): Validate IP addresses passed to CidrIPvX (#3642)
Fixes #3639
1 parent 05e13f3 commit b67b0f3

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed

packages/@aws-cdk/aws-ec2/lib/peer.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Token } from "@aws-cdk/core";
12
import { Connections, IConnectable } from "./connections";
23

34
/**
@@ -77,6 +78,18 @@ class CidrIPv4 implements IPeer {
7778
public readonly uniqueId: string;
7879

7980
constructor(private readonly cidrIp: string) {
81+
if (!Token.isUnresolved(cidrIp)) {
82+
const cidrMatch = cidrIp.match(/^(\d{1,3}\.){3}\d{1,3}(\/\d+)?$/);
83+
84+
if (!cidrMatch) {
85+
throw new Error(`Invalid IPv4 CIDR: "${cidrIp}"`);
86+
}
87+
88+
if (!cidrMatch[2]) {
89+
throw new Error(`CIDR mask is missing in IPv4: "${cidrIp}". Did you mean "${cidrIp}/32"?`);
90+
}
91+
}
92+
8093
this.uniqueId = cidrIp;
8194
}
8295

@@ -112,6 +125,18 @@ class CidrIPv6 implements IPeer {
112125
public readonly uniqueId: string;
113126

114127
constructor(private readonly cidrIpv6: string) {
128+
if (!Token.isUnresolved(cidrIpv6)) {
129+
const cidrMatch = cidrIpv6.match(/^([\da-f]{0,4}:){2,7}([\da-f]{0,4})?(\/\d+)?$/);
130+
131+
if (!cidrMatch) {
132+
throw new Error(`Invalid IPv6 CIDR: "${cidrIpv6}"`);
133+
}
134+
135+
if (!cidrMatch[3]) {
136+
throw new Error(`CIDR mask is missing in IPv6: "${cidrIpv6}". Did you mean "${cidrIpv6}/128"?`);
137+
}
138+
}
139+
115140
this.uniqueId = cidrIpv6;
116141
}
117142

packages/@aws-cdk/aws-ec2/test/test.security-group.ts

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, haveResource } from '@aws-cdk/assert';
2-
import { Lazy, Stack } from '@aws-cdk/core';
2+
import { Intrinsic, Lazy, Stack, Token } from '@aws-cdk/core';
33
import { Test } from 'nodeunit';
44
import { Peer, Port, SecurityGroup, Vpc } from "../lib";
55

@@ -182,5 +182,81 @@ export = {
182182
}
183183

184184
test.done();
185+
},
186+
187+
'Peer IP CIDR validation': {
188+
'passes with valid IPv4 CIDR block'(test: Test) {
189+
// GIVEN
190+
const cidrIps = ['0.0.0.0/0', '192.168.255.255/24'];
191+
192+
// THEN
193+
for (const cidrIp of cidrIps) {
194+
test.equal(Peer.ipv4(cidrIp).uniqueId, cidrIp);
195+
}
196+
197+
test.done();
198+
},
199+
200+
'passes with unresolved IP CIDR token'(test: Test) {
201+
// GIVEN
202+
const cidrIp = Token.asString(new Intrinsic('ip'));
203+
204+
// THEN
205+
test.equal(Peer.ipv4(cidrIp).uniqueId, '${Token[TOKEN.1385]}');
206+
test.equal(Peer.ipv6(cidrIp).uniqueId, '${Token[TOKEN.1385]}');
207+
208+
test.done();
209+
},
210+
211+
'throws if invalid IPv4 CIDR block'(test: Test) {
212+
// THEN
213+
test.throws(() => {
214+
Peer.ipv4('invalid');
215+
}, /Invalid IPv4 CIDR/);
216+
217+
test.done();
218+
},
219+
220+
'throws if missing mask in IPv4 CIDR block'(test: Test) {
221+
test.throws(() => {
222+
Peer.ipv4('0.0.0.0');
223+
}, /CIDR mask is missing in IPv4/);
224+
225+
test.done();
226+
},
227+
228+
'passes with valid IPv6 CIDR block'(test: Test) {
229+
// GIVEN
230+
const cidrIps = [
231+
'::/0',
232+
'2001:db8::/32',
233+
'2001:0db8:0000:0000:0000:8a2e:0370:7334/32',
234+
'2001:db8::8a2e:370:7334/32',
235+
];
236+
237+
// THEN
238+
for (const cidrIp of cidrIps) {
239+
test.equal(Peer.ipv6(cidrIp).uniqueId, cidrIp);
240+
}
241+
242+
test.done();
243+
},
244+
245+
'throws if invalid IPv6 CIDR block'(test: Test) {
246+
// THEN
247+
test.throws(() => {
248+
Peer.ipv6('invalid');
249+
}, /Invalid IPv6 CIDR/);
250+
251+
test.done();
252+
},
253+
254+
'throws if missing mask in IPv6 CIDR block'(test: Test) {
255+
test.throws(() => {
256+
Peer.ipv6('::');
257+
}, /IDR mask is missing in IPv6/);
258+
259+
test.done();
260+
}
185261
}
186262
};

0 commit comments

Comments
 (0)