Skip to content

Commit 79e1c1c

Browse files
fix(app-scripts): raise TLD character limit in allowNetworks validation from 6 to 63 (#2972)
The regex used in `isValidNetwork` capped TLD length at 6 characters ({2,6}), which incorrectly rejected valid domains whose TLD is longer than 6 characters (e.g. .hosting, .international, .construction). The upper bound is raised to 63, which is the maximum length of a single DNS label as defined by RFC 1035 §2.3.4. This is not arbitrary — it is the hard protocol-level ceiling that ICANN itself enforces when approving new TLDs. Since ICANN opened the generic TLD (gTLD) programme in 2012, hundreds of long TLDs have been delegated, making the previous limit of 6 both technically incorrect and a source of real customer friction. Fixes: customer was unable to upload a custom app using the allowNetworks entry `qa-gql-gateway.akzonobel.hosting` because `.hosting` (7 chars) exceeded the old limit. The outbound worker (functions-api-outbound-worker) is not affected — it uses the `tldts` library backed by the Public Suffix List, which has no character-length restriction and already handles long TLDs correctly. Made-with: Cursor
1 parent b783c2c commit 79e1c1c

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

packages/contentful--app-scripts/src/utils.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,31 @@ describe('isValidIpAddress', () => {
7070
const result = isValidNetwork('*');
7171
assert.strictEqual(result, false);
7272
});
73+
74+
it('returns true for a domain with a TLD longer than 6 characters', () => {
75+
// .hosting is 7 chars — previously rejected by the {2,6} limit.
76+
// Customers using long gTLDs (e.g. akzonobel.hosting) were blocked from
77+
// uploading custom apps even though the address is perfectly valid.
78+
const result = isValidNetwork('qa-gql-gateway.akzonobel.hosting');
79+
assert.strictEqual(result, true);
80+
});
81+
82+
it('returns true for a wildcard domain with a TLD longer than 6 characters', () => {
83+
const result = isValidNetwork('*.akzonobel.hosting');
84+
assert.strictEqual(result, true);
85+
});
86+
87+
it('returns true for a domain with a TLD at the maximum DNS label length of 63 characters', () => {
88+
const maxLengthTld = 'a'.repeat(63);
89+
const result = isValidNetwork(`example.${maxLengthTld}`);
90+
assert.strictEqual(result, true);
91+
});
92+
93+
it('returns false for a domain with a TLD exceeding the maximum DNS label length of 63 characters', () => {
94+
const tooLongTld = 'a'.repeat(64);
95+
const result = isValidNetwork(`example.${tooLongTld}`);
96+
assert.strictEqual(result, false);
97+
});
7398
});
7499

75100
describe('removeProtocolFromUrl', () => {

packages/contentful--app-scripts/src/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ export const isValidNetwork = (address: string): boolean => {
3737
'(?:' + // Start of the non-capturing group for domain names
3838
'(?:\\*\\.)' + // Matches wildcard domains like *.example.com
3939
'(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)' + // Matches a single subdomain
40-
'[a-zA-Z]{2,6}' + // Matches the top-level domain (TLD)
40+
'[a-zA-Z]{2,63}' + // Matches the top-level domain (TLD). Upper bound of 63 follows RFC 1035 §2.3.4, which defines the maximum length of a single DNS label. ICANN began delegating long gTLDs (e.g. .hosting, .international) from 2012 onwards, making the previous limit of 6 too restrictive.
4141
'|' + // OR
4242
'(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+' + // Matches standard domains with one or more subdomains
43-
'[a-zA-Z]{2,6}' + // Matches the top-level domain (TLD)
43+
'[a-zA-Z]{2,63}' + // Matches the top-level domain (TLD). Upper bound of 63 follows RFC 1035 §2.3.4, which defines the maximum length of a single DNS label. ICANN began delegating long gTLDs (e.g. .hosting, .international) from 2012 onwards, making the previous limit of 6 too restrictive.
4444
')|' + // End of the non-capturing group for domain names, OR
4545
'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}' + // Matches the first three octets of an IPv4 address
4646
'(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|' + // Matches the last octet of an IPv4 address

0 commit comments

Comments
 (0)