@@ -113,48 +113,63 @@ public function isEnabled()
113113 }
114114
115115 /**
116- * Returns true if this applications is being executed on a domain with a TLD
117- * that is commonly associated with a production environment.
116+ * Returns true if this application is being executed on a domain with a TLD
117+ * that is commonly associated with a production environment, or if the IP
118+ * address is not in a private or reserved range.
119+ *
120+ * Private IPv4 = 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16
121+ * Reserved IPv4 = 0.0.0.0/8, 169.254.0.0/16, 127.0.0.0/8 and 240.0.0.0/4
122+ *
123+ * Private IPv6 = fc00::/7
124+ * Reserved IPv6 = ::1/128, ::/128, ::ffff:0:0/96 and fe80::/10
118125 *
119126 * @return bool
120127 */
121128 protected function isSuspiciouslyProduction ()
122129 {
123- $ url = parse_url ('http:// ' . env ('HTTP_HOST ' ), PHP_URL_HOST );
124- if ($ url === false ) {
130+ $ host = parse_url ('http:// ' . env ('HTTP_HOST ' ), PHP_URL_HOST );
131+ if ($ host === false ) {
125132 return false ;
126133 }
127134
128- $ host = explode ('. ' , $ url );
129- $ first = current ($ host );
130- $ isIP = is_numeric (implode ('' , $ host ));
135+ // IPv6 addresses in URLs are enclosed in brackets. Remove them.
136+ $ host = trim ($ host , '[] ' );
131137
132- if (count ($ host ) === 1 ) {
133- return false ;
138+ // Check if the host is a private or reserved IPv4/6 address.
139+ $ isIp = filter_var ($ host , FILTER_VALIDATE_IP ) !== false ;
140+ if ($ isIp ) {
141+ $ flags = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ;
142+ $ isPublicIp = filter_var ($ host , FILTER_VALIDATE_IP , $ flags ) !== false ;
143+
144+ return $ isPublicIp ;
134145 }
135146
136- if ($ isIP && in_array ($ first , ['192 ' , '10 ' , '127 ' ])) {
137- // Accessing the app by private IP, this is safe
147+ // So it's not an IP address. It must be a domain name.
148+ $ parts = explode ('. ' , $ host );
149+ if (count ($ parts ) == 1 ) {
138150 return false ;
139151 }
140152
141- $ tld = end ($ host );
142- $ safeTopLevelDomains = ['localhost ' , 'invalid ' , 'test ' , 'example ' , 'local ' ];
143- $ safeTopLevelDomains = array_merge ($ safeTopLevelDomains , (array )$ this ->getConfig ('safeTld ' ));
153+ // Check if the TLD is in the list of safe TLDs.
154+ $ tld = end ($ parts );
155+ $ safeTlds = ['localhost ' , 'invalid ' , 'test ' , 'example ' , 'local ' ];
156+ $ safeTlds = array_merge ($ safeTlds , (array )$ this ->getConfig ('safeTld ' ));
157+
158+ if (in_array ($ tld , $ safeTlds , true )) {
159+ return false ;
160+ }
144161
145- if (! in_array ( $ tld , $ safeTopLevelDomains , true ) && ! $ this -> getConfig ( ' forceEnable ' )) {
146- $ host = implode ( ' . ' , $ host );
147- $ safeList = implode (', ' , $ safeTopLevelDomains );
162+ // Don't log a warning if forceEnable is set.
163+ if (! $ this -> getConfig ( ' forceEnable ' )) {
164+ $ safeList = implode (', ' , $ safeTlds );
148165 Log::warning (
149166 "DebugKit is disabling itself as your host ` {$ host }` " .
150167 "is not in the known safe list of top-level-domains ( {$ safeList }). " .
151168 'If you would like to force DebugKit on use the `DebugKit.forceEnable` Configure option. '
152169 );
153-
154- return true ;
155170 }
156171
157- return false ;
172+ return true ;
158173 }
159174
160175 /**
0 commit comments