1
+ if let url = URL ( string: " https://mail.google.com/mail/u/0/ " ) {
2
+ if let host = url. host {
3
+ print ( " URL: \( url) " )
4
+ print ( " Host: \( host) " )
5
+ // ruleid: insecure-url-host-hassuffix-check
6
+ if host. hasSuffix ( " google.com " ) {
7
+ print ( " This is a Google domain! " )
8
+ } else {
9
+ print ( " This is not a Google domain. " )
10
+ }
11
+ }
12
+ }
13
+
14
+
15
+ if let url = URL ( string: " https://mail.google.com/mail/u/0/ " ) {
16
+ if let host = url. host {
17
+ print ( " URL: \( url) " )
18
+ print ( " Host: \( host) " )
19
+ // ruleid: insecure-url-host-hassuffix-check
20
+ if host. hasSuffix ( " google.com " ) {
21
+ print ( " This is a Google domain! " )
22
+ } else {
23
+ print ( " This is not a Google domain. " )
24
+ }
25
+ }
26
+ }
27
+
28
+ // ruleid: insecure-url-host-hassuffix-check
29
+ URL ( string: " https://example.com " ) ? . host? . hasSuffix ( " google.com " )
30
+ let url = URL ( string: someString)
31
+ // ruleid: insecure-url-host-hassuffix-check
32
+ url? . host? . hasSuffix ( " domain.com " )
33
+
34
+ // ok: insecure-url-host-hassuffix-check
35
+ URL ( string: " https://example.com " ) ? . host? . hasSuffix ( " .google.com " )
36
+ let url = URL ( string: someString)
37
+ // ok: insecure-url-host-hassuffix-check
38
+ url? . host? . hasSuffix ( " .domain.com " )
39
+
40
+
41
+ extension URL {
42
+ /// Returns whether the URL matches Slack's top level domain.
43
+ var isSlackHost : Bool {
44
+ // ruleid: insecure-url-host-hassuffix-check
45
+ host? . hasSuffix ( " slack.com " ) ?? false
46
+ }
47
+
48
+ public var isSlackOpenURL : Bool {
49
+ guard
50
+ isSlackHost,
51
+ x [ y: 1 ] == " z "
52
+ else {
53
+ return false
54
+ }
55
+ return true
56
+ }
57
+ }
58
+
59
+ func case1_nestedIfLet( ) {
60
+ if let url = URL ( string: " https://mail.google.com/mail/u/0/ " ) {
61
+ if let host = url. host {
62
+ print ( " URL: \( url) " )
63
+ print ( " Host: \( host) " )
64
+
65
+ // ruleid: insecure-url-host-hassuffix-check
66
+ if host. hasSuffix ( " google.com " ) {
67
+ print ( " This is a Google domain! " )
68
+ } else {
69
+ print ( " This is not a Google domain. " )
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ func testDifferentVariableNames( ) {
76
+ // Test with different variable names
77
+ if let url = URL ( string: " https://docs.google.com " ) {
78
+ if let serverName = url. host {
79
+ // ruleid: insecure-url-host-hassuffix-check
80
+ if serverName. hasSuffix ( " google.com " ) {
81
+ print ( " Google server " )
82
+ }
83
+ }
84
+ }
85
+
86
+ if let url = URL ( string: " https://slack.com " ) {
87
+ if let domain = url. host {
88
+ // ruleid: insecure-url-host-hassuffix-check
89
+ if domain. hasSuffix ( " slack.com " ) {
90
+ print ( " Slack domain " )
91
+ }
92
+ }
93
+ }
94
+
95
+ let someURL = URL ( string: " https://github.com " )
96
+ if let hostname = someURL? . host {
97
+ // ruleid: insecure-url-host-hassuffix-check
98
+ if hostname. hasSuffix ( " github.com " ) {
99
+ print ( " GitHub hostname " )
100
+ }
101
+ }
102
+ }
103
+
104
+ func case2_directChaining( ) {
105
+ let urlString = " https://docs.google.com/document "
106
+
107
+ // ruleid: insecure-url-host-hassuffix-check
108
+ if URL ( string: urlString) ? . host? . hasSuffix ( " google.com " ) == true {
109
+ print ( " Google domain detected " )
110
+ }
111
+
112
+ let trusted = " https://slack.com/workspace "
113
+ // ruleid: insecure-url-host-hassuffix-check
114
+ if URL ( string: trusted) !. host!. hasSuffix ( " slack.com " ) {
115
+ print ( " Slack domain " )
116
+ }
117
+
118
+ // ruleid: insecure-url-host-hassuffix-check
119
+ if URL ( string: urlString) ? . host. hasSuffix ( " google.com " ) == true {
120
+ print ( " Another Google check " )
121
+ }
122
+ }
123
+
124
+ extension URL {
125
+ var isSlackHost : Bool {
126
+ // ruleid: insecure-url-host-hassuffix-check
127
+ host? . hasSuffix ( " slack.com " ) ?? false
128
+ }
129
+
130
+ var isGoogleHost : Bool {
131
+ // ruleid: insecure-url-host-hassuffix-check
132
+ self . host? . hasSuffix ( " google.com " ) ?? false
133
+ }
134
+
135
+ var isGitHubHost : Bool {
136
+ guard let host = host else { return false }
137
+ // ruleid: insecure-url-host-hassuffix-check
138
+ return host. hasSuffix ( " github.com " )
139
+ }
140
+
141
+ var isMicrosoftHost : Bool {
142
+ // ruleid: insecure-url-host-hassuffix-check
143
+ self . host? . hasSuffix ( " microsoft.com " ) ?? false
144
+ }
145
+ }
146
+
147
+ func case4_urlVariable( ) {
148
+ let myURL = URL ( string: " https://app.slack.com/client " )
149
+
150
+ // ruleid: insecure-url-host-hassuffix-check
151
+ if myURL? . host? . hasSuffix ( " slack.com " ) == true {
152
+ print ( " Slack URL confirmed " )
153
+ }
154
+
155
+ // Another variation
156
+ let anotherURL = URL ( string: " https://drive.google.com " )
157
+
158
+ // ruleid: insecure-url-host-hassuffix-check
159
+ if anotherURL!. host? . hasSuffix ( " google.com " ) == true {
160
+ print ( " Google Drive URL " )
161
+ }
162
+
163
+ // ruleid: insecure-url-host-hassuffix-check
164
+ if myURL? . host. hasSuffix ( " slack.com " ) == true {
165
+ print ( " Another Slack check " )
166
+ }
167
+ }
168
+
169
+ func case5_hostExtracted( ) {
170
+ let url = URL ( string: " https://mail.yahoo.com " )
171
+
172
+ let extractedHost = url? . host
173
+
174
+ // ruleid: insecure-url-host-hassuffix-check
175
+ if extractedHost? . hasSuffix ( " yahoo.com " ) == true {
176
+ print ( " Yahoo mail detected " )
177
+ }
178
+ }
179
+
180
+ func case6_directHostBinding( ) {
181
+ let urlString = " https://teams.microsoft.com/meeting "
182
+
183
+
184
+ if let host = URL ( string: urlString) ? . host {
185
+ // ruleid: insecure-url-host-hassuffix-check
186
+ if host. hasSuffix ( " microsoft.com " ) {
187
+ print ( " Microsoft Teams URL " )
188
+ }
189
+ }
190
+ }
191
+
192
+ func case7_singleIfLetURL( ) {
193
+ let input = " https://calendar.google.com/calendar "
194
+ if let url = URL ( string: input) {
195
+ // Some other logic here
196
+ print ( " Processing URL: \( url) " )
197
+
198
+ // ruleid: insecure-url-host-hassuffix-check
199
+ if url. host? . hasSuffix ( " google.com " ) == true {
200
+ print ( " Google Calendar detected " )
201
+ }
202
+ }
203
+ }
204
+
205
+ // Function with URL parameter
206
+ func validateDomain( url: URL ) -> Bool {
207
+ // ruleid: insecure-url-host-hassuffix-check
208
+ return url. host? . hasSuffix ( " example.com " ) ?? false
209
+ }
210
+
211
+ // Guard let patterns
212
+ func processURL( urlString: String ) {
213
+ guard let url = URL ( string: urlString) else { return }
214
+
215
+ // ruleid: insecure-url-host-hassuffix-check
216
+ guard url. host? . hasSuffix ( " trusted.com " ) == true else {
217
+ print ( " Untrusted domain " )
218
+ return
219
+ }
220
+
221
+ print ( " Processing trusted domain " )
222
+ }
223
+
224
+ // Nested guard patterns
225
+ func complexGuardPattern( input: String ) {
226
+ guard let url = URL ( string: input) else { return }
227
+ guard let host = url. host else { return }
228
+
229
+ // ruleid: insecure-url-host-hassuffix-check
230
+ if host. hasSuffix ( " secure.net " ) {
231
+ print ( " Secure network domain " )
232
+ }
233
+ }
234
+
235
+ // Class/Struct with URL property
236
+ class URLValidator {
237
+ let url : URL
238
+
239
+ init ? ( urlString: String ) {
240
+ guard let url = URL ( string: urlString) else { return nil }
241
+ self . url = url
242
+ }
243
+
244
+ func isCompanyDomain( ) -> Bool {
245
+ // ruleid: insecure-url-host-hassuffix-check
246
+ return url. host? . hasSuffix ( " company.com " ) ?? false
247
+ }
248
+ }
249
+
250
+ // Switch statement with multiple domains
251
+ func categorizeURL( _ urlString: String ) {
252
+ guard let url = URL ( string: urlString) ,
253
+ let host = url. host else { return }
254
+
255
+ switch true {
256
+ // ruleid: insecure-url-host-hassuffix-check
257
+ case host. hasSuffix ( " google.com " ) :
258
+ print ( " Google service " )
259
+ // ruleid: insecure-url-host-hassuffix-check
260
+ case host. hasSuffix ( " microsoft.com " ) :
261
+ print ( " Microsoft service " )
262
+ // ruleid: insecure-url-host-hassuffix-check
263
+ case host. hasSuffix ( " apple.com " ) :
264
+ print ( " Apple service " )
265
+ default :
266
+ print ( " Other service " )
267
+ }
268
+ }
269
+
270
+ func correctExamples( ) {
271
+ if let url = URL ( string: " https://mail.google.com " ) {
272
+ if let host = url. host {
273
+ // ok: insecure-url-host-hassuffix-check
274
+ if host. hasSuffix ( " .google.com " ) {
275
+ print ( " Google subdomain " )
276
+ }
277
+
278
+ // ok: insecure-url-host-hassuffix-check
279
+ if host. hasSuffix ( " .google.com " ) || host == " google.com " {
280
+ print ( " Google domain or subdomain " )
281
+ }
282
+ }
283
+ }
284
+ }
285
+
286
+ extension URL {
287
+ // ok: insecure-url-host-hassuffix-check
288
+ var isProperSlackHost : Bool {
289
+ guard let host = host else { return false }
290
+ return host. hasSuffix ( " .slack.com " ) || host == " slack.com "
291
+ }
292
+ }
293
+
294
+ // Normal string operations - should NOT be flagged
295
+ func normalStringOperations( ) {
296
+
297
+ // ok: insecure-url-host-hassuffix-check
298
+ if email. hasSuffix ( " google.com " ) {
299
+ print ( " Google email " )
300
+ }
301
+
302
+ let filename = " document.google.com "
303
+ // ok: insecure-url-host-hassuffix-check
304
+ if filename. hasSuffix ( " google.com " ) {
305
+ print ( " Filename ends with google.com " )
306
+ }
307
+
308
+ let randomString = " This is not a URL but ends with microsoft.com "
309
+ // ok: insecure-url-host-hassuffix-check
310
+ if randomString. hasSuffix ( " microsoft.com " ) {
311
+ print ( " String ends with microsoft.com " )
312
+ }
313
+
314
+ let userInput = getUserInput ( )
315
+ // ok: insecure-url-host-hassuffix-check
316
+ if userInput. hasSuffix ( " apple.com " ) {
317
+ print ( " User input ends with apple.com " )
318
+ }
319
+ }
320
+
321
+ // More edge cases
322
+ func edgeCases( ) {
323
+ // URLComponents host check
324
+ var components = URLComponents ( string: " https://docs.google.com " )
325
+ // ruleid: insecure-url-host-hassuffix-check
326
+ if components? . host? . hasSuffix ( " google.com " ) == true {
327
+ print ( " Google docs " )
328
+ }
329
+
330
+ // Computed property
331
+ struct Request {
332
+ let url : URL
333
+
334
+ var isGoogleDomain : Bool {
335
+ // ruleid: insecure-url-host-hassuffix-check
336
+ url. host? . hasSuffix ( " google.com " ) ?? false
337
+ }
338
+ }
339
+
340
+ // Closure with URL
341
+ let checkDomain : ( URL ) -> Bool = { url in
342
+ // ruleid: insecure-url-host-hassuffix-check
343
+ url. host? . hasSuffix ( " example.com " ) ?? false
344
+ }
345
+
346
+ // Array of URLs
347
+ let urls = [ URL ( string: " https://mail.google.com " ) !]
348
+ for url in urls {
349
+ // ruleid: insecure-url-host-hassuffix-check
350
+ if url. host? . hasSuffix ( " google.com " ) == true {
351
+ print ( " Found Google URL " )
352
+ }
353
+ }
354
+ }
0 commit comments