Skip to content

Commit 8602a82

Browse files
committed
Add nextjs-images-wildcard-hostname security rule
- Detects overly permissive wildcard hostnames in Next.js images.remotePatterns - Prevents image injection attacks and potential SSRF vulnerabilities - Includes comprehensive test cases with positive and negative examples - Follows security metadata standards (CWE-200, OWASP A05:2021) - Targets javascript and typescript languages Fixes: Security misconfiguration in Next.js image configuration Category: security Technology: nextjs
1 parent 12f2eb5 commit 8602a82

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Test cases for nextjs-images-wildcard-hostname rule
2+
3+
// BAD: Using wildcard hostname - should trigger the rule
4+
const badConfig1 = {
5+
images: {
6+
remotePatterns: [
7+
{
8+
protocol: 'https',
9+
hostname: '**', // ERROR: Wildcard hostname
10+
port: '',
11+
pathname: '/account123/**',
12+
},
13+
],
14+
},
15+
};
16+
17+
// BAD: Another wildcard hostname pattern - should trigger the rule
18+
const badConfig2 = {
19+
images: {
20+
remotePatterns: [
21+
{
22+
hostname: '**', // ERROR: Wildcard hostname
23+
},
24+
],
25+
},
26+
};
27+
28+
// BAD: Wildcard in nested structure - should trigger the rule
29+
const badConfig3 = {
30+
images: {
31+
remotePatterns: [
32+
{
33+
protocol: 'https',
34+
hostname: '**', // ERROR: Wildcard hostname
35+
port: '8080',
36+
pathname: '/images/**',
37+
},
38+
],
39+
},
40+
};
41+
42+
// GOOD: Specific domain - should not trigger the rule
43+
const goodConfig1 = {
44+
images: {
45+
remotePatterns: [
46+
{
47+
protocol: 'https',
48+
hostname: 'example.com', // OK: Specific domain
49+
port: '',
50+
pathname: '/account123/**',
51+
},
52+
],
53+
},
54+
};
55+
56+
// GOOD: Multiple specific domains - should not trigger the rule
57+
const goodConfig2 = {
58+
images: {
59+
remotePatterns: [
60+
{
61+
protocol: 'https',
62+
hostname: 'cdn.example.com', // OK: Specific subdomain
63+
port: '',
64+
pathname: '/images/**',
65+
},
66+
{
67+
protocol: 'https',
68+
hostname: 'assets.example.com', // OK: Another specific subdomain
69+
port: '',
70+
pathname: '/public/**',
71+
},
72+
],
73+
},
74+
};
75+
76+
// GOOD: Using subdomain wildcard (more restrictive) - should not trigger the rule
77+
const goodConfig3 = {
78+
images: {
79+
remotePatterns: [
80+
{
81+
protocol: 'https',
82+
hostname: '*.example.com', // OK: Subdomain wildcard (more restrictive)
83+
port: '',
84+
pathname: '/images/**',
85+
},
86+
],
87+
},
88+
};
89+
90+
// GOOD: Localhost and specific IP - should not trigger the rule
91+
const goodConfig4 = {
92+
images: {
93+
remotePatterns: [
94+
{
95+
protocol: 'http',
96+
hostname: 'localhost', // OK: Localhost
97+
port: '3000',
98+
pathname: '/uploads/**',
99+
},
100+
{
101+
protocol: 'https',
102+
hostname: '192.168.1.100', // OK: Specific IP
103+
port: '',
104+
pathname: '/media/**',
105+
},
106+
],
107+
},
108+
};
109+
110+
// GOOD: Empty remotePatterns - should not trigger the rule
111+
const goodConfig5 = {
112+
images: {
113+
remotePatterns: [], // OK: Empty array
114+
},
115+
};
116+
117+
// GOOD: No images config - should not trigger the rule
118+
const goodConfig6 = {
119+
// No images configuration
120+
experimental: {
121+
appDir: true,
122+
},
123+
};
124+
125+
// GOOD: Images config without remotePatterns - should not trigger the rule
126+
const goodConfig7 = {
127+
images: {
128+
domains: ['example.com'], // OK: Using domains instead of remotePatterns
129+
},
130+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
rules:
2+
- id: nextjs-images-wildcard-hostname
3+
message: >-
4+
Avoid using '**' for images.remotePatterns.hostname (overly permissive, security risk).
5+
Using wildcard hostnames allows loading images from any domain, which can lead to:
6+
- Image injection attacks
7+
- Data exfiltration through image requests
8+
- Potential SSRF vulnerabilities
9+
Instead, specify exact domains or use more restrictive patterns.
10+
languages:
11+
- javascript
12+
- typescript
13+
severity: ERROR
14+
patterns:
15+
- pattern: |
16+
{
17+
hostname: "**"
18+
}
19+
- pattern-inside: |
20+
images: {
21+
remotePatterns: [
22+
...
23+
]
24+
}
25+
metadata:
26+
category: security
27+
technology:
28+
- nextjs
29+
subcategory:
30+
- vuln
31+
confidence: HIGH
32+
likelihood: MEDIUM
33+
impact: MEDIUM
34+
cwe:
35+
- "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
36+
owasp:
37+
- A05:2021 - Security Misconfiguration
38+
references:
39+
- https://nextjs.org/docs/app/api-reference/next-config-js/images#remotepatterns
40+
- https://nextjs.org/docs/pages/api-reference/next-config-js/images#remotepatterns

0 commit comments

Comments
 (0)