@runhalo/engine 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast-engine.d.ts +60 -0
- package/dist/ast-engine.js +653 -0
- package/dist/ast-engine.js.map +1 -0
- package/dist/context-analyzer.d.ts +209 -0
- package/dist/context-analyzer.js +401 -0
- package/dist/context-analyzer.js.map +1 -0
- package/dist/data-flow-tracer.d.ts +106 -0
- package/dist/data-flow-tracer.js +506 -0
- package/dist/data-flow-tracer.js.map +1 -0
- package/dist/frameworks/django.d.ts +11 -0
- package/dist/frameworks/django.js +57 -0
- package/dist/frameworks/django.js.map +1 -0
- package/dist/frameworks/index.d.ts +59 -0
- package/dist/frameworks/index.js +93 -0
- package/dist/frameworks/index.js.map +1 -0
- package/dist/frameworks/nextjs.d.ts +11 -0
- package/dist/frameworks/nextjs.js +59 -0
- package/dist/frameworks/nextjs.js.map +1 -0
- package/dist/frameworks/rails.d.ts +11 -0
- package/dist/frameworks/rails.js +58 -0
- package/dist/frameworks/rails.js.map +1 -0
- package/dist/frameworks/types.d.ts +29 -0
- package/dist/frameworks/types.js +11 -0
- package/dist/frameworks/types.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +105 -7
- package/dist/index.js.map +1 -1
- package/dist/scope-analyzer.d.ts +91 -0
- package/dist/scope-analyzer.js +300 -0
- package/dist/scope-analyzer.js.map +1 -0
- package/package.json +6 -2
- package/rules/rules.json +1699 -72
- package/rules/validation-report.json +58 -0
package/rules/rules.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"coppa": {
|
|
6
6
|
"id": "coppa",
|
|
7
7
|
"name": "COPPA 2.0 Core",
|
|
8
|
-
"description": "
|
|
8
|
+
"description": "25 rules for COPPA & COPPA 2.0 compliance. Effective April 22, 2026.",
|
|
9
9
|
"jurisdiction": "US-Federal",
|
|
10
10
|
"jurisdiction_level": "federal",
|
|
11
11
|
"is_free": true,
|
|
@@ -51,6 +51,56 @@
|
|
|
51
51
|
"is_free": true,
|
|
52
52
|
"effective_date": "2026-05-06",
|
|
53
53
|
"source_url": "https://le.utah.gov/~2025/bills/static/SB0142.html"
|
|
54
|
+
},
|
|
55
|
+
"uk-aadc": {
|
|
56
|
+
"id": "uk-aadc",
|
|
57
|
+
"name": "UK Age Appropriate Design Code",
|
|
58
|
+
"description": "15 rules for the UK ICO Children's Code (AADC) — the 15 standards for age-appropriate online services.",
|
|
59
|
+
"jurisdiction": "UK",
|
|
60
|
+
"jurisdiction_level": "national",
|
|
61
|
+
"is_free": false,
|
|
62
|
+
"effective_date": "2021-09-02",
|
|
63
|
+
"source_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/"
|
|
64
|
+
},
|
|
65
|
+
"eu-dsa": {
|
|
66
|
+
"id": "eu-dsa",
|
|
67
|
+
"name": "EU DSA Article 28 (Minor Protection)",
|
|
68
|
+
"description": "10 rules for EU Digital Services Act Article 28 — online protection of minors on platforms.",
|
|
69
|
+
"jurisdiction": "EU",
|
|
70
|
+
"jurisdiction_level": "supranational",
|
|
71
|
+
"is_free": false,
|
|
72
|
+
"effective_date": "2024-02-17",
|
|
73
|
+
"source_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
74
|
+
},
|
|
75
|
+
"au-osa": {
|
|
76
|
+
"id": "au-osa",
|
|
77
|
+
"name": "AU Online Safety Act",
|
|
78
|
+
"description": "12 rules for Australia's Online Safety Act 2021 (as amended 2024) — age verification, content moderation, under-16 social media ban, and eSafety Commissioner compliance.",
|
|
79
|
+
"jurisdiction": "AU-Federal",
|
|
80
|
+
"jurisdiction_level": "federal",
|
|
81
|
+
"is_free": false,
|
|
82
|
+
"effective_date": "2025-01-01",
|
|
83
|
+
"source_url": "https://www.esafety.gov.au/whats-on/online-safety-act"
|
|
84
|
+
},
|
|
85
|
+
"caadca": {
|
|
86
|
+
"id": "caadca",
|
|
87
|
+
"name": "California AADCA",
|
|
88
|
+
"description": "15 rules for the California Age-Appropriate Design Code Act (AB 2273) — default privacy, age estimation, profiling restrictions, dark pattern prohibitions, and data minimization for child users.",
|
|
89
|
+
"jurisdiction": "US-CA",
|
|
90
|
+
"jurisdiction_level": "state",
|
|
91
|
+
"is_free": false,
|
|
92
|
+
"effective_date": "2024-07-01",
|
|
93
|
+
"source_url": "https://leginfo.legislature.ca.gov/faces/billNavClient.xhtml?bill_id=202120220AB2273"
|
|
94
|
+
},
|
|
95
|
+
"eu-ai-act": {
|
|
96
|
+
"id": "eu-ai-act",
|
|
97
|
+
"name": "EU AI Act (Children)",
|
|
98
|
+
"description": "15 rules for EU AI Act compliance in children's AI systems — risk management (Art. 9), transparency (Art. 13), and constitutional AI principles.",
|
|
99
|
+
"jurisdiction": "EU",
|
|
100
|
+
"jurisdiction_level": "supranational",
|
|
101
|
+
"is_free": false,
|
|
102
|
+
"effective_date": "2026-08-01",
|
|
103
|
+
"source_url": "https://artificialintelligenceact.eu/"
|
|
54
104
|
}
|
|
55
105
|
},
|
|
56
106
|
"rules": [
|
|
@@ -58,6 +108,7 @@
|
|
|
58
108
|
"id": "coppa-auth-001",
|
|
59
109
|
"name": "Unverified Social Login Providers",
|
|
60
110
|
"severity": "critical",
|
|
111
|
+
"confidence": "low",
|
|
61
112
|
"category": "auth",
|
|
62
113
|
"description": "Social login (Google, Facebook, Twitter) without age gating is prohibited for child-directed apps",
|
|
63
114
|
"patterns": [
|
|
@@ -90,13 +141,14 @@
|
|
|
90
141
|
"id": "coppa-data-002",
|
|
91
142
|
"name": "PII Collection in URL Parameters",
|
|
92
143
|
"severity": "high",
|
|
144
|
+
"confidence": "medium",
|
|
93
145
|
"category": "data",
|
|
94
146
|
"description": "Email, name, DOB, or phone in GET request URLs exposes PII in logs",
|
|
95
147
|
"patterns": [
|
|
96
|
-
{ "pattern": "(\\?|&)(email|first_?name|last_?name|dob|phone|birthdate)=", "flags": "gi" },
|
|
97
|
-
{ "pattern": "axios\\.get\\s*\\(\\s*[`'\"]https?://[^\\s]*\\?[^`'\"]*\\$\\{", "flags": "gi" },
|
|
98
|
-
{ "pattern": "fetch\\s*\\(\\s*[`'\"]https?://[^\\s]*\\?[^`'\"]*\\$\\{", "flags": "gi" },
|
|
99
|
-
{ "pattern": "\\?[^'\"`\\s]*\\$\\{[^}]*(?:\\.email|\\.firstName|\\.lastName|\\.dob|\\.phone)[^}]*\\}", "flags": "gi" }
|
|
148
|
+
{ "pattern": "(?<!(?:test|spec|mock|fixture|example|__test__|__mock__|__fixture__)[^\\n]{0,50})(\\?|&)(email|first_?name|last_?name|dob|phone|birthdate)=", "flags": "gi" },
|
|
149
|
+
{ "pattern": "axios\\.get\\s*\\(\\s*[`'\"]https?://[^\\s]*\\?[^`'\"]*(?:email|first_?name|last_?name|dob|phone|birthdate|birth_?date|ssn|username)=[^`'\"]*\\$\\{", "flags": "gi" },
|
|
150
|
+
{ "pattern": "fetch\\s*\\(\\s*[`'\"]https?://[^\\s]*\\?[^`'\"]*(?:email|first_?name|last_?name|dob|phone|birthdate|birth_?date|ssn|username)=[^`'\"]*\\$\\{", "flags": "gi" },
|
|
151
|
+
{ "pattern": "\\?[^'\"`\\s]*\\$\\{[^}]*(?:\\.email|\\.firstName|\\.lastName|\\.dob|\\.phone|\\.birthdate|\\.ssn)[^}]*\\}", "flags": "gi" }
|
|
100
152
|
],
|
|
101
153
|
"fix_suggestion": "Switch to POST method and move PII to request body",
|
|
102
154
|
"penalty": "$51,744 per violation",
|
|
@@ -111,6 +163,7 @@
|
|
|
111
163
|
"id": "coppa-tracking-003",
|
|
112
164
|
"name": "Third-Party Ad Trackers",
|
|
113
165
|
"severity": "critical",
|
|
166
|
+
"confidence": "low",
|
|
114
167
|
"category": "tracking",
|
|
115
168
|
"description": "Facebook Pixel, Google Analytics, or other ad trackers without child_directed_treatment flag",
|
|
116
169
|
"patterns": [
|
|
@@ -133,6 +186,7 @@
|
|
|
133
186
|
"id": "coppa-geo-004",
|
|
134
187
|
"name": "Precise Geolocation Collection",
|
|
135
188
|
"severity": "high",
|
|
189
|
+
"confidence": "low",
|
|
136
190
|
"category": "geo",
|
|
137
191
|
"description": "High-accuracy geolocation without parental consent is prohibited",
|
|
138
192
|
"patterns": [
|
|
@@ -161,10 +215,11 @@
|
|
|
161
215
|
"id": "coppa-retention-005",
|
|
162
216
|
"name": "Missing Data Retention Policy",
|
|
163
217
|
"severity": "medium",
|
|
218
|
+
"confidence": "medium",
|
|
164
219
|
"category": "retention",
|
|
165
|
-
"description": "User schemas must have deleted_at, expiration_date, or TTL index for data retention",
|
|
220
|
+
"description": "User schemas containing PII fields must have deleted_at, expiration_date, or TTL index for data retention",
|
|
166
221
|
"patterns": [
|
|
167
|
-
{ "pattern": "new\\s+Schema\\s*\\(\\s*\\{[^{}]*\\}", "flags": "gi" },
|
|
222
|
+
{ "pattern": "new\\s+Schema\\s*\\(\\s*\\{[^{}]*(?:email|password|username|phone|dob|birth|firstName|lastName|first_name|last_name|fullName|full_name|displayName|display_name|address|ssn)[^{}]*\\}", "flags": "gi" },
|
|
168
223
|
{ "pattern": "class\\s+(?:User|Child|Student|Profile|Account|Member)\\w*\\s*\\(\\s*models\\.Model\\s*\\)", "flags": "gi" },
|
|
169
224
|
{ "pattern": "class\\s+(?:User|Child|Student|Profile|Account|Member)\\w*\\s*\\(\\s*(?:Base|db\\.Model)\\s*\\)", "flags": "gi" },
|
|
170
225
|
{ "pattern": "type\\s+(?:User|Child|Student|Profile|Account|Member)\\w*\\s+struct\\s*\\{", "flags": "gi" },
|
|
@@ -184,14 +239,14 @@
|
|
|
184
239
|
"id": "coppa-sec-006",
|
|
185
240
|
"name": "Unencrypted PII Transmission",
|
|
186
241
|
"severity": "critical",
|
|
242
|
+
"confidence": "medium",
|
|
187
243
|
"category": "security",
|
|
188
244
|
"description": "HTTP transmission of PII exposes data in transit. All API endpoints handling personal information must use HTTPS.",
|
|
189
245
|
"patterns": [
|
|
190
|
-
{ "pattern": "http://[^\\s]*(/api/|/login|/user|/register|/profile)", "flags": "gi" },
|
|
191
|
-
{ "pattern": "http://localhost
|
|
192
|
-
{ "pattern": "
|
|
193
|
-
{ "pattern": "
|
|
194
|
-
{ "pattern": "http://[^\\s]*email[^\\s]*", "flags": "gi" }
|
|
246
|
+
{ "pattern": "http://(?!localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|\\[::1\\]|10\\.|192\\.168\\.|172\\.(?:1[6-9]|2[0-9]|3[01]))[^\\s]*(/api/|/login|/user|/register|/profile)", "flags": "gi" },
|
|
247
|
+
{ "pattern": "axios\\.get\\s*\\(\\s*['\"]http://(?!localhost|127\\.0\\.0\\.1)", "flags": "gi" },
|
|
248
|
+
{ "pattern": "fetch\\s*\\(\\s*['\"]http://(?!localhost|127\\.0\\.0\\.1)", "flags": "gi" },
|
|
249
|
+
{ "pattern": "http://(?!localhost|127\\.0\\.0\\.1)[^\\s]*email[^\\s]*", "flags": "gi" }
|
|
195
250
|
],
|
|
196
251
|
"fix_suggestion": "Replace http:// with https:// for all API endpoints and resources",
|
|
197
252
|
"penalty": "Security breach liability + COPPA penalties",
|
|
@@ -206,6 +261,7 @@
|
|
|
206
261
|
"id": "coppa-audio-007",
|
|
207
262
|
"name": "Unauthorized Audio Recording",
|
|
208
263
|
"severity": "high",
|
|
264
|
+
"confidence": "low",
|
|
209
265
|
"category": "audio",
|
|
210
266
|
"description": "Audio recording without explicit user consent is prohibited. COPPA 2.0 clarifies voice prints as biometric data.",
|
|
211
267
|
"patterns": [
|
|
@@ -230,12 +286,13 @@
|
|
|
230
286
|
"id": "coppa-ui-008",
|
|
231
287
|
"name": "Missing Privacy Policy on Registration",
|
|
232
288
|
"severity": "medium",
|
|
289
|
+
"confidence": "medium",
|
|
233
290
|
"category": "ui",
|
|
234
291
|
"description": "Registration forms collecting PII must include a clear link to the privacy policy",
|
|
235
292
|
"patterns": [
|
|
236
|
-
{ "pattern": "\\b(?:SignUp|Register|Registration|CreateAccount)Form\\b", "flags": "gi" },
|
|
237
|
-
{ "pattern": "\\b(?:sign[-_]?up|register|registration|create[-_]?account)[-_]form\\b", "flags": "gi" },
|
|
238
|
-
{ "pattern": "<form[^>]*(?:id|class|name)\\s*=\\s*[\"'][^\"']*(?:register|signup|sign[-_]up|create[-_]account)[^\"']*[\"']", "flags": "gi" }
|
|
293
|
+
{ "pattern": "(?<!(?:interface|type|import|from|require|mock|Mock|jest\\.fn)\\s{0,10})\\b(?!Admin|Teacher|Staff|Instructor|Educator|Parent|Guardian)(?:SignUp|Register|Registration|CreateAccount)Form\\b(?!\\s*(?:\\{|<|\\||&|extends|implements))", "flags": "gi" },
|
|
294
|
+
{ "pattern": "(?<!(?:import|from|require|mock|type|interface)\\s{0,10})\\b(?!admin[-_]?|teacher[-_]?|staff[-_]?|instructor[-_]?|parent[-_]?)(?:sign[-_]?up|register|registration|create[-_]?account)[-_]form\\b(?!\\s*(?:type|interface|schema))", "flags": "gi" },
|
|
295
|
+
{ "pattern": "<form[^>]*(?:id|class|name)\\s*=\\s*[\"'][^\"']*(?!admin|teacher|staff|instructor|educator|parent|guardian)(?:register|signup|sign[-_]up|create[-_]account)[^\"']*[\"']", "flags": "gi" }
|
|
239
296
|
],
|
|
240
297
|
"fix_suggestion": "Add <a href=\"/privacy\">Privacy Policy</a> link to registration form footer",
|
|
241
298
|
"penalty": "Compliance failure",
|
|
@@ -250,6 +307,7 @@
|
|
|
250
307
|
"id": "coppa-flow-009",
|
|
251
308
|
"name": "Direct Contact Collection Without Parent Context",
|
|
252
309
|
"severity": "high",
|
|
310
|
+
"confidence": "high",
|
|
253
311
|
"category": "flow",
|
|
254
312
|
"description": "Forms collecting child email/phone must also require parent email for consent verification",
|
|
255
313
|
"patterns": [
|
|
@@ -269,13 +327,14 @@
|
|
|
269
327
|
"id": "coppa-sec-010",
|
|
270
328
|
"name": "Weak Default Student Passwords",
|
|
271
329
|
"severity": "medium",
|
|
330
|
+
"confidence": "high",
|
|
272
331
|
"category": "security",
|
|
273
332
|
"description": "Default passwords like \"password\", \"123456\", or \"changeme\" create security vulnerabilities",
|
|
274
333
|
"patterns": [
|
|
275
|
-
{ "pattern": "(password|default_pass|temp_password)\\s
|
|
334
|
+
{ "pattern": "(?:const|let|var|export|config|env|setting)\\s*(?:\\w+\\s*=\\s*\\{[^}]*?)?(password|default_pass|temp_password)\\s*[:=]\\s*['\"](123456|password|changeme|student|welcome)['\"]", "flags": "gi" },
|
|
276
335
|
{ "pattern": "defaultPassword:\\s*['\"](123456|password|changeme)['\"]", "flags": "gi" },
|
|
277
336
|
{ "pattern": "initialPassword:\\s*['\"](123456|password)['\"]", "flags": "gi" },
|
|
278
|
-
{ "pattern": "
|
|
337
|
+
{ "pattern": "(?:const|let|var|config)\\s*\\w*[Pp]ass\\w*\\s*=\\s*['\"](student123|child123|default)['\"]", "flags": "gi" }
|
|
279
338
|
],
|
|
280
339
|
"fix_suggestion": "Use a secure random string generator for temporary credentials",
|
|
281
340
|
"penalty": "Security audit failure",
|
|
@@ -290,6 +349,7 @@
|
|
|
290
349
|
"id": "coppa-ext-011",
|
|
291
350
|
"name": "Unmoderated Third-Party Chat",
|
|
292
351
|
"severity": "high",
|
|
352
|
+
"confidence": "medium",
|
|
293
353
|
"category": "external",
|
|
294
354
|
"description": "Third-party chat widgets (Intercom, Zendesk, Drift) allow children to disclose PII freely",
|
|
295
355
|
"patterns": [
|
|
@@ -313,6 +373,7 @@
|
|
|
313
373
|
"id": "coppa-bio-012",
|
|
314
374
|
"name": "Biometric Data Collection",
|
|
315
375
|
"severity": "critical",
|
|
376
|
+
"confidence": "medium",
|
|
316
377
|
"category": "biometric",
|
|
317
378
|
"description": "Face recognition, voice prints, or gait analysis requires explicit parental consent. COPPA 2.0 explicitly classifies biometrics as PI.",
|
|
318
379
|
"patterns": [
|
|
@@ -337,6 +398,7 @@
|
|
|
337
398
|
"id": "coppa-notif-013",
|
|
338
399
|
"name": "Direct Push Notifications Without Consent",
|
|
339
400
|
"severity": "medium",
|
|
401
|
+
"confidence": "low",
|
|
340
402
|
"category": "notification",
|
|
341
403
|
"description": "Push notifications are \"Online Contact Info\" under COPPA 2.0. Direct notifications to children require parental consent.",
|
|
342
404
|
"patterns": [
|
|
@@ -361,15 +423,16 @@
|
|
|
361
423
|
"id": "coppa-ugc-014",
|
|
362
424
|
"name": "UGC Upload Without PII Filter",
|
|
363
425
|
"severity": "high",
|
|
426
|
+
"confidence": "medium",
|
|
364
427
|
"category": "ugc",
|
|
365
428
|
"description": "Text areas for \"bio\", \"about me\", or comments must pass through PII scrubbing before database storage",
|
|
366
429
|
"patterns": [
|
|
367
430
|
{ "pattern": "<textarea[^>]*placeholder=[\"'](?:bio|about me|describe yourself)[^\"']*[\"']", "flags": "gi" },
|
|
368
431
|
{ "pattern": "user\\.bio\\s*=", "flags": "gi" },
|
|
369
432
|
{ "pattern": "aboutMe\\s*=", "flags": "gi" },
|
|
370
|
-
{ "pattern": "(?:submit|save|post)Comment\\s*\\(", "flags": "gi" },
|
|
371
|
-
{ "pattern": "saveBio
|
|
372
|
-
{ "pattern": "commentForm.*submit|handleCommentSubmit", "flags": "gi" }
|
|
433
|
+
{ "pattern": "(?:submit|save|post)Comment\\s*\\((?![^)]*(?:admin|moderate|internal|review))", "flags": "gi" },
|
|
434
|
+
{ "pattern": "(?:saveBio|updateBio)\\s*\\((?![^)]*(?:admin|moderate|internal))", "flags": "gi" },
|
|
435
|
+
{ "pattern": "(?<!admin|Admin|moderate|Moderate)(?:commentForm.*submit|handleCommentSubmit)", "flags": "gi" }
|
|
373
436
|
],
|
|
374
437
|
"fix_suggestion": "Add middleware hook for PII scrubbing (regex or AWS Comprehend) before database storage",
|
|
375
438
|
"penalty": "$51,744 per violation",
|
|
@@ -384,6 +447,7 @@
|
|
|
384
447
|
"id": "coppa-sec-015",
|
|
385
448
|
"name": "Reflected XSS Risk",
|
|
386
449
|
"severity": "medium",
|
|
450
|
+
"confidence": "medium",
|
|
387
451
|
"category": "security",
|
|
388
452
|
"description": "DangerouslySetInnerHTML or innerHTML with user-controlled content creates XSS vulnerabilities",
|
|
389
453
|
"patterns": [
|
|
@@ -393,7 +457,7 @@
|
|
|
393
457
|
{ "pattern": "\\.html\\s*\\(\\s*(?:user|req\\.|request\\.|params?\\.)", "flags": "gi" },
|
|
394
458
|
{ "pattern": "v-html\\s*=\\s*[\"']?(?!.*sanitize)", "flags": "gi" }
|
|
395
459
|
],
|
|
396
|
-
"fix_suggestion": "Use standard JSX rendering or DOMPurify before setting HTML content",
|
|
460
|
+
"fix_suggestion": "Use standard JSX rendering or DOMPurify before setting HTML content. Note: vendor/bundled libraries may trigger this rule — use .haloignore to suppress.",
|
|
397
461
|
"penalty": "Security failure",
|
|
398
462
|
"languages": ["typescript", "javascript", "tsx", "jsx", "vue"],
|
|
399
463
|
"packs": ["coppa"],
|
|
@@ -406,12 +470,13 @@
|
|
|
406
470
|
"id": "coppa-cookies-016",
|
|
407
471
|
"name": "Missing Cookie Notice",
|
|
408
472
|
"severity": "low",
|
|
473
|
+
"confidence": "medium",
|
|
409
474
|
"category": "cookies",
|
|
410
475
|
"description": "Cookies or localStorage storing tracking data or PII requires a consent banner",
|
|
411
476
|
"patterns": [
|
|
412
477
|
{ "pattern": "document\\.cookie\\s*=\\s*[^;]*(?:user|email|name|token|session|track|id|uid|analytics)", "flags": "gi" },
|
|
413
|
-
{ "pattern": "localStorage\\.setItem\\s*\\(\\s*['\"][^'\"]*(?:
|
|
414
|
-
{ "pattern": "sessionStorage\\.setItem\\s*\\(\\s*['\"][^'\"]*(?:
|
|
478
|
+
{ "pattern": "localStorage\\.setItem\\s*\\(\\s*['\"][^'\"]*(?:user_?id|user_?email|user_?token|auth_?token|session_?token|track_?id|tracking|login_?token|uid|analytics_?id|user_?data|user_?profile)[^'\"]*['\"]", "flags": "gi" },
|
|
479
|
+
{ "pattern": "sessionStorage\\.setItem\\s*\\(\\s*['\"][^'\"]*(?:user_?id|user_?email|user_?token|auth_?token|session_?token|track_?id|tracking|login_?token|uid|analytics_?id|user_?data|user_?profile)[^'\"]*['\"]", "flags": "gi" },
|
|
415
480
|
{ "pattern": "\\.set_cookie\\s*\\(\\s*['\"][^'\"]*(?:user|email|token|session|track|auth|login|uid|analytics)[^'\"]*['\"]", "flags": "gi" },
|
|
416
481
|
{ "pattern": "http\\.SetCookie\\s*\\(\\s*\\w+\\s*,\\s*&http\\.Cookie\\s*\\{", "flags": "gi" },
|
|
417
482
|
{ "pattern": "\\.addCookie\\s*\\(\\s*new\\s+Cookie\\s*\\(", "flags": "gi" },
|
|
@@ -431,11 +496,12 @@
|
|
|
431
496
|
"id": "coppa-ext-017",
|
|
432
497
|
"name": "Unwarned External Links",
|
|
433
498
|
"severity": "medium",
|
|
499
|
+
"confidence": "medium",
|
|
434
500
|
"category": "external",
|
|
435
501
|
"description": "External links in child-facing views should trigger a \"You are leaving...\" modal",
|
|
436
502
|
"patterns": [
|
|
437
503
|
{ "pattern": "<a[^>]+href=[\"']https?://(?!.*(?:privacy|terms|legal|tos|policy|consent|support|help|docs|documentation))[^\"']+[\"'][^>]*target=[\"']_blank[\"'][^>]*>", "flags": "gi" },
|
|
438
|
-
{ "pattern": "window\\.open\\s*\\(\\s*['\"]https?://(?!.*(?:privacy|terms|legal|tos|policy))", "flags": "gi" }
|
|
504
|
+
{ "pattern": "window\\.open\\s*\\(\\s*['\"]https?://(?!.*(?:privacy|terms|legal|tos|policy|support|help|docs|documentation|faq|about))", "flags": "gi" }
|
|
439
505
|
],
|
|
440
506
|
"fix_suggestion": "Wrap external links in SafeLink component with warning modal",
|
|
441
507
|
"penalty": "Warning",
|
|
@@ -450,6 +516,7 @@
|
|
|
450
516
|
"id": "coppa-analytics-018",
|
|
451
517
|
"name": "Mapping PII to Analytics User IDs",
|
|
452
518
|
"severity": "high",
|
|
519
|
+
"confidence": "medium",
|
|
453
520
|
"category": "analytics",
|
|
454
521
|
"description": "Passing email, name, or phone to analytics.identify() exposes PII to third parties",
|
|
455
522
|
"patterns": [
|
|
@@ -479,6 +546,7 @@
|
|
|
479
546
|
"id": "coppa-edu-019",
|
|
480
547
|
"name": "Missing Teacher/School Verification",
|
|
481
548
|
"severity": "medium",
|
|
549
|
+
"confidence": "low",
|
|
482
550
|
"category": "education",
|
|
483
551
|
"description": "Teacher accounts using generic email (@gmail.com) bypass \"School Official\" consent exception",
|
|
484
552
|
"patterns": [
|
|
@@ -500,14 +568,15 @@
|
|
|
500
568
|
"id": "coppa-default-020",
|
|
501
569
|
"name": "Default Public Profile Visibility",
|
|
502
570
|
"severity": "critical",
|
|
571
|
+
"confidence": "medium",
|
|
503
572
|
"category": "defaults",
|
|
504
573
|
"description": "Default profile visibility must be private. COPPA 2.0 requires privacy by design.",
|
|
505
574
|
"patterns": [
|
|
506
|
-
{ "pattern": "isProfileVisible:\\s*true", "flags": "gi" },
|
|
507
|
-
{ "pattern": "visibility:\\s*['\"]public['\"]", "flags": "gi" },
|
|
508
|
-
{ "pattern": "defaultPrivacy:\\s*['\"]public['\"]", "flags": "gi" },
|
|
509
|
-
{ "pattern": "isPublic:\\s*true[^}]*(profile|User)", "flags": "gi" },
|
|
510
|
-
{ "pattern": "profileVisibility\\s*=\\s*['\"]?(?:public|Public)['\"]?", "flags": "gi" }
|
|
575
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})isProfileVisible:\\s*true", "flags": "gi" },
|
|
576
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})(?:profile|user|account|member)[^\\n]{0,30}visibility:\\s*['\"]public['\"]", "flags": "gi" },
|
|
577
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})defaultPrivacy:\\s*['\"]public['\"]", "flags": "gi" },
|
|
578
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})isPublic:\\s*true[^}]*(profile|User)", "flags": "gi" },
|
|
579
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})profileVisibility\\s*=\\s*['\"]?(?:public|Public)['\"]?", "flags": "gi" }
|
|
511
580
|
],
|
|
512
581
|
"fix_suggestion": "Change default visibility to \"private\" or false",
|
|
513
582
|
"penalty": "$51,744 per violation",
|
|
@@ -522,17 +591,18 @@
|
|
|
522
591
|
"id": "ETHICAL-001",
|
|
523
592
|
"name": "Infinite Scroll / Endless Feed",
|
|
524
593
|
"severity": "high",
|
|
594
|
+
"confidence": "medium",
|
|
525
595
|
"category": "ethical-design",
|
|
526
596
|
"description": "Infinite scroll exploits lack of impulse control. Children spend 2-3x longer on infinite feeds.",
|
|
527
597
|
"patterns": [
|
|
528
|
-
{ "pattern": "IntersectionObserver
|
|
529
|
-
{ "pattern": "window\\.addEventListener
|
|
530
|
-
{ "pattern": "import
|
|
531
|
-
{ "pattern": "<InfiniteScroll", "flags": "gi" },
|
|
598
|
+
{ "pattern": "IntersectionObserver[^\\n]*isIntersecting[^\\n]*(?:loadMore|fetchMore|nextPage)", "flags": "gi" },
|
|
599
|
+
{ "pattern": "window\\.addEventListener[^\\n]*['\"]scroll['\"][^\\n]*(?:fetchNext|loadNext|loadMore)", "flags": "gi" },
|
|
600
|
+
{ "pattern": "import[^\\n]*(?:InfiniteScroll|InfiniteLoader|InfiniteList)(?![^\\n]*(?:admin|Admin|table|Table|data))", "flags": "gi" },
|
|
601
|
+
{ "pattern": "<(?:InfiniteScroll|InfiniteLoader)(?![^>]*(?:admin|table|data-table))", "flags": "gi" },
|
|
532
602
|
{ "pattern": "ngx-infinite-scroll", "flags": "gi" },
|
|
533
603
|
{ "pattern": "vue-infinite-loading", "flags": "gi" }
|
|
534
604
|
],
|
|
535
|
-
"fix_suggestion": "Replace infinite scroll with pagination or \"Load More\" buttons to create natural stopping points",
|
|
605
|
+
"fix_suggestion": "Replace infinite scroll with pagination or \"Load More\" buttons to create natural stopping points. Suppress with .haloignore for admin/internal dashboards.",
|
|
536
606
|
"penalty": "Ethical Design Violation",
|
|
537
607
|
"languages": ["typescript", "javascript", "tsx", "jsx", "vue"],
|
|
538
608
|
"packs": ["ethical"],
|
|
@@ -545,6 +615,7 @@
|
|
|
545
615
|
"id": "ETHICAL-002",
|
|
546
616
|
"name": "Streak Pressure Mechanics",
|
|
547
617
|
"severity": "high",
|
|
618
|
+
"confidence": "medium",
|
|
548
619
|
"category": "ethical-design",
|
|
549
620
|
"description": "Streak mechanics use loss aversion to manufacture daily compulsive usage",
|
|
550
621
|
"patterns": [
|
|
@@ -568,6 +639,7 @@
|
|
|
568
639
|
"id": "ETHICAL-003",
|
|
569
640
|
"name": "Variable Ratio Rewards (Loot Boxes)",
|
|
570
641
|
"severity": "critical",
|
|
642
|
+
"confidence": "medium",
|
|
571
643
|
"category": "ethical-design",
|
|
572
644
|
"description": "Randomized rewards (loot boxes, gacha) exploit gambling psychology in developing brains",
|
|
573
645
|
"patterns": [
|
|
@@ -592,13 +664,14 @@
|
|
|
592
664
|
"id": "ETHICAL-004",
|
|
593
665
|
"name": "Manipulative Notification Language",
|
|
594
666
|
"severity": "medium",
|
|
667
|
+
"confidence": "medium",
|
|
595
668
|
"category": "ethical-design",
|
|
596
|
-
"description": "
|
|
669
|
+
"description": "User-facing strings using urgency language (\"Hurry!\", \"Missing out\") manipulate children's fear of social exclusion. Only flags text inside string literals or JSX content.",
|
|
597
670
|
"patterns": [
|
|
598
|
-
{ "pattern": "hurry|limited\\s*time|missing\\s*out|don'?t\\s*miss|left\\s*behind", "flags": "gi" },
|
|
599
|
-
{ "pattern": "everyone\\s*else\\s*is", "flags": "gi" },
|
|
600
|
-
{ "pattern": "last\\s*chance", "flags": "gi" },
|
|
601
|
-
{ "pattern": "running\\s*out", "flags": "gi" }
|
|
671
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?(?:hurry|limited\\s*time|missing\\s*out|don'?t\\s*miss|left\\s*behind)", "flags": "gi" },
|
|
672
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?everyone\\s*else\\s*is", "flags": "gi" },
|
|
673
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?last\\s*chance", "flags": "gi" },
|
|
674
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?running\\s*out(?!\\s*of\\s*(?:memory|disk|space|storage|connections|retries|attempts|time))", "flags": "gi" }
|
|
602
675
|
],
|
|
603
676
|
"fix_suggestion": "Use neutral, informational language. Avoid FOMO (Fear Of Missing Out) triggers.",
|
|
604
677
|
"penalty": "Ethical Design Violation",
|
|
@@ -613,17 +686,18 @@
|
|
|
613
686
|
"id": "ETHICAL-005",
|
|
614
687
|
"name": "Artificial Scarcity / Countdowns",
|
|
615
688
|
"severity": "medium",
|
|
689
|
+
"confidence": "medium",
|
|
616
690
|
"category": "ethical-design",
|
|
617
691
|
"description": "Fake scarcity (\"Only 2 left!\") and countdown timers pressure children into impulsive decisions",
|
|
618
692
|
"patterns": [
|
|
619
|
-
{ "pattern": "CountdownTimer", "flags": "gi" },
|
|
620
|
-
{ "pattern": "only\\s*\\d+\\s*left", "flags": "gi" },
|
|
621
|
-
{ "pattern": "offer\\s*ends\\s*in", "flags": "gi" },
|
|
622
|
-
{ "pattern": "selling\\s*fast", "flags": "gi" },
|
|
623
|
-
{ "pattern": "almost\\s*sold\\s*out", "flags": "gi" },
|
|
624
|
-
{ "pattern": "limited\\s*availability", "flags": "gi" }
|
|
693
|
+
{ "pattern": "(?:sale|offer|deal|promo|discount|purchase|buy|shop|cart|checkout)[^\\n]*CountdownTimer|CountdownTimer[^\\n]*(?:sale|offer|deal|promo|discount|purchase|buy|shop|cart|checkout)", "flags": "gi" },
|
|
694
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?only\\s*\\d+\\s*left", "flags": "gi" },
|
|
695
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?offer\\s*ends\\s*in", "flags": "gi" },
|
|
696
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?selling\\s*fast", "flags": "gi" },
|
|
697
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?almost\\s*sold\\s*out", "flags": "gi" },
|
|
698
|
+
{ "pattern": "(?:[\"'`>])\\s*[^\"'`<\\n]*?limited\\s*availability", "flags": "gi" }
|
|
625
699
|
],
|
|
626
|
-
"fix_suggestion": "Remove artificial urgency. If an offer expires, state the date calmly without countdown pressure.",
|
|
700
|
+
"fix_suggestion": "Remove artificial urgency. If an offer expires, state the date calmly without countdown pressure. Suppress with .haloignore for non-commerce timers (quizzes, sessions, deploys).",
|
|
627
701
|
"penalty": "Ethical Design Violation",
|
|
628
702
|
"languages": ["typescript", "javascript", "tsx", "jsx", "html"],
|
|
629
703
|
"packs": ["ethical"],
|
|
@@ -636,6 +710,7 @@
|
|
|
636
710
|
"id": "AI-AUDIT-001",
|
|
637
711
|
"name": "Placeholder Analytics Script",
|
|
638
712
|
"severity": "high",
|
|
713
|
+
"confidence": "high",
|
|
639
714
|
"category": "ai-audit",
|
|
640
715
|
"description": "AI-generated code frequently includes placeholder analytics (UA-XXXXX, G-XXXXXX, fbq) copied from training data. These may activate real tracking without child_directed_treatment flags.",
|
|
641
716
|
"patterns": [
|
|
@@ -658,6 +733,7 @@
|
|
|
658
733
|
"id": "AI-AUDIT-002",
|
|
659
734
|
"name": "AI-Generated Hardcoded Secrets",
|
|
660
735
|
"severity": "critical",
|
|
736
|
+
"confidence": "medium",
|
|
661
737
|
"category": "ai-audit",
|
|
662
738
|
"description": "AI coding assistants frequently generate placeholder API keys, tokens, and secrets inline. These may be committed to version control and exposed.",
|
|
663
739
|
"patterns": [
|
|
@@ -665,7 +741,7 @@
|
|
|
665
741
|
{ "pattern": "(?:secret|SECRET|token|TOKEN)\\s*[:=]\\s*['\"](?!process\\.env)[a-zA-Z0-9_-]{20,}['\"]", "flags": "gi" },
|
|
666
742
|
{ "pattern": "SUPABASE_(?:ANON_KEY|SERVICE_ROLE_KEY)\\s*[:=]\\s*['\"]ey[a-zA-Z0-9_.+-]{30,}['\"]", "flags": "gi" },
|
|
667
743
|
{ "pattern": "FIREBASE_(?:API_KEY|CONFIG)\\s*[:=]\\s*['\"]AI[a-zA-Z0-9_-]{30,}['\"]", "flags": "gi" },
|
|
668
|
-
{ "pattern": "(?:password|passwd|pwd)\\s*[:=]\\s*['\"](?!process\\.env)[^'\"]{8,}['\"]\\s*(?:,|;|\\})", "flags": "gi" }
|
|
744
|
+
{ "pattern": "(?:password|passwd|pwd)\\s*[:=]\\s*['\"](?!process\\.env|test|Test|mock|Mock|example|Example|dummy|Dummy|fake|Fake|fixture)[^'\"]{8,}['\"]\\s*(?:,|;|\\})", "flags": "gi" }
|
|
669
745
|
],
|
|
670
746
|
"fix_suggestion": "Move all secrets to environment variables. Use process.env.API_KEY or a secrets manager. Never hardcode credentials.",
|
|
671
747
|
"penalty": "Security exposure — credentials in source code",
|
|
@@ -680,6 +756,7 @@
|
|
|
680
756
|
"id": "AI-AUDIT-003",
|
|
681
757
|
"name": "Hallucinated/Placeholder API URLs",
|
|
682
758
|
"severity": "medium",
|
|
759
|
+
"confidence": "high",
|
|
683
760
|
"category": "ai-audit",
|
|
684
761
|
"description": "AI models often generate fake API endpoints (api.example.com, jsonplaceholder, reqres.in) that may be replaced with real endpoints without proper review.",
|
|
685
762
|
"patterns": [
|
|
@@ -700,6 +777,7 @@
|
|
|
700
777
|
"id": "AI-AUDIT-004",
|
|
701
778
|
"name": "Copy-Paste Tracking Boilerplate",
|
|
702
779
|
"severity": "high",
|
|
780
|
+
"confidence": "medium",
|
|
703
781
|
"category": "ai-audit",
|
|
704
782
|
"description": "AI assistants reproduce common analytics setup patterns from training data. These often include user identification, event tracking, and session recording without consent flows.",
|
|
705
783
|
"patterns": [
|
|
@@ -726,6 +804,7 @@
|
|
|
726
804
|
"id": "AI-AUDIT-005",
|
|
727
805
|
"name": "AI-Generated Insecure Defaults",
|
|
728
806
|
"severity": "medium",
|
|
807
|
+
"confidence": "high",
|
|
729
808
|
"category": "ai-audit",
|
|
730
809
|
"description": "AI models commonly generate code with insecure default configurations: CORS *, disabled SSL verification, permissive CSP, or open CORS origins.",
|
|
731
810
|
"patterns": [
|
|
@@ -749,6 +828,7 @@
|
|
|
749
828
|
"id": "AI-AUDIT-006",
|
|
750
829
|
"name": "Unresolved Compliance TODOs",
|
|
751
830
|
"severity": "low",
|
|
831
|
+
"confidence": "high",
|
|
752
832
|
"category": "ai-audit",
|
|
753
833
|
"description": "AI-generated code often includes TODO/FIXME comments for compliance-related features (consent, age verification, privacy policy) that may ship unimplemented.",
|
|
754
834
|
"patterns": [
|
|
@@ -769,14 +849,15 @@
|
|
|
769
849
|
"id": "AU-SBD-001",
|
|
770
850
|
"name": "Default Public Profile Visibility",
|
|
771
851
|
"severity": "high",
|
|
852
|
+
"confidence": "low",
|
|
772
853
|
"category": "safety-by-design",
|
|
773
854
|
"description": "User profiles default to public or visible. AU Safety by Design requires privacy-by-default for minors — profiles should be private until explicitly changed by the user or a verified parent.",
|
|
774
855
|
"patterns": [
|
|
775
|
-
{ "pattern": "(?:visibility|profile_?visibility|is_?public|isPublic)\\s*[:=]\\s*(?:['\"]public['\"]|true)", "flags": "gi" },
|
|
776
|
-
{ "pattern": "default(?:_?visibility|_?privacy|_?profile)\\s*[:=]\\s*['\"](?:public|open|visible|everyone)['\"]", "flags": "gi" },
|
|
777
|
-
{ "pattern": "(?:privacy|profilePrivacy)\\s*[:=]\\s*\\{[^}]*default\\s*:\\s*['\"](?:public|open|everyone)['\"]", "flags": "gi" },
|
|
778
|
-
{ "pattern": "(?:showProfile|profileVisible|publicByDefault|show_profile)\\s*[:=]\\s*true", "flags": "gi" },
|
|
779
|
-
{ "pattern": "(?:searchable|discoverable|findable)\\s*[:=]\\s*true\\b", "flags": "gi" }
|
|
856
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})(?:visibility|profile_?visibility|is_?public|isPublic)\\s*[:=]\\s*(?:['\"]public['\"]|true)", "flags": "gi" },
|
|
857
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})default(?:_?visibility|_?privacy|_?profile)\\s*[:=]\\s*['\"](?:public|open|visible|everyone)['\"]", "flags": "gi" },
|
|
858
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})(?:privacy|profilePrivacy)\\s*[:=]\\s*\\{[^}]*default\\s*:\\s*['\"](?:public|open|everyone)['\"]", "flags": "gi" },
|
|
859
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})(?:showProfile|profileVisible|publicByDefault|show_profile)\\s*[:=]\\s*true", "flags": "gi" },
|
|
860
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|admin|Admin|dashboard|internal|//|\\*)\\s{0,20})(?:user|profile|account|member)[^\\n]{0,50}(?:searchable|discoverable|findable)\\s*[:=]\\s*true\\b", "flags": "gi" }
|
|
780
861
|
],
|
|
781
862
|
"fix_suggestion": "Set profile visibility to \"private\" by default. Require explicit user action (or parental consent for children) to make profiles public. AU SbD Principle 1: safety as a fundamental design consideration.",
|
|
782
863
|
"penalty": "Default public exposure of minor profiles",
|
|
@@ -791,11 +872,12 @@
|
|
|
791
872
|
"id": "AU-SBD-002",
|
|
792
873
|
"name": "Social Features Without Report/Block",
|
|
793
874
|
"severity": "medium",
|
|
875
|
+
"confidence": "medium",
|
|
794
876
|
"category": "safety-by-design",
|
|
795
|
-
"description": "Social interaction features (comments, posts, messaging) detected without corresponding report or block mechanisms. AU SbD Principle 2 requires users to have tools to protect themselves from harmful interactions.",
|
|
877
|
+
"description": "Social interaction features (comments, posts, messaging) detected without corresponding report or block mechanisms. AU SbD Principle 2 requires users to have tools to protect themselves from harmful interactions. Excludes window.postMessage (IPC) and admin/internal contexts.",
|
|
796
878
|
"patterns": [
|
|
797
879
|
{ "pattern": "(?:addComment|postComment|submitComment|createComment|commentCreate)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
798
|
-
{ "pattern": "(?:sendMessage|createMessage|
|
|
880
|
+
{ "pattern": "(?<!window\\.)(?:sendMessage|createMessage|submitMessage|messageCreate)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
799
881
|
{ "pattern": "(?:createPost|submitPost|publishPost|addPost|postCreate)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
800
882
|
{ "pattern": "(?:addReview|submitReview|createReview|postReview|reviewCreate)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
801
883
|
{ "pattern": "(?:shareContent|createShare|submitShare)\\s*(?:=|:|\\()", "flags": "gi" }
|
|
@@ -813,11 +895,12 @@
|
|
|
813
895
|
"id": "AU-SBD-003",
|
|
814
896
|
"name": "Unrestricted Direct Messaging for Minors",
|
|
815
897
|
"severity": "critical",
|
|
898
|
+
"confidence": "medium",
|
|
816
899
|
"category": "safety-by-design",
|
|
817
900
|
"description": "Direct messaging or chat functionality without safety controls (contact restrictions, message filtering, or parental oversight). The AU Online Safety Act requires platforms to take reasonable steps to prevent child exploitation in private communications.",
|
|
818
901
|
"patterns": [
|
|
819
902
|
{ "pattern": "(?:directMessage|sendDM|privateMess|createDM|dmChannel|startChat|privateChat|initiateChat)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
820
|
-
{ "pattern": "(?:WebSocket|io\\.connect|socket\\.emit)\\s*\\([^)]*(?:chat|message|dm|private)", "flags": "gi" },
|
|
903
|
+
{ "pattern": "(?:WebSocket|io\\.connect|socket\\.emit)\\s*\\([^)]*(?:chat|message|dm|private)(?![^\\n]*(?:admin|support|internal|helpdesk|customer_?service))", "flags": "gi" },
|
|
821
904
|
{ "pattern": "(?:allowDMs?|enableDMs?|allow_?direct_?message|enable_?private_?message)\\s*[:=]\\s*true", "flags": "gi" },
|
|
822
905
|
{ "pattern": "(?:contactStranger|messageAnyone|openChat|unrestricted_?message)\\s*[:=]\\s*true", "flags": "gi" }
|
|
823
906
|
],
|
|
@@ -834,12 +917,13 @@
|
|
|
834
917
|
"id": "AU-SBD-004",
|
|
835
918
|
"name": "Recommendation Algorithm Without Safety Guardrails",
|
|
836
919
|
"severity": "high",
|
|
920
|
+
"confidence": "medium",
|
|
837
921
|
"category": "safety-by-design",
|
|
838
922
|
"description": "Content recommendation or feed algorithms detected without safety filtering, content classification, or age-appropriate guardrails. AU SbD requires platforms to assess and mitigate algorithmic harms, particularly for young users.",
|
|
839
923
|
"patterns": [
|
|
840
|
-
{ "pattern": "(?:
|
|
924
|
+
{ "pattern": "(?:personalizedFeed|forYouFeed|contentFeed)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
841
925
|
{ "pattern": "(?:algorithm|algo)(?:_?feed|_?rank|_?recommend|_?suggest)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
842
|
-
{ "pattern": "(?:trending|viral|popular)(?:_?content|_?posts|_?feed|_?items)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
926
|
+
{ "pattern": "(?:trending|viral|popular)(?:_?content|_?posts|_?feed|_?items)\\s*(?:=|:|\\()(?![^\\n]*(?:curated|editorial|manual|handpick|staff_?pick))", "flags": "gi" },
|
|
843
927
|
{ "pattern": "(?:engagement_?score|clickBait|engagement_?rank|watch_?next|autoplay_?next)\\s*[:=]", "flags": "gi" },
|
|
844
928
|
{ "pattern": "(?:rabbit_?hole|endless_?feed|infinite_?recommend|auto_?suggest)\\s*[:=]\\s*true", "flags": "gi" }
|
|
845
929
|
],
|
|
@@ -856,12 +940,13 @@
|
|
|
856
940
|
"id": "AU-SBD-005",
|
|
857
941
|
"name": "Engagement Features Without Time Awareness",
|
|
858
942
|
"severity": "medium",
|
|
943
|
+
"confidence": "medium",
|
|
859
944
|
"category": "safety-by-design",
|
|
860
945
|
"description": "High-engagement features (autoplay, continuous scrolling, notifications) detected without corresponding digital wellbeing controls (screen time limits, break reminders, usage dashboards). AU SbD encourages platforms to build in digital wellbeing tools.",
|
|
861
946
|
"patterns": [
|
|
862
|
-
{ "pattern": "(?:
|
|
863
|
-
{ "pattern": "(?:autoPlay|autoPlayNext|playNext|nextEpisode)\\s*[:=]\\s*true", "flags": "gi" },
|
|
947
|
+
{ "pattern": "(?:autoPlayNext|playNext|nextEpisode|autoplay_?next)\\s*[:=]\\s*true", "flags": "gi" },
|
|
864
948
|
{ "pattern": "(?:continuous_?play|binge_?mode|marathon_?mode|watch_?party)\\s*[:=]\\s*true", "flags": "gi" },
|
|
949
|
+
{ "pattern": "(?:autoplay|auto_?play)\\s*[:=]\\s*true(?=[^\\n]*(?:feed|playlist|series|queue|channel|episode|next))", "flags": "gi" },
|
|
865
950
|
{ "pattern": "(?:push_?notification|sendNotification|scheduleNotif|notif_?trigger).*(?:re_?engage|comeback|miss_?you|inactive)", "flags": "gi" },
|
|
866
951
|
{ "pattern": "(?:daily_?reward|login_?bonus|daily_?streak|come_?back_?reward)\\s*(?:=|:|\\()", "flags": "gi" }
|
|
867
952
|
],
|
|
@@ -878,6 +963,7 @@
|
|
|
878
963
|
"id": "AU-SBD-006",
|
|
879
964
|
"name": "Location Data Without Explicit Consent",
|
|
880
965
|
"severity": "critical",
|
|
966
|
+
"confidence": "low",
|
|
881
967
|
"category": "safety-by-design",
|
|
882
968
|
"description": "Location data collection or sharing enabled without explicit, informed opt-in. AU SbD and the Privacy Act 1988 require data minimization, especially for children's geolocation data — location should never be collected by default.",
|
|
883
969
|
"patterns": [
|
|
@@ -900,13 +986,14 @@
|
|
|
900
986
|
"id": "ut-sb142-001",
|
|
901
987
|
"name": "Minor Account Creation Without Age Assurance",
|
|
902
988
|
"severity": "critical",
|
|
989
|
+
"confidence": "medium",
|
|
903
990
|
"category": "age-verification",
|
|
904
|
-
"description": "Utah SB 142 requires an age assurance system with at least 95% accuracy to identify minor account holders (under 18). Account creation flows that lack age verification gates violate this requirement.",
|
|
991
|
+
"description": "Utah SB 142 requires an age assurance system with at least 95% accuracy to identify minor account holders (under 18). Account creation flows that lack age verification gates violate this requirement. Excludes test factories and seed scripts.",
|
|
905
992
|
"patterns": [
|
|
906
993
|
{ "pattern": "(?:createUser|signUp|register)\\s*\\((?![^)]*(?:age|dateOfBirth|dob|birthDate|birth_date))[^)]*\\)", "flags": "gi" },
|
|
907
994
|
{ "pattern": "(?:create_user|sign_up|create_account)\\s*\\((?![^)]*(?:age|date_of_birth|dob|birth_date))[^)]*\\)", "flags": "gi" },
|
|
908
|
-
{ "pattern": "(?:
|
|
909
|
-
{ "pattern": "INSERT\\s+INTO\\s+(?:users|accounts)\\s*\\([^)]*\\)\\s*VALUES", "flags": "gi" }
|
|
995
|
+
{ "pattern": "(?:RegistrationService)\\.(?:create|register)\\s*\\((?![^)]*(?:age|dob|birth))", "flags": "gi" },
|
|
996
|
+
{ "pattern": "INSERT\\s+INTO\\s+(?:users|accounts)\\s*\\((?![^)]*(?:age|dob|birth_date|date_of_birth))[^)]*\\)\\s*VALUES", "flags": "gi" }
|
|
910
997
|
],
|
|
911
998
|
"fix_suggestion": "Add an age assurance step (date-of-birth collection, age estimation, or ID verification) before account creation. If the user is under 18, flag the account as a minor account and require parental consent before activation. See Utah SB 142 §13-72-201.",
|
|
912
999
|
"penalty": "Up to $2,500 per violation; private right of action for parents",
|
|
@@ -921,13 +1008,14 @@
|
|
|
921
1008
|
"id": "ut-sb142-002",
|
|
922
1009
|
"name": "Missing Parental Consent for Minor Account",
|
|
923
1010
|
"severity": "critical",
|
|
1011
|
+
"confidence": "low",
|
|
924
1012
|
"category": "parental-consent",
|
|
925
1013
|
"description": "Utah SB 142 requires verifiable parental consent before a minor (under 18) can use a social media platform or download apps. Code that activates minor accounts without a parental consent verification step violates this requirement.",
|
|
926
1014
|
"patterns": [
|
|
927
|
-
{ "pattern": "(?:activateAccount|enableAccount|verifyEmail|confirmRegistration)\\s*\\((?![^)]*(?:parent|guardian|consent|parental))[^)]*\\)", "flags": "gi" },
|
|
928
|
-
{ "pattern": "(?:activate_account|enable_account|verify_email|confirm_registration)\\s*\\((?![^)]*(?:parent|guardian|consent|parental))[^)]*\\)", "flags": "gi" },
|
|
929
|
-
{ "pattern": "(?:isMinor|is_minor|isUnder18|is_under_18)\\s*(?:&&|\\|\\||and|or)\\s*(?!.*(?:parentConsent|parent_consent|guardianApproval|guardian_approval))", "flags": "gi" },
|
|
930
|
-
{ "pattern": "(?:minor|child|teen)(?:Account|_account|Profile|_profile)\\s*[:=]\\s*(?:true|1|'active'|\"active\")", "flags": "gi" }
|
|
1015
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|test|Test|expect|assert|//|\\*)\\s{0,20})(?:activateAccount|enableAccount|verifyEmail|confirmRegistration)\\s*\\((?![^)]*(?:parent|guardian|consent|parental))[^)]*\\)", "flags": "gi" },
|
|
1016
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|test|Test|expect|assert|//|\\*)\\s{0,20})(?:activate_account|enable_account|verify_email|confirm_registration)\\s*\\((?![^)]*(?:parent|guardian|consent|parental))[^)]*\\)", "flags": "gi" },
|
|
1017
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|test|Test|expect|assert|//|\\*)\\s{0,20})(?:activate|enable|register)[^\\n]{0,40}(?:isMinor|is_minor|isUnder18|is_under_18)\\s*(?:&&|\\|\\||and|or)\\s*(?!.*(?:parentConsent|parent_consent|guardianApproval|guardian_approval))", "flags": "gi" },
|
|
1018
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})(?:minor|child|teen)(?:Account|_account|Profile|_profile)\\s*[:=]\\s*(?:true|1|'active'|\"active\")", "flags": "gi" }
|
|
931
1019
|
],
|
|
932
1020
|
"fix_suggestion": "Before activating any minor account, implement a verifiable parental consent flow: send a verification email/SMS to a parent-linked account, require parental ID verification, or integrate with a COPPA-safe consent provider. See Utah SB 142 §13-72-202.",
|
|
933
1021
|
"penalty": "Up to $2,500 per violation; private right of action for parents",
|
|
@@ -942,6 +1030,7 @@
|
|
|
942
1030
|
"id": "ut-sb142-003",
|
|
943
1031
|
"name": "Default DM Access Open for Minors",
|
|
944
1032
|
"severity": "high",
|
|
1033
|
+
"confidence": "medium",
|
|
945
1034
|
"category": "messaging-safety",
|
|
946
1035
|
"description": "Utah SB 142 requires that direct messaging for minor accounts be restricted to connected accounts only by default. Code that enables open or unrestricted DM access for all users (including minors) violates this requirement.",
|
|
947
1036
|
"patterns": [
|
|
@@ -963,10 +1052,11 @@
|
|
|
963
1052
|
"id": "ut-sb142-004",
|
|
964
1053
|
"name": "Missing Parental Supervisory Tools",
|
|
965
1054
|
"severity": "high",
|
|
1055
|
+
"confidence": "medium",
|
|
966
1056
|
"category": "parental-controls",
|
|
967
1057
|
"description": "Utah SB 142 requires platforms to offer parents supervisory tools: time limits, mandatory break scheduling, usage data viewing, connected account lists, and setting-change notifications. Applications that provide user accounts for minors without implementing or referencing a parental dashboard violate this requirement.",
|
|
968
1058
|
"patterns": [
|
|
969
|
-
{ "pattern": "(?:
|
|
1059
|
+
{ "pattern": "(?:minor|child|student|teen|kid|youth)\\w*(?:Settings|Config|Account|Profile|Preferences)\\s*[:=]\\s*\\{(?![^}]*(?:parent|guardian|supervisory|parental|family))[^}]*\\}", "flags": "gi" },
|
|
970
1060
|
{ "pattern": "(?:screenTime|screen_time|timeLimit|time_limit|usageLimit|usage_limit)\\s*[:=]\\s*(?:null|undefined|false|0|'disabled'|\"disabled\")", "flags": "gi" },
|
|
971
1061
|
{ "pattern": "(?:parentalControls|parental_controls|familySettings|family_settings)\\s*[:=]\\s*(?:false|null|undefined|'disabled'|\"disabled\")", "flags": "gi" }
|
|
972
1062
|
],
|
|
@@ -983,14 +1073,15 @@
|
|
|
983
1073
|
"id": "ut-sb142-005",
|
|
984
1074
|
"name": "Minor Profile Visible to Search Engines",
|
|
985
1075
|
"severity": "medium",
|
|
1076
|
+
"confidence": "medium",
|
|
986
1077
|
"category": "privacy-defaults",
|
|
987
1078
|
"description": "Utah SB 142 requires that minor accounts have search engine indexing disabled by default and account visibility restricted to connected users only. Code that allows public profile indexing or unrestricted profile visibility for all users violates this requirement.",
|
|
988
1079
|
"patterns": [
|
|
989
|
-
{ "pattern": "(?:indexable|
|
|
990
|
-
{ "pattern": "<meta\\s+name=['\"]robots['\"]\\s+content=['\"](?:index|all
|
|
991
|
-
{ "pattern": "(?:profileVisibility|profile_visibility|accountVisibility|account_visibility)\\s*[:=]\\s*(?:'public'|\"public\"|'everyone'|\"everyone\"|'all'|\"all\")", "flags": "gi" },
|
|
992
|
-
{ "pattern": "(?:isPublicProfile|is_public_profile|publicProfile|public_profile)\\s*[:=]\\s*(?:true|1)", "flags": "gi" },
|
|
993
|
-
{ "pattern": "X-Robots-Tag\\s*[:=]\\s*(?:'index'|\"index\"|'all'|\"all\")", "flags": "gi" }
|
|
1080
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|admin|Admin|internal|//|\\*)\\s{0,20})(?:user|profile|account|member)[^\\n]{0,50}(?:indexable|seo_?visible|allow_?indexing|search_?engine_?visible)\\s*[:=]\\s*(?:true|1|'yes'|\"yes\")", "flags": "gi" },
|
|
1081
|
+
{ "pattern": "(?:user|profile|account|member|minor|child|student)[^\\n]{0,30}<meta\\s+name=['\"]robots['\"]\\s+content=['\"](?:index|all)['\"]", "flags": "gi" },
|
|
1082
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})(?:profileVisibility|profile_visibility|accountVisibility|account_visibility)\\s*[:=]\\s*(?:'public'|\"public\"|'everyone'|\"everyone\"|'all'|\"all\")", "flags": "gi" },
|
|
1083
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|expect|assert|//|\\*)\\s{0,20})(?:isPublicProfile|is_public_profile|publicProfile|public_profile)\\s*[:=]\\s*(?:true|1)", "flags": "gi" },
|
|
1084
|
+
{ "pattern": "(?<!(?:mock|Mock|fake|stub|fixture|seed|example|test|Test|//|\\*)\\s{0,20})X-Robots-Tag\\s*[:=]\\s*(?:'index'|\"index\"|'all'|\"all\")", "flags": "gi" }
|
|
994
1085
|
],
|
|
995
1086
|
"fix_suggestion": "Default minor accounts to non-indexable (noindex, nofollow) and restrict profile visibility to connected/approved users only. Add a robots meta tag or X-Robots-Tag header that blocks search engine crawling for minor profiles. See Utah SB 142 §13-72-301.",
|
|
996
1087
|
"penalty": "Up to $2,500 per violation; private right of action for parents",
|
|
@@ -1000,6 +1091,1542 @@
|
|
|
1000
1091
|
"transform_type": null,
|
|
1001
1092
|
"scaffold_id": null,
|
|
1002
1093
|
"guidance_url": null
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
"id": "coppa-2-021",
|
|
1097
|
+
"name": "Biometric Identifier Collection Without VPC",
|
|
1098
|
+
"severity": "critical",
|
|
1099
|
+
"confidence": "medium",
|
|
1100
|
+
"category": "bio",
|
|
1101
|
+
"description": "COPPA 2.0 expands 'personal information' to include biometric identifiers: fingerprints, voiceprints, facial geometry, gait patterns. Collection requires Verifiable Parental Consent (VPC) before any data capture.",
|
|
1102
|
+
"patterns": [
|
|
1103
|
+
{ "pattern": "(?:fingerprint|faceprint|voiceprint|gaitAnalysis|gait_analysis)\\s*[:=]", "flags": "gi" },
|
|
1104
|
+
{ "pattern": "(?:biometric|Biometric)(?:Data|Info|Template|Hash|Feature|Scan)\\s*[:=]", "flags": "gi" },
|
|
1105
|
+
{ "pattern": "(?:faceGeometry|face_geometry|facialGeometry|facial_geometry)\\s*[:=]", "flags": "gi" },
|
|
1106
|
+
{ "pattern": "(?:ARFaceAnchor|ARFaceGeometry)\\.(?:geometry|blendShapes)", "flags": "g" },
|
|
1107
|
+
{ "pattern": "(?:SpeakerRecognition|VoiceEnrollment|VoiceVerification)\\s*\\(", "flags": "g" },
|
|
1108
|
+
{ "pattern": "(?:palmPrint|palm_print|irisPattern|iris_pattern|retinaScan|retina_scan)\\s*[:=]", "flags": "gi" }
|
|
1109
|
+
],
|
|
1110
|
+
"fix_suggestion": "Obtain Verifiable Parental Consent (VPC) before collecting any biometric identifiers. Under COPPA 2.0, biometric data is 'personal information' requiring the highest consent standard. Keep biometric processing local-only where possible.",
|
|
1111
|
+
"penalty": "$51,744 per violation (FTC Final Rule effective April 22, 2026)",
|
|
1112
|
+
"languages": ["typescript", "javascript", "python", "go", "java", "kotlin", "swift"],
|
|
1113
|
+
"packs": ["coppa"],
|
|
1114
|
+
"fixability": "guided",
|
|
1115
|
+
"transform_type": null,
|
|
1116
|
+
"scaffold_id": null,
|
|
1117
|
+
"guidance_url": null
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
"id": "coppa-2-022",
|
|
1121
|
+
"name": "Push Notification Token Without Parental Opt-In",
|
|
1122
|
+
"severity": "high",
|
|
1123
|
+
"confidence": "medium",
|
|
1124
|
+
"category": "notif",
|
|
1125
|
+
"description": "COPPA 2.0 classifies device push notification tokens as 'online contact information'. Subscribing a child's device to push notifications requires prior parental consent and an opt-out mechanism.",
|
|
1126
|
+
"patterns": [
|
|
1127
|
+
{ "pattern": "(?:messaging|Messaging)\\.(?:getToken|requestPermission|subscribeToTopic)\\s*\\(", "flags": "g" },
|
|
1128
|
+
{ "pattern": "(?:registerForRemoteNotifications|requestAuthorization)\\s*\\(\\s*\\[?\\s*\\.(?:alert|badge|sound)", "flags": "g" },
|
|
1129
|
+
{ "pattern": "(?:PushNotificationIOS|PushNotification)\\.(?:requestPermissions|configure)\\s*\\(", "flags": "g" },
|
|
1130
|
+
{ "pattern": "(?:expo-notifications|@notifee|react-native-push-notification).*(?:requestPermissions|getToken)", "flags": "gi" },
|
|
1131
|
+
{ "pattern": "(?:saveDeviceToken|storeDeviceToken|registerDeviceToken|savePushToken|storePushToken)\\s*\\(", "flags": "gi" }
|
|
1132
|
+
],
|
|
1133
|
+
"fix_suggestion": "Gate push notification token registration behind a parental consent check. Under COPPA 2.0, push tokens are 'online contact information' — parents must explicitly opt in, and you must provide an opt-out mechanism accessible from a parental dashboard.",
|
|
1134
|
+
"penalty": "$51,744 per violation (FTC Final Rule effective April 22, 2026)",
|
|
1135
|
+
"languages": ["typescript", "javascript", "swift", "kotlin", "java"],
|
|
1136
|
+
"packs": ["coppa"],
|
|
1137
|
+
"fixability": "guided",
|
|
1138
|
+
"transform_type": null,
|
|
1139
|
+
"scaffold_id": null,
|
|
1140
|
+
"guidance_url": null
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
"id": "coppa-2-023",
|
|
1144
|
+
"name": "Ed-Tech Data Use Beyond Educational Purpose",
|
|
1145
|
+
"severity": "high",
|
|
1146
|
+
"confidence": "low",
|
|
1147
|
+
"category": "edu",
|
|
1148
|
+
"description": "COPPA 2.0 restricts ed-tech providers operating under the 'school official' exception: student data may only be used for the educational purpose authorized by the school. No advertising, profiling, or secondary data use.",
|
|
1149
|
+
"patterns": [
|
|
1150
|
+
{ "pattern": "(?:student|Student)(?:Data|Profile|Record|Info).*(?:marketing|advertising|adTargeting|ad_targeting|profiling|analytics\\.identify|recommend)", "flags": "gi" },
|
|
1151
|
+
{ "pattern": "(?:classroomData|classroom_data|schoolData|school_data).*(?:thirdParty|third_party|partner|advertis|market)", "flags": "gi" },
|
|
1152
|
+
{ "pattern": "(?:edtech|EdTech|LMS|lms).*(?:analytics\\.track|mixpanel|amplitude|segment\\.identify)", "flags": "gi" },
|
|
1153
|
+
{ "pattern": "(?:shareStudentData|share_student_data|exportStudentRecords|export_student_records)\\s*\\(", "flags": "gi" }
|
|
1154
|
+
],
|
|
1155
|
+
"fix_suggestion": "Ensure ed-tech data collected under the 'school official' exception is used exclusively for the authorized educational purpose. Remove any analytics, advertising, or profiling code paths that touch student data. COPPA 2.0 makes this an explicit prohibition.",
|
|
1156
|
+
"penalty": "$51,744 per violation (FTC Final Rule effective April 22, 2026)",
|
|
1157
|
+
"languages": ["typescript", "javascript", "python", "go", "java", "kotlin"],
|
|
1158
|
+
"packs": ["coppa"],
|
|
1159
|
+
"fixability": "guided",
|
|
1160
|
+
"transform_type": null,
|
|
1161
|
+
"scaffold_id": null,
|
|
1162
|
+
"guidance_url": null
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
"id": "coppa-2-024",
|
|
1166
|
+
"name": "Data Retention Beyond Reasonable Necessity",
|
|
1167
|
+
"severity": "medium",
|
|
1168
|
+
"confidence": "low",
|
|
1169
|
+
"category": "retention",
|
|
1170
|
+
"description": "COPPA 2.0 strengthens data retention requirements: operators must delete children's personal information when it is no longer reasonably necessary for the purpose for which it was collected. Indefinite retention or missing deletion mechanisms violate this requirement.",
|
|
1171
|
+
"patterns": [
|
|
1172
|
+
{ "pattern": "(?:retentionPolicy|retention_policy|dataRetention|data_retention)\\s*[:=]\\s*(?:'forever'|\"forever\"|'indefinite'|\"indefinite\"|'none'|\"none\"|null|undefined|-1|0)", "flags": "gi" },
|
|
1173
|
+
{ "pattern": "(?:deleteAfterDays|delete_after_days|ttlDays|ttl_days|expiresIn|expires_in)\\s*[:=]\\s*(?:null|undefined|0|-1|false)", "flags": "gi" },
|
|
1174
|
+
{ "pattern": "(?:neverDelete|never_delete|keepForever|keep_forever|permanentStorage|permanent_storage)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1175
|
+
{ "pattern": "(?:childData|child_data|minorData|minor_data|studentData|student_data).*(?:archive|Archive|longTermStorage|long_term_storage)", "flags": "gi" }
|
|
1176
|
+
],
|
|
1177
|
+
"fix_suggestion": "Implement automatic data deletion policies for children's personal information. Set reasonable TTLs based on the purpose of collection. Add a scheduled deletion job that purges expired child data. COPPA 2.0 requires deletion when data is no longer reasonably necessary.",
|
|
1178
|
+
"penalty": "$51,744 per violation (FTC Final Rule effective April 22, 2026)",
|
|
1179
|
+
"languages": ["typescript", "javascript", "python", "go", "java", "kotlin"],
|
|
1180
|
+
"packs": ["coppa"],
|
|
1181
|
+
"fixability": "guided",
|
|
1182
|
+
"transform_type": null,
|
|
1183
|
+
"scaffold_id": null,
|
|
1184
|
+
"guidance_url": null
|
|
1185
|
+
},
|
|
1186
|
+
{
|
|
1187
|
+
"id": "coppa-2-025",
|
|
1188
|
+
"name": "Consent Mechanism Not Meeting VPC Standard",
|
|
1189
|
+
"severity": "high",
|
|
1190
|
+
"confidence": "low",
|
|
1191
|
+
"category": "consent",
|
|
1192
|
+
"description": "COPPA 2.0 requires Verifiable Parental Consent (VPC) via methods that provide a greater level of assurance: signed consent forms, credit card transactions, video calls, government ID, or knowledge-based authentication. Simple email-based consent ('email plus') is only valid for internal use.",
|
|
1193
|
+
"patterns": [
|
|
1194
|
+
{ "pattern": "(?:parentConsent|parent_consent|parentalConsent|parental_consent)\\s*[:=]\\s*(?:true|1|'yes'|\"yes\")", "flags": "gi" },
|
|
1195
|
+
{ "pattern": "(?:consentMethod|consent_method|verificationMethod|verification_method)\\s*[:=]\\s*(?:'email'|\"email\"|'checkbox'|\"checkbox\"|'click'|\"click\")", "flags": "gi" },
|
|
1196
|
+
{ "pattern": "(?:parentEmail|parent_email).*(?:sendVerification|send_verification|sendConsent|send_consent)\\s*\\(", "flags": "gi" },
|
|
1197
|
+
{ "pattern": "<input[^>]*type=['\"]checkbox['\"][^>]*(?:consent|agree|parent)", "flags": "gi" }
|
|
1198
|
+
],
|
|
1199
|
+
"fix_suggestion": "Upgrade consent mechanism to meet COPPA 2.0 VPC standards. For external data sharing, use credit card verification, video calls, government ID, or knowledge-based authentication. Simple checkboxes and email confirmations do not meet the VPC standard for external use of children's data.",
|
|
1200
|
+
"penalty": "$51,744 per violation (FTC Final Rule effective April 22, 2026)",
|
|
1201
|
+
"languages": ["typescript", "javascript", "python", "go", "java", "kotlin", "swift"],
|
|
1202
|
+
"packs": ["coppa"],
|
|
1203
|
+
"fixability": "guided",
|
|
1204
|
+
"transform_type": null,
|
|
1205
|
+
"scaffold_id": null,
|
|
1206
|
+
"guidance_url": null
|
|
1207
|
+
},
|
|
1208
|
+
|
|
1209
|
+
{
|
|
1210
|
+
"id": "aadc-defaults-001",
|
|
1211
|
+
"name": "Default Privacy Set to Public",
|
|
1212
|
+
"severity": "critical",
|
|
1213
|
+
"confidence": "high",
|
|
1214
|
+
"category": "privacy",
|
|
1215
|
+
"description": "AADC Standard 7 requires settings to be 'high privacy' by default. Children's data should only be visible to others if the child actively changes the setting. Default-public profiles, content, or activity violate this standard.",
|
|
1216
|
+
"patterns": [
|
|
1217
|
+
{ "pattern": "(?:default|initial)(?:Privacy|Visibility|Setting)\\s*[:=]\\s*['\"]?(?:public|open|everyone|all)['\"]?", "flags": "gi" },
|
|
1218
|
+
{ "pattern": "shareByDefault\\s*[:=]\\s*true", "flags": "gi" },
|
|
1219
|
+
{ "pattern": "(?:discoverability|discoverable)\\s*[:=]\\s*['\"]?(?:public|everyone|all)['\"]?", "flags": "gi" },
|
|
1220
|
+
{ "pattern": "(?:searchable|allowStrangers|showOnlineStatus|showActivity)\\s*[:=]\\s*true", "flags": "gi" }
|
|
1221
|
+
],
|
|
1222
|
+
"fix_suggestion": "Set all privacy defaults to the most restrictive option. Profiles, activity, and content should be private by default. Users (especially children) should actively opt in to share data with others. See ICO AADC Standard 7.",
|
|
1223
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1224
|
+
"languages": ["typescript", "javascript", "python", "go", "java", "kotlin", "swift"],
|
|
1225
|
+
"packs": ["uk-aadc"],
|
|
1226
|
+
"fixability": "auto",
|
|
1227
|
+
"transform_type": null,
|
|
1228
|
+
"scaffold_id": null,
|
|
1229
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/7-default-settings/"
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
"id": "aadc-defaults-002",
|
|
1233
|
+
"name": "Opt-Out Tracking Enabled by Default",
|
|
1234
|
+
"severity": "high",
|
|
1235
|
+
"confidence": "high",
|
|
1236
|
+
"category": "tracking",
|
|
1237
|
+
"description": "AADC Standard 7 requires optional data uses to be individually selected and activated. Tracking, analytics, or personalization enabled by default with an opt-out mechanism violates this standard.",
|
|
1238
|
+
"patterns": [
|
|
1239
|
+
{ "pattern": "(?:tracking|analytics|personalization|marketing)(?:Enabled|Active|On)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1240
|
+
{ "pattern": "defaultConsent\\s*[:=]\\s*(?:true|['\"]granted['\"]|['\"]accepted['\"])", "flags": "gi" },
|
|
1241
|
+
{ "pattern": "optOut|opt_out|optedOut", "flags": "gi" }
|
|
1242
|
+
],
|
|
1243
|
+
"fix_suggestion": "Switch from opt-out to opt-in for all tracking, analytics, and personalization. These features must be off by default and require active user consent before activation. See ICO AADC Standard 7.",
|
|
1244
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1245
|
+
"languages": ["typescript", "javascript", "python", "go", "java", "kotlin", "swift", "html"],
|
|
1246
|
+
"packs": ["uk-aadc"],
|
|
1247
|
+
"fixability": "guided",
|
|
1248
|
+
"transform_type": null,
|
|
1249
|
+
"scaffold_id": null,
|
|
1250
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/7-default-settings/"
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
"id": "aadc-minimisation-003",
|
|
1254
|
+
"name": "Excessive Personal Data Collection",
|
|
1255
|
+
"severity": "high",
|
|
1256
|
+
"confidence": "medium",
|
|
1257
|
+
"category": "data-collection",
|
|
1258
|
+
"description": "AADC Standard 8 requires collecting only the minimum personal data needed to provide the service. Requiring fields like phone, address, school, gender, or ethnicity beyond what is necessary violates data minimisation.",
|
|
1259
|
+
"patterns": [
|
|
1260
|
+
{ "pattern": "(?:required|mandatory)\\s*[:=].*(?:phone|address|school|gender|ethnicity|religion)", "flags": "gi" },
|
|
1261
|
+
{ "pattern": "<input[^>]*required[^>]*(?:phone|address|middleName|employer|school)", "flags": "gi" },
|
|
1262
|
+
{ "pattern": "(?:collectAll|gatherAll|harvestData)", "flags": "gi" }
|
|
1263
|
+
],
|
|
1264
|
+
"fix_suggestion": "Review which personal data fields are truly required for your service. Make non-essential fields optional. Give children choices over which elements of data they wish to provide. See ICO AADC Standard 8.",
|
|
1265
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1266
|
+
"languages": ["typescript", "javascript", "python", "html", "php"],
|
|
1267
|
+
"packs": ["uk-aadc"],
|
|
1268
|
+
"fixability": "guided",
|
|
1269
|
+
"transform_type": null,
|
|
1270
|
+
"scaffold_id": null,
|
|
1271
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/8-data-minimisation/"
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
"id": "aadc-sharing-004",
|
|
1275
|
+
"name": "Third-Party Data Sharing Without Child Safety Check",
|
|
1276
|
+
"severity": "critical",
|
|
1277
|
+
"confidence": "medium",
|
|
1278
|
+
"category": "data-sharing",
|
|
1279
|
+
"description": "AADC Standard 9 prohibits disclosing children's data unless there is a compelling reason. Analytics and advertising SDKs that share data with third parties require child-safety checks before initialization.",
|
|
1280
|
+
"patterns": [
|
|
1281
|
+
{ "pattern": "(?:facebook|google|amplitude|mixpanel|segment)\\.(?:track|identify|log|init)", "flags": "gi" },
|
|
1282
|
+
{ "pattern": "(?:AdMob|MoPub|UnityAds|IronSource|AppLovin|InMobi)", "flags": "g" },
|
|
1283
|
+
{ "pattern": "(?:ad|advertising)SDK\\.init", "flags": "gi" },
|
|
1284
|
+
{ "pattern": "(?:databroker|dataBroker|sellData|dataMarketplace)", "flags": "gi" }
|
|
1285
|
+
],
|
|
1286
|
+
"fix_suggestion": "Before initializing third-party SDKs, check user age and disable data sharing for children. Use child-directed SDK configurations (e.g., tag_for_child_directed_treatment). Do not share children's data with data brokers or ad networks. See ICO AADC Standard 9.",
|
|
1287
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1288
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1289
|
+
"packs": ["uk-aadc"],
|
|
1290
|
+
"fixability": "guided",
|
|
1291
|
+
"transform_type": null,
|
|
1292
|
+
"scaffold_id": null,
|
|
1293
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/9-data-sharing/"
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
"id": "aadc-geolocation-005",
|
|
1297
|
+
"name": "Geolocation Enabled by Default",
|
|
1298
|
+
"severity": "critical",
|
|
1299
|
+
"confidence": "high",
|
|
1300
|
+
"category": "geolocation",
|
|
1301
|
+
"description": "AADC Standard 10 requires geolocation options to be switched off by default. Location tracking, sharing, and high-accuracy positioning must not be activated without explicit user action.",
|
|
1302
|
+
"patterns": [
|
|
1303
|
+
{ "pattern": "(?:geolocation|location(?:Tracking|Sharing|Service))(?:Enabled|Active|On|Default)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1304
|
+
{ "pattern": "(?:enableLocation|shareLocation|trackLocation)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1305
|
+
{ "pattern": "(?:enableHighAccuracy|highAccuracy)\\s*[:=]\\s*true", "flags": "gi" }
|
|
1306
|
+
],
|
|
1307
|
+
"fix_suggestion": "Set geolocation to off by default. Require explicit user action to enable location services. When location is active, provide a prominent visible indicator. Location sharing with others should reset to off at end of session. See ICO AADC Standard 10.",
|
|
1308
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1309
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1310
|
+
"packs": ["uk-aadc"],
|
|
1311
|
+
"fixability": "auto",
|
|
1312
|
+
"transform_type": null,
|
|
1313
|
+
"scaffold_id": null,
|
|
1314
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/10-geolocation/"
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
"id": "aadc-geolocation-006",
|
|
1318
|
+
"name": "Continuous Background Location Tracking",
|
|
1319
|
+
"severity": "high",
|
|
1320
|
+
"confidence": "high",
|
|
1321
|
+
"category": "geolocation",
|
|
1322
|
+
"description": "AADC Standard 10 requires using minimum granularity for geolocation. Continuous background location tracking or watch-based location monitoring collects excessive positional data from children.",
|
|
1323
|
+
"patterns": [
|
|
1324
|
+
{ "pattern": "(?:backgroundLocation|Background.*Location.*Mode|backgroundLocationUpdate)", "flags": "gi" },
|
|
1325
|
+
{ "pattern": "startUpdatingLocation|requestLocationUpdates|LocationManager.*startMonitoring", "flags": "g" },
|
|
1326
|
+
{ "pattern": "navigator\\.geolocation\\.watchPosition", "flags": "g" }
|
|
1327
|
+
],
|
|
1328
|
+
"fix_suggestion": "Use single-point location requests instead of continuous monitoring. Avoid background location tracking. Use the minimum granularity needed (e.g., city-level rather than precise coordinates). See ICO AADC Standard 10.",
|
|
1329
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1330
|
+
"languages": ["typescript", "javascript", "java", "kotlin", "swift"],
|
|
1331
|
+
"packs": ["uk-aadc"],
|
|
1332
|
+
"fixability": "guided",
|
|
1333
|
+
"transform_type": null,
|
|
1334
|
+
"scaffold_id": null,
|
|
1335
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/10-geolocation/"
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
"id": "aadc-profiling-007",
|
|
1339
|
+
"name": "Profiling or Algorithmic Feed Enabled by Default",
|
|
1340
|
+
"severity": "critical",
|
|
1341
|
+
"confidence": "high",
|
|
1342
|
+
"category": "profiling",
|
|
1343
|
+
"description": "AADC Standard 12 requires profiling to be switched off by default for children. Algorithmic content feeds, behavioral profiling, and personalization engines must not be active without explicit opt-in.",
|
|
1344
|
+
"patterns": [
|
|
1345
|
+
{ "pattern": "(?:profiling|personaliz(?:e|ation)|algorithmicFeed)(?:Enabled|Active|On|Default)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1346
|
+
{ "pattern": "(?:enableProfiling|enablePersonalization)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1347
|
+
{ "pattern": "(?:behaviorProfile|userProfile|interestGraph)\\s*[:=]", "flags": "gi" },
|
|
1348
|
+
{ "pattern": "(?:userSegment|audienceSegment|cohort)\\s*[:=]", "flags": "gi" }
|
|
1349
|
+
],
|
|
1350
|
+
"fix_suggestion": "Switch profiling off by default. Provide a chronological or non-personalized feed as the default experience. Only enable algorithmic personalization if the child actively opts in. See ICO AADC Standard 12.",
|
|
1351
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1352
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1353
|
+
"packs": ["uk-aadc"],
|
|
1354
|
+
"fixability": "guided",
|
|
1355
|
+
"transform_type": null,
|
|
1356
|
+
"scaffold_id": null,
|
|
1357
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/12-profiling/"
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
"id": "aadc-profiling-008",
|
|
1361
|
+
"name": "Behavioral Data Collection for Recommendation Engine",
|
|
1362
|
+
"severity": "high",
|
|
1363
|
+
"confidence": "medium",
|
|
1364
|
+
"category": "profiling",
|
|
1365
|
+
"description": "AADC Standard 12 restricts profiling children. Collecting behavioral data (interests, habits, browsing patterns) to feed recommendation algorithms requires safeguards to protect children from harmful content amplification.",
|
|
1366
|
+
"patterns": [
|
|
1367
|
+
{ "pattern": "(?:trackBehavior|behavioralData|browsingHistory|viewHistory|watchHistory)", "flags": "gi" },
|
|
1368
|
+
{ "pattern": "(?:recommend|suggest).*(?:algorithm|engine|model|ml)", "flags": "gi" },
|
|
1369
|
+
{ "pattern": "(?:contentRecommend|personalizedFeed|forYou|fyp)", "flags": "gi" }
|
|
1370
|
+
],
|
|
1371
|
+
"fix_suggestion": "If using recommendation algorithms, implement age-appropriate content filtering. Do not amplify harmful, addictive, or age-inappropriate content to children. Provide transparency about why content is recommended. See ICO AADC Standard 12.",
|
|
1372
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1373
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1374
|
+
"packs": ["uk-aadc"],
|
|
1375
|
+
"fixability": "guided",
|
|
1376
|
+
"transform_type": null,
|
|
1377
|
+
"scaffold_id": null,
|
|
1378
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/12-profiling/"
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
"id": "aadc-nudge-009",
|
|
1382
|
+
"name": "Pre-Checked Consent or Privacy Boxes",
|
|
1383
|
+
"severity": "high",
|
|
1384
|
+
"confidence": "high",
|
|
1385
|
+
"category": "dark-patterns",
|
|
1386
|
+
"description": "AADC Standard 13 prohibits nudge techniques that lead children to weaken or turn off privacy protections. Pre-checked consent, marketing, or data-sharing boxes are a nudge that defaults to less privacy.",
|
|
1387
|
+
"patterns": [
|
|
1388
|
+
{ "pattern": "(?:checked|defaultChecked|preChecked)\\s*[:=]\\s*true.*(?:consent|share|track|market|newsletter|terms)", "flags": "gi" },
|
|
1389
|
+
{ "pattern": "(?:consent|share|track|market|newsletter|terms).*(?:checked|defaultChecked|preChecked)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1390
|
+
{ "pattern": "<input[^>]*checked[^>]*(?:consent|agree|marketing|newsletter|share)", "flags": "gi" }
|
|
1391
|
+
],
|
|
1392
|
+
"fix_suggestion": "Remove all pre-checked consent and data-sharing boxes. Consent inputs should start unchecked, requiring active selection by the user. This applies to marketing consent, newsletter signups, data sharing agreements, and privacy preferences. See ICO AADC Standard 13.",
|
|
1393
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1394
|
+
"languages": ["typescript", "javascript", "html", "php", "python"],
|
|
1395
|
+
"packs": ["uk-aadc"],
|
|
1396
|
+
"fixability": "auto",
|
|
1397
|
+
"transform_type": null,
|
|
1398
|
+
"scaffold_id": null,
|
|
1399
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/13-nudge-techniques/"
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
"id": "aadc-nudge-010",
|
|
1403
|
+
"name": "Confirmshaming or Guilt-Based Privacy Nudge",
|
|
1404
|
+
"severity": "high",
|
|
1405
|
+
"confidence": "medium",
|
|
1406
|
+
"category": "dark-patterns",
|
|
1407
|
+
"description": "AADC Standard 13 prohibits exploiting psychological processes to weaken children's privacy. Confirmshaming uses guilt, shame, or fear-of-missing-out language to pressure users into sharing more data or accepting weaker privacy settings.",
|
|
1408
|
+
"patterns": [
|
|
1409
|
+
{ "pattern": "(?:confirmSham|guiltTrip|shameText|shameModal|fomo(?:Text|Message|Modal))", "flags": "gi" },
|
|
1410
|
+
{ "pattern": "(?:are you sure|really want to|miss out|lose access).*(?:privacy|private|restrict|decline)", "flags": "gi" },
|
|
1411
|
+
{ "pattern": "(?:everyone.(?:else\\s)?is|your friends are|left behind|missing out).*(?:share|public|join)", "flags": "gi" }
|
|
1412
|
+
],
|
|
1413
|
+
"fix_suggestion": "Present privacy choices neutrally without emotional manipulation. Avoid language that makes children feel bad for choosing privacy. Do not imply social exclusion or loss for choosing restrictive settings. See ICO AADC Standard 13.",
|
|
1414
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1415
|
+
"languages": ["typescript", "javascript", "html", "python"],
|
|
1416
|
+
"packs": ["uk-aadc"],
|
|
1417
|
+
"fixability": "guided",
|
|
1418
|
+
"transform_type": null,
|
|
1419
|
+
"scaffold_id": null,
|
|
1420
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/13-nudge-techniques/"
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
"id": "aadc-nudge-011",
|
|
1424
|
+
"name": "Privacy-Weakening Reward Mechanism",
|
|
1425
|
+
"severity": "high",
|
|
1426
|
+
"confidence": "medium",
|
|
1427
|
+
"category": "dark-patterns",
|
|
1428
|
+
"description": "AADC Standard 13 prohibits nudges that lead children to provide unnecessary personal data. Offering rewards, unlocks, or premium features in exchange for sharing more data or making profiles public incentivizes weaker privacy.",
|
|
1429
|
+
"patterns": [
|
|
1430
|
+
{ "pattern": "(?:unlock|bonus|reward|premium|upgrade).*(?:share|public|visible|data|profile)", "flags": "gi" },
|
|
1431
|
+
{ "pattern": "(?:shareMore|goPublic|makeVisible).*(?:unlock|get|earn|reward|access)", "flags": "gi" }
|
|
1432
|
+
],
|
|
1433
|
+
"fix_suggestion": "Do not gate features or rewards behind data sharing or public profile requirements. Core service features should be available regardless of privacy settings. See ICO AADC Standard 13.",
|
|
1434
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1435
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1436
|
+
"packs": ["uk-aadc"],
|
|
1437
|
+
"fixability": "guided",
|
|
1438
|
+
"transform_type": null,
|
|
1439
|
+
"scaffold_id": null,
|
|
1440
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/13-nudge-techniques/"
|
|
1441
|
+
},
|
|
1442
|
+
{
|
|
1443
|
+
"id": "aadc-age-012",
|
|
1444
|
+
"name": "Weak Age Gate Using Self-Declaration Only",
|
|
1445
|
+
"severity": "high",
|
|
1446
|
+
"confidence": "medium",
|
|
1447
|
+
"category": "age-assurance",
|
|
1448
|
+
"description": "AADC Standard 3 requires a risk-based approach to recognizing user age. Simple self-declaration checkboxes or dropdowns ('Are you over 13?') are easily bypassed and provide inadequate age assurance for high-risk services.",
|
|
1449
|
+
"patterns": [
|
|
1450
|
+
{ "pattern": "(?:isOver13|isOver18|isAdult|isMinor)\\s*[:=]\\s*(?:true|false|!?\\w+\\.checked)", "flags": "gi" },
|
|
1451
|
+
{ "pattern": "(?:ageGate|age_gate|ageCheck|age_check).*(?:checkbox|select|dropdown|input)", "flags": "gi" },
|
|
1452
|
+
{ "pattern": "(?:age|birth).*(?:self.?report|self.?declare|self.?certif)", "flags": "gi" }
|
|
1453
|
+
],
|
|
1454
|
+
"fix_suggestion": "Implement a risk-based age assurance approach. For high-risk services, use age estimation technology, identity verification, or neutral age estimation rather than simple self-declaration. If unable to verify age, apply the code's standards to all users. See ICO AADC Standard 3.",
|
|
1455
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1456
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift", "html"],
|
|
1457
|
+
"packs": ["uk-aadc"],
|
|
1458
|
+
"fixability": "guided",
|
|
1459
|
+
"transform_type": null,
|
|
1460
|
+
"scaffold_id": null,
|
|
1461
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/3-age-appropriate-application/"
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
"id": "aadc-detrimental-013",
|
|
1465
|
+
"name": "Targeted Advertising to Minors",
|
|
1466
|
+
"severity": "critical",
|
|
1467
|
+
"confidence": "high",
|
|
1468
|
+
"category": "advertising",
|
|
1469
|
+
"description": "AADC Standard 5 prohibits using children's personal data in ways detrimental to their wellbeing. Targeted advertising using children's behavioral data, profiles, or personal information is a detrimental use under the code.",
|
|
1470
|
+
"patterns": [
|
|
1471
|
+
{ "pattern": "(?:targetedAd|personalized(?:Ad|Advert)|behavioralAd).*(?:child|minor|student|kid|teen)", "flags": "gi" },
|
|
1472
|
+
{ "pattern": "(?:child|minor|student|kid|teen).*(?:adTarget|targetAd|personalized(?:Ad|Advert))", "flags": "gi" },
|
|
1473
|
+
{ "pattern": "(?:childProfile|minorProfile|studentProfile).*(?:ad|marketing|monetize)", "flags": "gi" }
|
|
1474
|
+
],
|
|
1475
|
+
"fix_suggestion": "Do not serve targeted or personalized advertising to children. Use only contextual advertising (based on page content, not user data) if advertising is necessary. See ICO AADC Standard 5.",
|
|
1476
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1477
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1478
|
+
"packs": ["uk-aadc"],
|
|
1479
|
+
"fixability": "guided",
|
|
1480
|
+
"transform_type": null,
|
|
1481
|
+
"scaffold_id": null,
|
|
1482
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/5-detrimental-use-of-data/"
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
"id": "aadc-parental-014",
|
|
1486
|
+
"name": "Covert Child Monitoring Without Notification",
|
|
1487
|
+
"severity": "high",
|
|
1488
|
+
"confidence": "high",
|
|
1489
|
+
"category": "parental-controls",
|
|
1490
|
+
"description": "AADC Standard 11 requires that if parental monitoring or tracking features are active, the child must be given an obvious sign. Covert surveillance features that hide monitoring from the child violate this standard.",
|
|
1491
|
+
"patterns": [
|
|
1492
|
+
{ "pattern": "(?:silentTrack|hiddenMonitor|stealthMode|covertMonitor|invisibleTrack)", "flags": "gi" },
|
|
1493
|
+
{ "pattern": "(?:hideTracking|invisible.*monitor|stealth.*(?:parent|track|monitor))", "flags": "gi" },
|
|
1494
|
+
{ "pattern": "(?:parentalMonitor|parentTrack|monitorChild|childTrack|parentalSpy)", "flags": "gi" }
|
|
1495
|
+
],
|
|
1496
|
+
"fix_suggestion": "When parental monitoring or tracking is active, display a clear, prominent indicator visible to the child. Provide age-appropriate explanations of what monitoring is active. Respect the child's growing autonomy. See ICO AADC Standard 11.",
|
|
1497
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1498
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1499
|
+
"packs": ["uk-aadc"],
|
|
1500
|
+
"fixability": "guided",
|
|
1501
|
+
"transform_type": null,
|
|
1502
|
+
"scaffold_id": null,
|
|
1503
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/11-parental-controls/"
|
|
1504
|
+
},
|
|
1505
|
+
{
|
|
1506
|
+
"id": "aadc-tools-015",
|
|
1507
|
+
"name": "User Content Without Report or Block Mechanism",
|
|
1508
|
+
"severity": "medium",
|
|
1509
|
+
"confidence": "medium",
|
|
1510
|
+
"category": "safety",
|
|
1511
|
+
"description": "AADC Standard 15 requires prominent tools to help children report concerns. AADC Standard 6 requires active content moderation. User-generated content (comments, messages, posts) without report, flag, or block mechanisms fails both standards.",
|
|
1512
|
+
"patterns": [
|
|
1513
|
+
{ "pattern": "(?:comment|post|message|chat).*(?:submit|publish|send)(?![\\s\\S]{0,1000}(?:report|flag|block|moderate|filter))", "flags": "gi" },
|
|
1514
|
+
{ "pattern": "(?:directMessage|privateChat|sendMessage|userChat)(?![\\s\\S]{0,500}(?:report|block|moderate|filter))", "flags": "gi" }
|
|
1515
|
+
],
|
|
1516
|
+
"fix_suggestion": "Add prominent report, flag, and block mechanisms alongside all user-generated content features. Implement content moderation for user communications. Provide children with easy ways to report harmful content. See ICO AADC Standards 6 and 15.",
|
|
1517
|
+
"penalty": "Up to £17.5 million or 4% of annual global turnover (UK GDPR)",
|
|
1518
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1519
|
+
"packs": ["uk-aadc"],
|
|
1520
|
+
"fixability": "guided",
|
|
1521
|
+
"transform_type": null,
|
|
1522
|
+
"scaffold_id": null,
|
|
1523
|
+
"guidance_url": "https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/childrens-information/childrens-code-guidance-and-resources/age-appropriate-design-a-code-of-practice-for-online-services/15-online-tools/"
|
|
1524
|
+
},
|
|
1525
|
+
|
|
1526
|
+
{
|
|
1527
|
+
"id": "dsa-ad-profiling-001",
|
|
1528
|
+
"name": "Profiling-Based Ad Targeting Without Minor Exclusion",
|
|
1529
|
+
"severity": "critical",
|
|
1530
|
+
"confidence": "medium",
|
|
1531
|
+
"category": "advertising",
|
|
1532
|
+
"description": "DSA Article 28(2) strictly prohibits presenting advertisements based on profiling using personal data when the platform is aware with reasonable certainty that the recipient is a minor. This ban cannot be overridden by parental consent.",
|
|
1533
|
+
"patterns": [
|
|
1534
|
+
{ "pattern": "(?:targetAudience|behavioralTarget|interest_based|personalized_ad|profile_target)", "flags": "gi" },
|
|
1535
|
+
{ "pattern": "(?:adPersonalization|ad_personalization|personalized_ads)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1536
|
+
{ "pattern": "(?:targeting|retargeting|remarketing)\\s*[:=].*(?:interest|behavior|engagement|browsing)", "flags": "gi" }
|
|
1537
|
+
],
|
|
1538
|
+
"fix_suggestion": "Before serving ads, check if the user is a minor. If so, disable all profiling-based ad targeting. Only contextual advertising (based on page content, not user data) is permitted for minors under DSA Article 28(2). This restriction cannot be waived by parental consent.",
|
|
1539
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1540
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1541
|
+
"packs": ["eu-dsa"],
|
|
1542
|
+
"fixability": "guided",
|
|
1543
|
+
"transform_type": null,
|
|
1544
|
+
"scaffold_id": null,
|
|
1545
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1546
|
+
},
|
|
1547
|
+
{
|
|
1548
|
+
"id": "dsa-autoplay-002",
|
|
1549
|
+
"name": "Media Autoplay Without Minor-Conditional Default",
|
|
1550
|
+
"severity": "high",
|
|
1551
|
+
"confidence": "high",
|
|
1552
|
+
"category": "addictive-design",
|
|
1553
|
+
"description": "DSA Article 28(1) Guidelines require autoplay of video/audio content to be disabled by default for minor users. Autoplay drives extended engagement and undermines minors' ability to control their usage.",
|
|
1554
|
+
"patterns": [
|
|
1555
|
+
{ "pattern": "autoplay|autoPlay|auto_play", "flags": "gi" },
|
|
1556
|
+
{ "pattern": "\\.play\\(\\)", "flags": "g" },
|
|
1557
|
+
{ "pattern": "(?:autoplay|autoPlay|auto_play)\\s*[:=]\\s*true", "flags": "gi" }
|
|
1558
|
+
],
|
|
1559
|
+
"fix_suggestion": "Disable autoplay by default for minor users. Require explicit user action to play media content. If autoplay is needed, gate it behind an age check and provide prominent controls to pause or stop playback. See DSA Article 28(1) Guidelines.",
|
|
1560
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1561
|
+
"languages": ["typescript", "javascript", "html", "python", "java", "kotlin", "swift"],
|
|
1562
|
+
"packs": ["eu-dsa"],
|
|
1563
|
+
"fixability": "auto",
|
|
1564
|
+
"transform_type": null,
|
|
1565
|
+
"scaffold_id": null,
|
|
1566
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
"id": "dsa-infinite-scroll-003",
|
|
1570
|
+
"name": "Infinite Scroll Without Minor Gating",
|
|
1571
|
+
"severity": "high",
|
|
1572
|
+
"confidence": "high",
|
|
1573
|
+
"category": "addictive-design",
|
|
1574
|
+
"description": "DSA Article 28(1) Guidelines require continuous content delivery mechanisms (infinite scroll) to be disabled by default for minors. Infinite scroll exploits psychological mechanisms to extend session times beyond user intent.",
|
|
1575
|
+
"patterns": [
|
|
1576
|
+
{ "pattern": "(?:InfiniteScroll|infinite.?scroll|useInfiniteScroll)", "flags": "gi" },
|
|
1577
|
+
{ "pattern": "IntersectionObserver.*(?:load.?more|next.?page|fetch.?more)", "flags": "gi" },
|
|
1578
|
+
{ "pattern": "(?:onEndReached|onScrollEnd|loadMore|infiniteLoad)", "flags": "gi" }
|
|
1579
|
+
],
|
|
1580
|
+
"fix_suggestion": "Disable infinite scroll by default for minor users. Provide pagination or a 'Load More' button that requires deliberate action. Include session time awareness features (e.g., 'You've been scrolling for X minutes'). See DSA Article 28(1) Guidelines.",
|
|
1581
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1582
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1583
|
+
"packs": ["eu-dsa"],
|
|
1584
|
+
"fixability": "guided",
|
|
1585
|
+
"transform_type": null,
|
|
1586
|
+
"scaffold_id": null,
|
|
1587
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1588
|
+
},
|
|
1589
|
+
{
|
|
1590
|
+
"id": "dsa-push-notify-004",
|
|
1591
|
+
"name": "Push Notification Registration Without Minor Checks",
|
|
1592
|
+
"severity": "high",
|
|
1593
|
+
"confidence": "high",
|
|
1594
|
+
"category": "notifications",
|
|
1595
|
+
"description": "DSA Article 28(1) Guidelines require push notifications to be disabled by default for minors, with additional restrictions during core sleep hours. Notification registration without age-gating or time-of-day restrictions violates this requirement.",
|
|
1596
|
+
"patterns": [
|
|
1597
|
+
{ "pattern": "Notification\\.requestPermission", "flags": "g" },
|
|
1598
|
+
{ "pattern": "PushManager\\.subscribe", "flags": "g" },
|
|
1599
|
+
{ "pattern": "(?:firebase\\.messaging|FCM|APNs)\\.(?:getToken|requestPermission|register)", "flags": "gi" },
|
|
1600
|
+
{ "pattern": "registerForRemoteNotifications|requestNotificationPermission", "flags": "g" }
|
|
1601
|
+
],
|
|
1602
|
+
"fix_suggestion": "Disable push notifications by default for minor users. If notifications are enabled, restrict them during sleep hours (typically 10pm-7am based on age). Require explicit opt-in and provide granular notification controls. See DSA Article 28(1) Guidelines.",
|
|
1603
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1604
|
+
"languages": ["typescript", "javascript", "java", "kotlin", "swift"],
|
|
1605
|
+
"packs": ["eu-dsa"],
|
|
1606
|
+
"fixability": "guided",
|
|
1607
|
+
"transform_type": null,
|
|
1608
|
+
"scaffold_id": null,
|
|
1609
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1610
|
+
},
|
|
1611
|
+
{
|
|
1612
|
+
"id": "dsa-streak-005",
|
|
1613
|
+
"name": "Streak or Engagement Loop Mechanics",
|
|
1614
|
+
"severity": "high",
|
|
1615
|
+
"confidence": "high",
|
|
1616
|
+
"category": "addictive-design",
|
|
1617
|
+
"description": "DSA Article 28(1) Guidelines require streak mechanics and daily engagement reward loops to be disabled by default for minors. These patterns create compulsive usage through loss aversion and variable reward schedules.",
|
|
1618
|
+
"patterns": [
|
|
1619
|
+
{ "pattern": "(?:streakCount|streak_count|dailyStreak|daily_streak|consecutiveDays|consecutive_days)", "flags": "gi" },
|
|
1620
|
+
{ "pattern": "(?:streakReward|streak_reward|streakBonus|streak_bonus)", "flags": "gi" },
|
|
1621
|
+
{ "pattern": "(?:loseStreak|lose_streak|streakBroken|streak_broken|resetStreak|reset_streak)", "flags": "gi" }
|
|
1622
|
+
],
|
|
1623
|
+
"fix_suggestion": "Disable streak mechanics by default for minor users. If streaks are offered, ensure they do not penalize users for breaks and do not create anxiety about losing progress. Consider replacing streaks with non-compulsive engagement features. See DSA Article 28(1) Guidelines.",
|
|
1624
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1625
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1626
|
+
"packs": ["eu-dsa"],
|
|
1627
|
+
"fixability": "guided",
|
|
1628
|
+
"transform_type": null,
|
|
1629
|
+
"scaffold_id": null,
|
|
1630
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1631
|
+
},
|
|
1632
|
+
{
|
|
1633
|
+
"id": "dsa-recommender-006",
|
|
1634
|
+
"name": "Behavioral Recommendation Without Non-Profiled Alternative",
|
|
1635
|
+
"severity": "critical",
|
|
1636
|
+
"confidence": "medium",
|
|
1637
|
+
"category": "profiling",
|
|
1638
|
+
"description": "DSA Articles 27 and 28 require platforms to offer at least one recommendation option that is not based on profiling and to make it the default for minors. Engagement-based signals (watch time, dwell time, scroll depth) in recommender systems without a non-profiled fallback violate this requirement.",
|
|
1639
|
+
"patterns": [
|
|
1640
|
+
{ "pattern": "(?:watchTime|watch_time|dwellTime|dwell_time|engagementScore|engagement_score)", "flags": "gi" },
|
|
1641
|
+
{ "pattern": "(?:clickThroughRate|click_through_rate|scrollDepth|scroll_depth|viewingHistory|viewing_history)", "flags": "gi" },
|
|
1642
|
+
{ "pattern": "(?:implicitSignal|implicit_signal|behavioralSignal|behavioral_signal)", "flags": "gi" }
|
|
1643
|
+
],
|
|
1644
|
+
"fix_suggestion": "Provide a chronological or editorial feed as the default experience for minor users. If using algorithmic recommendations, ensure a non-profiled alternative is easily accessible and set as default. Prioritize explicit user preferences over implicit behavioral signals. See DSA Articles 27 and 28.",
|
|
1645
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1646
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1647
|
+
"packs": ["eu-dsa"],
|
|
1648
|
+
"fixability": "guided",
|
|
1649
|
+
"transform_type": null,
|
|
1650
|
+
"scaffold_id": null,
|
|
1651
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_27.html"
|
|
1652
|
+
},
|
|
1653
|
+
{
|
|
1654
|
+
"id": "dsa-cross-tracking-007",
|
|
1655
|
+
"name": "Cross-Platform Tracking of Minors",
|
|
1656
|
+
"severity": "critical",
|
|
1657
|
+
"confidence": "high",
|
|
1658
|
+
"category": "tracking",
|
|
1659
|
+
"description": "DSA Article 28(1) Guidelines restrict using minors' activity across or beyond the platform unless it serves the best interests of the minor. Cross-site tracking, device fingerprinting, and cross-app identifiers used for profiling minors violate this requirement.",
|
|
1660
|
+
"patterns": [
|
|
1661
|
+
{ "pattern": "(?:thirdPartyCookie|third_party_cookie|crossSiteTrack|cross_site_track)", "flags": "gi" },
|
|
1662
|
+
{ "pattern": "(?:deviceFingerprint|device_fingerprint|browserFingerprint|browser_fingerprint)", "flags": "gi" },
|
|
1663
|
+
{ "pattern": "(?:crossAppId|cross_app_id|advertisingId|advertising_id|IDFA|GAID)", "flags": "gi" }
|
|
1664
|
+
],
|
|
1665
|
+
"fix_suggestion": "Do not use cross-platform tracking identifiers for minors. Disable third-party cookies, device fingerprinting, and advertising identifiers for users known to be under 18. Activity tracking must be limited to the current platform and session. See DSA Article 28(1) Guidelines.",
|
|
1666
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1667
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1668
|
+
"packs": ["eu-dsa"],
|
|
1669
|
+
"fixability": "guided",
|
|
1670
|
+
"transform_type": null,
|
|
1671
|
+
"scaffold_id": null,
|
|
1672
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1673
|
+
},
|
|
1674
|
+
{
|
|
1675
|
+
"id": "dsa-ai-disclosure-008",
|
|
1676
|
+
"name": "AI or Chatbot Interaction Without Disclosure",
|
|
1677
|
+
"severity": "high",
|
|
1678
|
+
"confidence": "medium",
|
|
1679
|
+
"category": "transparency",
|
|
1680
|
+
"description": "DSA Article 28(1) Guidelines require clear, persistent signals when minors are interacting with AI rather than humans. AI features (chatbots, AI-generated responses, AI-powered filters) must be opt-in for minors, not automatically enabled.",
|
|
1681
|
+
"patterns": [
|
|
1682
|
+
{ "pattern": "(?:chatbot|ChatBot|chat_bot|AiAssistant|ai_assistant|virtualAssistant)", "flags": "gi" },
|
|
1683
|
+
{ "pattern": "(?:generateResponse|aiResponse|ai_response|llmOutput|llm_output|completionApi)", "flags": "gi" },
|
|
1684
|
+
{ "pattern": "(?:syntheticContent|synthetic_content|aiGenerated|ai_generated)", "flags": "gi" }
|
|
1685
|
+
],
|
|
1686
|
+
"fix_suggestion": "Display a clear, persistent, child-friendly indicator when a minor is interacting with AI rather than a human. AI chatbots, AI-generated content, and AI-powered features must require explicit opt-in for minor users. See DSA Article 28(1) Guidelines.",
|
|
1687
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1688
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1689
|
+
"packs": ["eu-dsa"],
|
|
1690
|
+
"fixability": "guided",
|
|
1691
|
+
"transform_type": null,
|
|
1692
|
+
"scaffold_id": null,
|
|
1693
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1694
|
+
},
|
|
1695
|
+
{
|
|
1696
|
+
"id": "dsa-ephemeral-009",
|
|
1697
|
+
"name": "Ephemeral or Disappearing Content Feature",
|
|
1698
|
+
"severity": "medium",
|
|
1699
|
+
"confidence": "high",
|
|
1700
|
+
"category": "addictive-design",
|
|
1701
|
+
"description": "DSA Article 28(1) Guidelines require disappearing/ephemeral content features (Stories-style) to be disabled by default for minors. These features create urgency and FOMO, driving compulsive checking behavior.",
|
|
1702
|
+
"patterns": [
|
|
1703
|
+
{ "pattern": "(?:ephemeral|disappearing|selfDestruct|self_destruct|expiringContent|expiring_content)", "flags": "gi" },
|
|
1704
|
+
{ "pattern": "(?:storyDuration|story_duration|storyExpire|story_expire|viewOnce|view_once)", "flags": "gi" },
|
|
1705
|
+
{ "pattern": "(?:ephemeralMessage|ephemeral_message|tempContent|temp_content)", "flags": "gi" }
|
|
1706
|
+
],
|
|
1707
|
+
"fix_suggestion": "Disable disappearing/ephemeral content features by default for minor users. If offered, ensure content expiration does not create artificial urgency. Allow minors to review content without time pressure. See DSA Article 28(1) Guidelines.",
|
|
1708
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1709
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1710
|
+
"packs": ["eu-dsa"],
|
|
1711
|
+
"fixability": "guided",
|
|
1712
|
+
"transform_type": null,
|
|
1713
|
+
"scaffold_id": null,
|
|
1714
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1715
|
+
},
|
|
1716
|
+
{
|
|
1717
|
+
"id": "dsa-read-receipts-010",
|
|
1718
|
+
"name": "Read Receipts or Typing Indicators Enabled by Default",
|
|
1719
|
+
"severity": "medium",
|
|
1720
|
+
"confidence": "high",
|
|
1721
|
+
"category": "privacy",
|
|
1722
|
+
"description": "DSA Article 28(1) Guidelines require read receipts and typing indicators to be disabled by default for minor users. These features create social pressure to respond immediately and can enable monitoring and bullying.",
|
|
1723
|
+
"patterns": [
|
|
1724
|
+
{ "pattern": "(?:readReceipt|read_receipt|readStatus|read_status|seenStatus|seen_status)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1725
|
+
{ "pattern": "(?:typingIndicator|typing_indicator|isTyping|is_typing)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1726
|
+
{ "pattern": "(?:showRead|show_read|markAsRead|mark_as_read).*(?:visible|enabled|default)\\s*[:=]\\s*true", "flags": "gi" }
|
|
1727
|
+
],
|
|
1728
|
+
"fix_suggestion": "Disable read receipts and typing indicators by default for minor users. Allow minors to choose whether to share their read status and typing activity. These features should require explicit opt-in. See DSA Article 28(1) Guidelines.",
|
|
1729
|
+
"penalty": "Up to 6% of annual global turnover (DSA Article 52)",
|
|
1730
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1731
|
+
"packs": ["eu-dsa"],
|
|
1732
|
+
"fixability": "auto",
|
|
1733
|
+
"transform_type": null,
|
|
1734
|
+
"scaffold_id": null,
|
|
1735
|
+
"guidance_url": "https://www.eu-digital-services-act.com/Digital_Services_Act_Article_28.html"
|
|
1736
|
+
},
|
|
1737
|
+
{
|
|
1738
|
+
"id": "caadca-privacy-001",
|
|
1739
|
+
"name": "Default Tracking Enabled",
|
|
1740
|
+
"severity": "critical",
|
|
1741
|
+
"confidence": "medium",
|
|
1742
|
+
"category": "privacy-defaults",
|
|
1743
|
+
"description": "CAADCA requires default high-privacy settings for children. Tracking, analytics, or telemetry must be OFF by default. Code that initializes tracking as enabled without explicit consent violates CAADCA Section 31(b)(7).",
|
|
1744
|
+
"patterns": [
|
|
1745
|
+
{ "pattern": "(?:trackingEnabled|tracking_enabled|enableTracking|enable_tracking)\\s*[:=]\\s*(?:true|1)", "flags": "gi" },
|
|
1746
|
+
{ "pattern": "(?:analytics|telemetry|tracking)\\s*[:=]\\s*\\{[^}]*(?:enabled|active|on)\\s*:\\s*true", "flags": "gi" },
|
|
1747
|
+
{ "pattern": "(?:doNotTrack|do_not_track|dnt)\\s*[:=]\\s*(?:false|0)", "flags": "gi" },
|
|
1748
|
+
{ "pattern": "(?:optOut|opt_out)\\s*[:=]\\s*false\\b", "flags": "gi" }
|
|
1749
|
+
],
|
|
1750
|
+
"fix_suggestion": "Set tracking, analytics, and telemetry to OFF by default. Require explicit opt-in consent before enabling any data collection. Children should not be tracked by default under CAADCA.",
|
|
1751
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1752
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1753
|
+
"packs": ["caadca"],
|
|
1754
|
+
"fixability": "auto",
|
|
1755
|
+
"transform_type": "set-default",
|
|
1756
|
+
"scaffold_id": null,
|
|
1757
|
+
"guidance_url": null
|
|
1758
|
+
},
|
|
1759
|
+
{
|
|
1760
|
+
"id": "caadca-privacy-002",
|
|
1761
|
+
"name": "Analytics Without Privacy Mode",
|
|
1762
|
+
"severity": "high",
|
|
1763
|
+
"confidence": "low",
|
|
1764
|
+
"category": "privacy-defaults",
|
|
1765
|
+
"description": "CAADCA requires privacy-protective defaults. Analytics SDKs must be initialized with privacy mode, anonymization, or child-safe configuration. Code that initializes analytics without privacy protections may violate CAADCA.",
|
|
1766
|
+
"patterns": [
|
|
1767
|
+
{ "pattern": "(?:GoogleAnalytics|ReactGA|gtag|ga)\\s*(?:\\.|\\()\\s*(?:init|initialize|create)\\s*\\((?![^)]*(?:anonym|privacy|child|coppa|restrict))", "flags": "gi" },
|
|
1768
|
+
{ "pattern": "(?:Amplitude|Mixpanel|Segment|Heap|FullStory)\\s*\\.\\s*(?:init|initialize|setup)\\s*\\((?![^)]*(?:anonym|privacy|child|restrict))", "flags": "gi" },
|
|
1769
|
+
{ "pattern": "(?:anonymizeIp|anonymize_ip|ip_anonymization)\\s*[:=]\\s*(?:false|0)", "flags": "gi" }
|
|
1770
|
+
],
|
|
1771
|
+
"fix_suggestion": "Initialize analytics with privacy mode enabled: anonymize IPs, disable user-level tracking, enable child-safe mode. Consider using privacy-preserving analytics alternatives.",
|
|
1772
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1773
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1774
|
+
"packs": ["caadca"],
|
|
1775
|
+
"fixability": "guided",
|
|
1776
|
+
"transform_type": null,
|
|
1777
|
+
"scaffold_id": null,
|
|
1778
|
+
"guidance_url": null
|
|
1779
|
+
},
|
|
1780
|
+
{
|
|
1781
|
+
"id": "caadca-age-001",
|
|
1782
|
+
"name": "Missing Age Estimation or Verification",
|
|
1783
|
+
"severity": "high",
|
|
1784
|
+
"confidence": "low",
|
|
1785
|
+
"category": "age-estimation",
|
|
1786
|
+
"description": "CAADCA Section 31(b)(1) requires businesses to estimate the age of child users with a reasonable level of certainty. Registration or signup flows that collect no age indicator violate this requirement.",
|
|
1787
|
+
"patterns": [
|
|
1788
|
+
{ "pattern": "(?:createUser|create_user|registerUser|register_user|signUp|sign_up)\\s*\\((?![^)]*(?:age|dob|birthdate|birth_?date|date_?of_?birth))[^)]*\\)", "flags": "gi" },
|
|
1789
|
+
{ "pattern": "(?:onboard|signup|register)(?:Form|Page|Screen|Component|View)\\b(?![^\\n]*(?:age|dob|birthdate|dateOfBirth))", "flags": "gi" }
|
|
1790
|
+
],
|
|
1791
|
+
"fix_suggestion": "Add age estimation to your registration flow: collect date of birth, use an age estimation API, or implement neutral age screening. CAADCA requires 'reasonable certainty' that users are not children.",
|
|
1792
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1793
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift", "html", "tsx", "jsx"],
|
|
1794
|
+
"packs": ["caadca"],
|
|
1795
|
+
"fixability": "guided",
|
|
1796
|
+
"transform_type": null,
|
|
1797
|
+
"scaffold_id": null,
|
|
1798
|
+
"guidance_url": null
|
|
1799
|
+
},
|
|
1800
|
+
{
|
|
1801
|
+
"id": "caadca-profiling-001",
|
|
1802
|
+
"name": "Behavioral Profiling Without Safeguards",
|
|
1803
|
+
"severity": "critical",
|
|
1804
|
+
"confidence": "medium",
|
|
1805
|
+
"category": "profiling",
|
|
1806
|
+
"description": "CAADCA Section 31(b)(4) prohibits profiling children by default. Code that builds behavioral profiles, interest graphs, or user segments without age-checking or child safeguards violates this requirement.",
|
|
1807
|
+
"patterns": [
|
|
1808
|
+
{ "pattern": "(?:buildProfile|build_profile|createProfile|create_profile|userProfile|user_profile)\\s*(?:\\(|[:=])(?![^\\n]*(?:age|child|minor|under_?18|safeguard))", "flags": "gi" },
|
|
1809
|
+
{ "pattern": "(?:interestGraph|interest_graph|behaviorProfile|behavior_profile|userSegment|user_segment)\\s*[:=]", "flags": "gi" },
|
|
1810
|
+
{ "pattern": "(?:trackBehavior|track_behavior|logActivity|log_activity|recordAction|record_action)\\s*\\((?![^)]*(?:consent|age|child|privacy))", "flags": "gi" }
|
|
1811
|
+
],
|
|
1812
|
+
"fix_suggestion": "Disable behavioral profiling by default for users who may be children. If profiling is necessary, implement age verification first and apply heightened protections for children under 18.",
|
|
1813
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1814
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1815
|
+
"packs": ["caadca"],
|
|
1816
|
+
"fixability": "guided",
|
|
1817
|
+
"transform_type": null,
|
|
1818
|
+
"scaffold_id": null,
|
|
1819
|
+
"guidance_url": null
|
|
1820
|
+
},
|
|
1821
|
+
{
|
|
1822
|
+
"id": "caadca-profiling-002",
|
|
1823
|
+
"name": "Content Recommendation Without Age Filter",
|
|
1824
|
+
"severity": "high",
|
|
1825
|
+
"confidence": "low",
|
|
1826
|
+
"category": "profiling",
|
|
1827
|
+
"description": "CAADCA requires transparent, age-appropriate content recommendations. Recommendation engines that lack age-based filtering or content rating checks may expose children to harmful content.",
|
|
1828
|
+
"patterns": [
|
|
1829
|
+
{ "pattern": "(?:recommend|getRecommendations|get_recommendations|suggestContent|suggest_content)\\s*\\((?![^)]*(?:age|rating|maturity|child|filter))", "flags": "gi" },
|
|
1830
|
+
{ "pattern": "(?:contentFeed|content_feed|forYou|for_you|discover)(?:Algorithm|Engine|Service)\\b(?![^\\n]*(?:age|rating|child|safe))", "flags": "gi" }
|
|
1831
|
+
],
|
|
1832
|
+
"fix_suggestion": "Add age-based filtering to content recommendations. Implement content rating checks and exclude age-inappropriate material for child users. Make recommendation logic transparent per CAADCA requirements.",
|
|
1833
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1834
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1835
|
+
"packs": ["caadca"],
|
|
1836
|
+
"fixability": "guided",
|
|
1837
|
+
"transform_type": null,
|
|
1838
|
+
"scaffold_id": null,
|
|
1839
|
+
"guidance_url": null
|
|
1840
|
+
},
|
|
1841
|
+
{
|
|
1842
|
+
"id": "caadca-darkpat-001",
|
|
1843
|
+
"name": "Manipulative Consent UI",
|
|
1844
|
+
"severity": "critical",
|
|
1845
|
+
"confidence": "medium",
|
|
1846
|
+
"category": "dark-patterns",
|
|
1847
|
+
"description": "CAADCA Section 31(b)(7) prohibits dark patterns that lead children to provide unnecessary personal information, weaken privacy settings, or extend use. UI patterns like 'skip' or 'continue without' on consent screens are manipulative.",
|
|
1848
|
+
"patterns": [
|
|
1849
|
+
{ "pattern": "(?:skip|dismiss|later|not now|maybe later|no thanks|continue without)(?:Consent|Privacy|Permission|Setup)\\b", "flags": "gi" },
|
|
1850
|
+
{ "pattern": ">\\s*(?:Skip|No thanks|Not now|Maybe later|Continue without|I don't care)\\s*<", "flags": "gi" },
|
|
1851
|
+
{ "pattern": "(?:text-(?:xs|sm)|opacity-(?:50|60|70)|text-gray-(?:300|400)|color:\\s*#(?:ccc|ddd|999)).*(?:decline|reject|opt.?out|privacy)", "flags": "gi" }
|
|
1852
|
+
],
|
|
1853
|
+
"fix_suggestion": "Present consent choices with equal visual weight. Don't make privacy-protective options harder to find or smaller than privacy-invasive options. Avoid manipulative language that pressures children to share data.",
|
|
1854
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1855
|
+
"languages": ["typescript", "javascript", "html", "tsx", "jsx", "vue", "svelte"],
|
|
1856
|
+
"packs": ["caadca"],
|
|
1857
|
+
"fixability": "flag-only",
|
|
1858
|
+
"transform_type": null,
|
|
1859
|
+
"scaffold_id": null,
|
|
1860
|
+
"guidance_url": null
|
|
1861
|
+
},
|
|
1862
|
+
{
|
|
1863
|
+
"id": "caadca-darkpat-002",
|
|
1864
|
+
"name": "Urgency-Creating Countdown Timer",
|
|
1865
|
+
"severity": "high",
|
|
1866
|
+
"confidence": "medium",
|
|
1867
|
+
"category": "dark-patterns",
|
|
1868
|
+
"description": "CAADCA prohibits dark patterns that exploit children. Countdown timers on offers, limited-time promotions, or fear-of-missing-out (FOMO) mechanics are manipulative design patterns targeting children.",
|
|
1869
|
+
"patterns": [
|
|
1870
|
+
{ "pattern": "(?:countdown|timer|timeLeft|time_left|expiresIn|expires_in|hurry|limited.?time|act.?now|last.?chance)(?:Component|Timer|Widget|Banner)\\b", "flags": "gi" },
|
|
1871
|
+
{ "pattern": "(?:setInterval|setTimeout)\\s*\\([^)]*(?:countdown|timer|remaining|expir|urgent|hurry)", "flags": "gi" },
|
|
1872
|
+
{ "pattern": "(?:FOMO|fomo|scarcity|urgency)(?:Banner|Modal|Popup|Alert|Notification)\\b", "flags": "gi" }
|
|
1873
|
+
],
|
|
1874
|
+
"fix_suggestion": "Remove urgency-creating countdown timers, FOMO mechanics, and limited-time pressure from child-facing interfaces. CAADCA prohibits manipulative design that exploits children's vulnerability to pressure tactics.",
|
|
1875
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1876
|
+
"languages": ["typescript", "javascript", "html", "tsx", "jsx", "vue", "svelte"],
|
|
1877
|
+
"packs": ["caadca"],
|
|
1878
|
+
"fixability": "flag-only",
|
|
1879
|
+
"transform_type": null,
|
|
1880
|
+
"scaffold_id": null,
|
|
1881
|
+
"guidance_url": null
|
|
1882
|
+
},
|
|
1883
|
+
{
|
|
1884
|
+
"id": "caadca-darkpat-003",
|
|
1885
|
+
"name": "Confirmshaming Pattern",
|
|
1886
|
+
"severity": "medium",
|
|
1887
|
+
"confidence": "medium",
|
|
1888
|
+
"category": "dark-patterns",
|
|
1889
|
+
"description": "CAADCA prohibits manipulative design patterns that shame children into making privacy-invasive choices. Confirmshaming uses guilt-inducing language on opt-out or decline buttons.",
|
|
1890
|
+
"patterns": [
|
|
1891
|
+
{ "pattern": ">\\s*(?:No,? I don't want|I prefer not to|I'll miss out|No,? I hate saving|I don't like)\\s*", "flags": "gi" },
|
|
1892
|
+
{ "pattern": "(?:confirmshaming|confirm_shaming|guiltTrip|guilt_trip|shameButton|shame_button)\\b", "flags": "gi" }
|
|
1893
|
+
],
|
|
1894
|
+
"fix_suggestion": "Use neutral, non-manipulative language for all opt-out and decline options. Replace confirmshaming copy with straightforward alternatives like 'No thanks' or 'Decline'.",
|
|
1895
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1896
|
+
"languages": ["typescript", "javascript", "html", "tsx", "jsx", "vue", "svelte"],
|
|
1897
|
+
"packs": ["caadca"],
|
|
1898
|
+
"fixability": "flag-only",
|
|
1899
|
+
"transform_type": null,
|
|
1900
|
+
"scaffold_id": null,
|
|
1901
|
+
"guidance_url": null
|
|
1902
|
+
},
|
|
1903
|
+
{
|
|
1904
|
+
"id": "caadca-geo-001",
|
|
1905
|
+
"name": "Precise Geolocation Without Purpose",
|
|
1906
|
+
"severity": "critical",
|
|
1907
|
+
"confidence": "medium",
|
|
1908
|
+
"category": "geolocation",
|
|
1909
|
+
"description": "CAADCA Section 31(b)(3) restricts collecting children's precise geolocation. Code that requests fine-grained location (GPS) without a clear, necessary purpose violates this requirement.",
|
|
1910
|
+
"patterns": [
|
|
1911
|
+
{ "pattern": "(?:getCurrentPosition|watchPosition|geolocation\\.get)\\s*\\((?![^)]*(?:coarse|approximate|city|region|purpose|reason))", "flags": "gi" },
|
|
1912
|
+
{ "pattern": "(?:enableHighAccuracy|high_accuracy)\\s*[:=]\\s*true", "flags": "gi" },
|
|
1913
|
+
{ "pattern": "(?:ACCESS_FINE_LOCATION|kCLLocationAccuracyBest|kCLLocationAccuracyNearestTenMeters)", "flags": "g" },
|
|
1914
|
+
{ "pattern": "(?:latitude|longitude|lat|lng|coordinates).*(?:store|save|persist|track|log|send|upload)\\s*\\(", "flags": "gi" }
|
|
1915
|
+
],
|
|
1916
|
+
"fix_suggestion": "Use coarse/approximate location (city-level) instead of precise GPS coordinates. Only request fine-grained location when strictly necessary for core functionality. Never persistently track a child's location.",
|
|
1917
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1918
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1919
|
+
"packs": ["caadca"],
|
|
1920
|
+
"fixability": "guided",
|
|
1921
|
+
"transform_type": null,
|
|
1922
|
+
"scaffold_id": null,
|
|
1923
|
+
"guidance_url": null
|
|
1924
|
+
},
|
|
1925
|
+
{
|
|
1926
|
+
"id": "caadca-datamin-001",
|
|
1927
|
+
"name": "Excessive Data Collection",
|
|
1928
|
+
"severity": "high",
|
|
1929
|
+
"confidence": "low",
|
|
1930
|
+
"category": "data-minimization",
|
|
1931
|
+
"description": "CAADCA Section 31(b)(3) requires data minimization — only collect personal information that is reasonably necessary. Code that collects extensive personal data fields beyond what the service needs may violate this requirement.",
|
|
1932
|
+
"patterns": [
|
|
1933
|
+
{ "pattern": "(?:collectData|collect_data|gatherInfo|gather_info|harvestData|harvest_data)\\s*\\(", "flags": "gi" },
|
|
1934
|
+
{ "pattern": "(?:required|mandatory)\\s*[:=]\\s*true[^\\n]*(?:phone|address|school|gender|ethnicity|income|ssn|social_security)", "flags": "gi" },
|
|
1935
|
+
{ "pattern": "(?:deviceFingerprint|device_fingerprint|browserFingerprint|browser_fingerprint|canvasFingerprint|canvas_fingerprint)\\b", "flags": "gi" }
|
|
1936
|
+
],
|
|
1937
|
+
"fix_suggestion": "Only collect data that is strictly necessary for the service's core functionality. Remove collection of non-essential fields. Implement data minimization by design per CAADCA requirements.",
|
|
1938
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1939
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1940
|
+
"packs": ["caadca"],
|
|
1941
|
+
"fixability": "flag-only",
|
|
1942
|
+
"transform_type": null,
|
|
1943
|
+
"scaffold_id": null,
|
|
1944
|
+
"guidance_url": null
|
|
1945
|
+
},
|
|
1946
|
+
{
|
|
1947
|
+
"id": "caadca-iap-001",
|
|
1948
|
+
"name": "One-Click Purchase Without Confirmation",
|
|
1949
|
+
"severity": "critical",
|
|
1950
|
+
"confidence": "high",
|
|
1951
|
+
"category": "in-app-purchases",
|
|
1952
|
+
"description": "CAADCA requires friction in purchase flows for children. One-click or instant purchases without a confirmation step can lead to unauthorized spending by minors.",
|
|
1953
|
+
"patterns": [
|
|
1954
|
+
{ "pattern": "(?:oneClickPurchase|one_click_purchase|instantPurchase|instant_purchase|quickBuy|quick_buy)\\b", "flags": "gi" },
|
|
1955
|
+
{ "pattern": "(?:purchase|buy|checkout|pay)\\s*\\((?![^)]*(?:confirm|verify|approve|consent|auth))[^)]*\\)", "flags": "gi" },
|
|
1956
|
+
{ "pattern": "(?:skipConfirmation|skip_confirmation|autoCharge|auto_charge|autoPurchase|auto_purchase)\\s*[:=]\\s*true", "flags": "gi" }
|
|
1957
|
+
],
|
|
1958
|
+
"fix_suggestion": "Add a confirmation step before any purchase. Require explicit confirmation (e.g., 'Are you sure?' dialog) before processing payments. For children, require parental authentication for purchases.",
|
|
1959
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1960
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1961
|
+
"packs": ["caadca"],
|
|
1962
|
+
"fixability": "guided",
|
|
1963
|
+
"transform_type": null,
|
|
1964
|
+
"scaffold_id": null,
|
|
1965
|
+
"guidance_url": null
|
|
1966
|
+
},
|
|
1967
|
+
{
|
|
1968
|
+
"id": "caadca-iap-002",
|
|
1969
|
+
"name": "In-App Purchase Without Parental Gate",
|
|
1970
|
+
"severity": "critical",
|
|
1971
|
+
"confidence": "medium",
|
|
1972
|
+
"category": "in-app-purchases",
|
|
1973
|
+
"description": "CAADCA requires parental consent for financial transactions involving children. In-app purchase flows that don't check for age or parental authorization expose children to unauthorized spending.",
|
|
1974
|
+
"patterns": [
|
|
1975
|
+
{ "pattern": "(?:makePurchase|make_purchase|processPurchase|process_purchase|completePurchase|complete_purchase)\\s*\\((?![^)]*(?:parent|guardian|age|minor|child|consent))", "flags": "gi" },
|
|
1976
|
+
{ "pattern": "(?:virtualCurrency|virtual_currency|coins|gems|vbucks|robux).*(?:purchase|buy|spend)\\s*\\((?![^)]*(?:parent|guardian|consent|auth))", "flags": "gi" }
|
|
1977
|
+
],
|
|
1978
|
+
"fix_suggestion": "Add parental authentication or consent before allowing in-app purchases for users who may be children. Implement age-gating and require parental approval for virtual currency purchases.",
|
|
1979
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
1980
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
1981
|
+
"packs": ["caadca"],
|
|
1982
|
+
"fixability": "guided",
|
|
1983
|
+
"transform_type": null,
|
|
1984
|
+
"scaffold_id": null,
|
|
1985
|
+
"guidance_url": null
|
|
1986
|
+
},
|
|
1987
|
+
{
|
|
1988
|
+
"id": "caadca-notify-001",
|
|
1989
|
+
"name": "Push Notifications Without Frequency Limit",
|
|
1990
|
+
"severity": "medium",
|
|
1991
|
+
"confidence": "low",
|
|
1992
|
+
"category": "notifications",
|
|
1993
|
+
"description": "CAADCA prohibits features that encourage excessive use by children. Push notifications without frequency limits or quiet hours can manipulate children into compulsive engagement.",
|
|
1994
|
+
"patterns": [
|
|
1995
|
+
{ "pattern": "(?:sendNotification|send_notification|pushNotification|push_notification|sendPush|send_push)\\s*\\((?![^)]*(?:limit|throttle|frequency|quiet|schedule|age|child))", "flags": "gi" },
|
|
1996
|
+
{ "pattern": "(?:notificationFrequency|notification_frequency|pushFrequency|push_frequency)\\s*[:=]\\s*(?:unlimited|0|null|undefined)", "flags": "gi" },
|
|
1997
|
+
{ "pattern": "(?:streakReminder|streak_reminder|comeBackNotification|come_back_notification|missYou|miss_you)\\b", "flags": "gi" }
|
|
1998
|
+
],
|
|
1999
|
+
"fix_suggestion": "Implement notification frequency limits and quiet hours for child users. Disable streak-based and FOMO notifications. Allow children to control notification settings easily.",
|
|
2000
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
2001
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
2002
|
+
"packs": ["caadca"],
|
|
2003
|
+
"fixability": "guided",
|
|
2004
|
+
"transform_type": null,
|
|
2005
|
+
"scaffold_id": null,
|
|
2006
|
+
"guidance_url": null
|
|
2007
|
+
},
|
|
2008
|
+
{
|
|
2009
|
+
"id": "caadca-transparency-001",
|
|
2010
|
+
"name": "Missing Child-Friendly Privacy Notice",
|
|
2011
|
+
"severity": "high",
|
|
2012
|
+
"confidence": "low",
|
|
2013
|
+
"category": "transparency",
|
|
2014
|
+
"description": "CAADCA Section 31(b)(6) requires privacy information to be provided in clear, age-appropriate language. Registration forms and data collection points must include prominent, child-friendly privacy disclosures.",
|
|
2015
|
+
"patterns": [
|
|
2016
|
+
{ "pattern": "<form[^>]*(?:id|class|name)\\s*=\\s*[\"'][^\"']*(?:register|signup|sign[-_]up|create[-_]account)[^\"']*[\"'](?![\\s\\S]{0,500}(?:privacy|data|information|collected|shared|used))", "flags": "gi" },
|
|
2017
|
+
{ "pattern": "(?:termsAndConditions|terms_and_conditions|tosAccepted|tos_accepted)\\s*(?:&&|\\|\\|)\\s*(?!.*(?:privacyPolicy|privacy_policy|privacyNotice|privacy_notice))", "flags": "gi" }
|
|
2018
|
+
],
|
|
2019
|
+
"fix_suggestion": "Add a clear, child-friendly privacy notice to all data collection points. Use simple language explaining what data is collected, why, and who has access. Include a prominent link to your privacy policy.",
|
|
2020
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
2021
|
+
"languages": ["typescript", "javascript", "html", "tsx", "jsx", "vue", "svelte"],
|
|
2022
|
+
"packs": ["caadca"],
|
|
2023
|
+
"fixability": "guided",
|
|
2024
|
+
"transform_type": null,
|
|
2025
|
+
"scaffold_id": null,
|
|
2026
|
+
"guidance_url": null
|
|
2027
|
+
},
|
|
2028
|
+
{
|
|
2029
|
+
"id": "caadca-ads-001",
|
|
2030
|
+
"name": "Targeted Advertising to Children",
|
|
2031
|
+
"severity": "critical",
|
|
2032
|
+
"confidence": "medium",
|
|
2033
|
+
"category": "advertising",
|
|
2034
|
+
"description": "CAADCA Section 31(b)(4) prohibits profiling children for targeted advertising. Code that serves behavioral or targeted ads without age verification violates this requirement.",
|
|
2035
|
+
"patterns": [
|
|
2036
|
+
{ "pattern": "(?:targetedAd|targeted_ad|personalizedAd|personalized_ad|behavioralAd|behavioral_ad)\\s*(?:\\(|[:=])(?![^\\n]*(?:age|child|minor|disable|restrict))", "flags": "gi" },
|
|
2037
|
+
{ "pattern": "(?:AdMob|GoogleAds|FacebookAds|adNetwork|ad_network)\\s*\\.\\s*(?:show|display|load|request)\\s*\\((?![^)]*(?:child|minor|age|coppa|restrict))", "flags": "gi" },
|
|
2038
|
+
{ "pattern": "(?:adPersonalization|ad_personalization|adTargeting|ad_targeting)\\s*[:=]\\s*(?:true|1|'enabled'|\"enabled\")", "flags": "gi" }
|
|
2039
|
+
],
|
|
2040
|
+
"fix_suggestion": "Disable targeted and behavioral advertising for users who may be children. Use only contextual (non-personalized) ads. Implement age verification before serving personalized advertising.",
|
|
2041
|
+
"penalty": "$2,500-$7,500 per affected child",
|
|
2042
|
+
"languages": ["typescript", "javascript", "python", "java", "kotlin", "swift"],
|
|
2043
|
+
"packs": ["caadca"],
|
|
2044
|
+
"fixability": "guided",
|
|
2045
|
+
"transform_type": null,
|
|
2046
|
+
"scaffold_id": null,
|
|
2047
|
+
"guidance_url": null
|
|
2048
|
+
},
|
|
2049
|
+
{
|
|
2050
|
+
"id": "AU-OSA-001",
|
|
2051
|
+
"name": "Missing Age Verification at Registration",
|
|
2052
|
+
"severity": "critical",
|
|
2053
|
+
"confidence": "medium",
|
|
2054
|
+
"category": "online-safety",
|
|
2055
|
+
"description": "Account creation or signup flow detected without age verification. The AU Online Safety Act 2021 (as amended 2024) s.63B requires social media platforms to take reasonable steps to verify that users are aged 16 or over before allowing account creation. Registration flows must include age assurance mechanisms — not just self-declaration.",
|
|
2056
|
+
"patterns": [
|
|
2057
|
+
{ "pattern": "(?:createAccount|create_account|registerUser|register_user)\\s*\\((?![^)]*(?:age|dob|dateOfBirth|date_of_birth|birthDate|birth_date|ageVerif|ageCheck|age_check|verifyAge|verify_age))[^)]*\\)", "flags": "gi" },
|
|
2058
|
+
{ "pattern": "(?:signUp|sign_up|onboardUser|onboard_user)\\s*\\((?![^)]*(?:age|dob|dateOfBirth|date_of_birth|birthDate|birth_date|ageVerif|ageCheck|verify_age))[^)]*\\)", "flags": "gi" },
|
|
2059
|
+
{ "pattern": "(?:UserRegistration|AccountCreation|SignupService)\\s*\\.\\s*(?:create|register|submit|process)\\s*\\((?![^)]*(?:age|birth|dob|verif))", "flags": "gi" },
|
|
2060
|
+
{ "pattern": "INSERT\\s+INTO\\s+(?:users|accounts|members)\\s*\\((?![^)]*(?:age|dob|birth_date|date_of_birth))[^)]*\\)\\s*VALUES", "flags": "gi" },
|
|
2061
|
+
{ "pattern": "(?:router|app)\\.(?:post|put)\\s*\\(\\s*['\"](?:\\/register|\\/signup|\\/create-account)['\"](?![^\\n]*(?:ageGate|age_gate|ageVerif|age_verif|checkAge|check_age))", "flags": "gi" }
|
|
2062
|
+
],
|
|
2063
|
+
"fix_suggestion": "Add an age verification step before account creation. Under AU OSA s.63B, social media services must use reasonably effective age assurance to prevent under-16s from creating accounts. Implement identity-based verification (document check, biometric estimation, or digital ID) — not just self-declaration.",
|
|
2064
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2065
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2066
|
+
"packs": ["au-osa"],
|
|
2067
|
+
"fixability": "flag-only",
|
|
2068
|
+
"transform_type": null,
|
|
2069
|
+
"scaffold_id": null,
|
|
2070
|
+
"guidance_url": null
|
|
2071
|
+
},
|
|
2072
|
+
{
|
|
2073
|
+
"id": "AU-OSA-002",
|
|
2074
|
+
"name": "Self-Declaration Age Check",
|
|
2075
|
+
"severity": "high",
|
|
2076
|
+
"confidence": "medium",
|
|
2077
|
+
"category": "online-safety",
|
|
2078
|
+
"description": "Reliance on self-declared age (checkbox, simple DOB field without verification) detected. The AU Online Safety Act 2021 (as amended 2024) s.63C requires 'reasonably effective' age assurance — simple self-declaration (e.g., 'I am over 16' checkbox or unverified date-of-birth entry) does not meet this threshold. Platforms must use technology-based age assurance methods.",
|
|
2079
|
+
"patterns": [
|
|
2080
|
+
{ "pattern": "(?:isOver16|is_over_16|isOver18|is_over_18|isAdult|is_adult|ageConfirmed|age_confirmed)\\s*[:=]\\s*(?:true|false|checkbox|input)", "flags": "gi" },
|
|
2081
|
+
{ "pattern": "(?:ageGate|age_gate|ageCheck|age_check)\\s*[:=]\\s*['\"]?(?:self[_-]?declar|checkbox|honor|trust|confirm)['\"]?", "flags": "gi" },
|
|
2082
|
+
{ "pattern": "<input[^>]*(?:type=['\"](?:checkbox|date)['\"])[^>]*(?:age|birth|dob|over.?1[68])[^>]*>", "flags": "gi" },
|
|
2083
|
+
{ "pattern": "(?:confirmAge|confirm_age|declareAge|declare_age|ageDeclaration|age_declaration)\\s*(?:=|:|\\()", "flags": "gi" },
|
|
2084
|
+
{ "pattern": "(?:age_?verification_?method|ageVerificationMethod)\\s*[:=]\\s*['\"](?:self|declaration|checkbox|honor|dob_only)['\"]", "flags": "gi" }
|
|
2085
|
+
],
|
|
2086
|
+
"fix_suggestion": "Replace self-declaration age checks with a reasonably effective age assurance method. AU OSA s.63C requires technology-based verification such as biometric age estimation, digital identity document checks, or government-issued digital ID verification. A simple checkbox or unverified DOB field is insufficient.",
|
|
2087
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2088
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2089
|
+
"packs": ["au-osa"],
|
|
2090
|
+
"fixability": "flag-only",
|
|
2091
|
+
"transform_type": null,
|
|
2092
|
+
"scaffold_id": null,
|
|
2093
|
+
"guidance_url": null
|
|
2094
|
+
},
|
|
2095
|
+
{
|
|
2096
|
+
"id": "AU-OSA-003",
|
|
2097
|
+
"name": "Missing Under-16 Account Purge",
|
|
2098
|
+
"severity": "critical",
|
|
2099
|
+
"confidence": "low",
|
|
2100
|
+
"category": "online-safety",
|
|
2101
|
+
"description": "Underage user detection without corresponding account deletion or data purge mechanism. When a social media platform determines a user is under 16, the AU Online Safety Act 2021 (as amended 2024) s.63D requires the platform to close the account and delete associated personal data. Failing to purge underage accounts exposes the platform to enforcement action by the eSafety Commissioner.",
|
|
2102
|
+
"patterns": [
|
|
2103
|
+
{ "pattern": "(?:userAge|user_age|accountAge|account_age)\\s*(?:<|<=)\\s*1[68](?![^\\n]*(?:delete|purge|remove|close|disable|suspend|deactivate|terminate))", "flags": "gi" },
|
|
2104
|
+
{ "pattern": "(?:isMinor|is_minor|isUnderage|is_underage|isChild|is_child)\\s*[:=]\\s*true(?![^\\n]*(?:delete|purge|remove|close|disable|suspend|deactivate))", "flags": "gi" },
|
|
2105
|
+
{ "pattern": "(?:age|userAge|user_age)\\s*(?:<|<=)\\s*1[68]\\s*(?:\\)|\\{|&&|\\|\\|)(?![\\s\\S]{0,200}(?:deleteAccount|delete_account|purgeUser|purge_user|removeData|remove_data|closeAccount|close_account))", "flags": "gi" },
|
|
2106
|
+
{ "pattern": "(?:underage_?detected|minorDetected|minor_detected|failed_?age_?check|failedAgeCheck)\\s*(?:=|:|\\()(?![^\\n]*(?:delete|purge|remove|close|wipe|destroy))", "flags": "gi" }
|
|
2107
|
+
],
|
|
2108
|
+
"fix_suggestion": "When a user is determined to be under 16, immediately close the account and delete all associated personal data. Implement an automated purge pipeline triggered by underage detection. AU OSA s.63D requires platforms to take reasonable steps to close accounts and remove data of users found to be under the minimum age.",
|
|
2109
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2110
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2111
|
+
"packs": ["au-osa"],
|
|
2112
|
+
"fixability": "flag-only",
|
|
2113
|
+
"transform_type": null,
|
|
2114
|
+
"scaffold_id": null,
|
|
2115
|
+
"guidance_url": null
|
|
2116
|
+
},
|
|
2117
|
+
{
|
|
2118
|
+
"id": "AU-OSA-004",
|
|
2119
|
+
"name": "Class 1/Class 2 Content Without Moderation",
|
|
2120
|
+
"severity": "critical",
|
|
2121
|
+
"confidence": "medium",
|
|
2122
|
+
"category": "online-safety",
|
|
2123
|
+
"description": "User-generated content upload or submission detected without content moderation, classification, or safety scanning. The AU Online Safety Act 2021 Schedule 2 classifies illegal content as Class 1 (e.g., CSAM, terrorism) and harmful content as Class 2 (e.g., violence, self-harm). Platforms must proactively detect and prevent distribution of such material under s.109 (BOSE determination).",
|
|
2124
|
+
"patterns": [
|
|
2125
|
+
{ "pattern": "(?:uploadContent|upload_content|submitPost|submit_post|uploadImage|upload_image|uploadVideo|upload_video|uploadMedia|upload_media)\\s*\\((?![^)]*(?:moderate|classify|scan|filter|review|check|safety|csam|hash))", "flags": "gi" },
|
|
2126
|
+
{ "pattern": "(?:createPost|create_post|publishContent|publish_content|postContent|post_content)\\s*\\((?![^)]*(?:moderate|classify|scan|filter|review|check|safety))", "flags": "gi" },
|
|
2127
|
+
{ "pattern": "(?:multer|formidable|busboy|express-fileupload)\\s*\\((?![^\\n]*(?:contentModerat|content_moderat|photoScan|photo_scan|imageSafety|image_safety|hashCheck|hash_check))", "flags": "gi" },
|
|
2128
|
+
{ "pattern": "(?:S3|GCS|Azure|CloudStorage)\\.(?:upload|putObject|put_object|createBlob)\\s*\\((?![^\\n]*(?:moderate|scan|classify|filter|safety))", "flags": "gi" }
|
|
2129
|
+
],
|
|
2130
|
+
"fix_suggestion": "Implement content moderation before or immediately after content upload. Use automated scanning for Class 1 material (CSAM hash matching via PhotoDNA or similar), and classification/filtering for Class 2 material (violence, self-harm). AU OSA Schedule 2 and BOSE s.109 require proactive detection and rapid removal.",
|
|
2131
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2132
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2133
|
+
"packs": ["au-osa"],
|
|
2134
|
+
"fixability": "flag-only",
|
|
2135
|
+
"transform_type": null,
|
|
2136
|
+
"scaffold_id": null,
|
|
2137
|
+
"guidance_url": null
|
|
2138
|
+
},
|
|
2139
|
+
{
|
|
2140
|
+
"id": "AU-OSA-005",
|
|
2141
|
+
"name": "Content Removal SLA Non-Compliance",
|
|
2142
|
+
"severity": "high",
|
|
2143
|
+
"confidence": "medium",
|
|
2144
|
+
"category": "online-safety",
|
|
2145
|
+
"description": "Content reporting or flagging mechanism detected without time-bound removal or escalation workflow. The AU Online Safety Act 2021 s.88 empowers the eSafety Commissioner to issue removal notices requiring compliance within 24 hours. Platforms must have automated escalation and removal pipelines to meet this SLA.",
|
|
2146
|
+
"patterns": [
|
|
2147
|
+
{ "pattern": "(?:reportContent|report_content|flagContent|flag_content|reportPost|report_post|flagPost|flag_post)\\s*(?:=|:|\\()(?![^\\n]*(?:autoRemove|auto_remove|queueReview|queue_review|removalSLA|removal_sla|escalat|removeWithin|remove_within|timer|deadline|sla))", "flags": "gi" },
|
|
2148
|
+
{ "pattern": "(?:contentReport|content_report|flaggedContent|flagged_content|reportQueue|report_queue)\\s*[:=]\\s*\\{(?![^}]*(?:sla|deadline|ttl|timeout|escalat|autoRemov|auto_remov|maxAge|max_age|expir))", "flags": "gi" },
|
|
2149
|
+
{ "pattern": "(?:handleReport|handle_report|processFlag|process_flag|reviewContent|review_content)\\s*\\((?![^)]*(?:sla|deadline|timeout|urgent|priority|escalat))", "flags": "gi" },
|
|
2150
|
+
{ "pattern": "(?:abuse_?report|safety_?report|harm_?report)\\s*(?:=|:|\\()(?![^\\n]*(?:24.?h|twenty.?four|sla|deadline|urgent|escalat|auto.?remov))", "flags": "gi" }
|
|
2151
|
+
],
|
|
2152
|
+
"fix_suggestion": "Implement a time-bound content removal pipeline. AU OSA s.88 removal notices require compliance within 24 hours. Add SLA tracking, automated escalation for unresolved reports, and priority queuing for eSafety Commissioner notices. Ensure removal timestamps are logged for compliance auditing.",
|
|
2153
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2154
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2155
|
+
"packs": ["au-osa"],
|
|
2156
|
+
"fixability": "flag-only",
|
|
2157
|
+
"transform_type": null,
|
|
2158
|
+
"scaffold_id": null,
|
|
2159
|
+
"guidance_url": null
|
|
2160
|
+
},
|
|
2161
|
+
{
|
|
2162
|
+
"id": "AU-OSA-006",
|
|
2163
|
+
"name": "Minor Data Retention Without TTL",
|
|
2164
|
+
"severity": "high",
|
|
2165
|
+
"confidence": "medium",
|
|
2166
|
+
"category": "online-safety",
|
|
2167
|
+
"description": "Storage of child or minor user data without time-to-live, retention policy, or automatic deletion mechanism. The AU Online Safety Act 2021 BOSE determination (s.109) and Privacy Act 1988 APP 11.2 require data minimization and defined retention limits for personal information, particularly for minors. Data must not be kept longer than necessary.",
|
|
2168
|
+
"patterns": [
|
|
2169
|
+
{ "pattern": "(?:childData|child_data|minorData|minor_data|kidProfile|kid_profile|childProfile|child_profile|underageData|underage_data)\\s*[:=]\\s*\\{(?![^}]*(?:ttl|expir|retention|deleteAfter|delete_after|maxAge|max_age|purge|cleanup))", "flags": "gi" },
|
|
2170
|
+
{ "pattern": "(?:userData|user_data|userProfile|user_profile|accountData|account_data)\\s*[:=]\\s*\\{[^}]*(?:isMinor|is_minor|isChild|is_child|age\\s*[:=]\\s*\\d)(?![^}]*(?:ttl|expir|retention|deleteAfter|delete_after|purge))", "flags": "gi" },
|
|
2171
|
+
{ "pattern": "(?:CREATE\\s+TABLE|createTable|defineSchema|Schema)\\s*[^;]*(?:child|minor|kid|youth|teen)[^;]*(?![^;]*(?:ttl|expir|retention|deleted_at|purge_at|cleanup))", "flags": "gi" },
|
|
2172
|
+
{ "pattern": "(?:store|save|persist|cache|retain)(?:Child|Minor|Youth|Kid|Teen)(?:Data|Profile|Record|Info)\\s*\\((?![^)]*(?:ttl|expir|retention|maxAge|max_age|purge))", "flags": "gi" }
|
|
2173
|
+
],
|
|
2174
|
+
"fix_suggestion": "Add retention limits (TTL, expiresAt, or retention policy) to all data stores containing minor user information. Implement automated purge mechanisms. AU OSA BOSE (s.109) expects data minimization, and Privacy Act 1988 APP 11.2 requires deletion when data is no longer needed for its collected purpose.",
|
|
2175
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2176
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2177
|
+
"packs": ["au-osa"],
|
|
2178
|
+
"fixability": "flag-only",
|
|
2179
|
+
"transform_type": null,
|
|
2180
|
+
"scaffold_id": null,
|
|
2181
|
+
"guidance_url": null
|
|
2182
|
+
},
|
|
2183
|
+
{
|
|
2184
|
+
"id": "AU-OSA-007",
|
|
2185
|
+
"name": "Missing Safety Impact Assessment Hook",
|
|
2186
|
+
"severity": "medium",
|
|
2187
|
+
"confidence": "low",
|
|
2188
|
+
"category": "online-safety",
|
|
2189
|
+
"description": "Feature launch, deployment, or rollout code detected without a safety assessment or risk evaluation step. The AU Online Safety Act 2021 BOSE determination (s.109) expects platforms to proactively assess the safety impact of new features before deployment, particularly features that affect minors or user-generated content.",
|
|
2190
|
+
"patterns": [
|
|
2191
|
+
{ "pattern": "(?:featureLaunch|feature_launch|launchFeature|launch_feature|deployFeature|deploy_feature|rolloutFeature|rollout_feature)\\s*(?:=|:|\\()(?![^\\n]*(?:safetyReview|safety_review|impactAssess|impact_assess|riskEval|risk_eval|safetyCheck|safety_check))", "flags": "gi" },
|
|
2192
|
+
{ "pattern": "(?:featureFlag|feature_flag|featureToggle|feature_toggle)\\s*\\.\\s*(?:enable|activate|launch|rollout)\\s*\\((?![^)]*(?:safety|risk|assess|review|impact))", "flags": "gi" },
|
|
2193
|
+
{ "pattern": "(?:releaseFeature|release_feature|enableFeature|enable_feature|shipFeature|ship_feature)\\s*\\((?![^)]*(?:safety|risk|assess|review|impact|audit))", "flags": "gi" },
|
|
2194
|
+
{ "pattern": "(?:gradualRollout|gradual_rollout|canaryRelease|canary_release|abTest|ab_test)\\s*(?:=|:|\\()(?![^\\n]*(?:safety|risk|assess|impact|child|minor))", "flags": "gi" }
|
|
2195
|
+
],
|
|
2196
|
+
"fix_suggestion": "Add a safety impact assessment gate before feature launches. Create a safetyReview() or impactAssessment() hook that evaluates potential harms to minors, content moderation implications, and regulatory compliance before enabling new features. AU OSA BOSE (s.109) expects proactive safety evaluation.",
|
|
2197
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2198
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2199
|
+
"packs": ["au-osa"],
|
|
2200
|
+
"fixability": "flag-only",
|
|
2201
|
+
"transform_type": null,
|
|
2202
|
+
"scaffold_id": null,
|
|
2203
|
+
"guidance_url": null
|
|
2204
|
+
},
|
|
2205
|
+
{
|
|
2206
|
+
"id": "AU-OSA-008",
|
|
2207
|
+
"name": "Missing Transparency Report Generation",
|
|
2208
|
+
"severity": "medium",
|
|
2209
|
+
"confidence": "low",
|
|
2210
|
+
"category": "online-safety",
|
|
2211
|
+
"description": "Platform analytics, metrics, or reporting infrastructure detected without transparency report generation for safety compliance. The AU Online Safety Act 2021 BOSE determination (s.109) requires platforms to publish transparency reports covering content removal statistics, complaint resolution rates, and safety enforcement actions.",
|
|
2212
|
+
"patterns": [
|
|
2213
|
+
{ "pattern": "(?:platformMetrics|platform_metrics|adminDashboard|admin_dashboard|analyticsReport|analytics_report|moderationStats|moderation_stats)\\s*(?:=|:|\\()(?![^\\n]*(?:transparencyReport|transparency_report|safetyMetrics|safety_metrics|complianceReport|compliance_report|publicReport|public_report))", "flags": "gi" },
|
|
2214
|
+
{ "pattern": "(?:generateReport|generate_report|exportMetrics|export_metrics|buildReport|build_report)\\s*\\((?![^)]*(?:transparency|compliance|safety|eSafety|esafety|public|removal|enforcement))", "flags": "gi" },
|
|
2215
|
+
{ "pattern": "(?:contentRemovalCount|removal_count|flaggedCount|flagged_count|reportCount|report_count)\\s*[:=](?![^\\n]*(?:transparencyReport|transparency_report|publicReport|public_report|publish|disclose))", "flags": "gi" },
|
|
2216
|
+
{ "pattern": "(?:moderationDashboard|moderation_dashboard|trustSafety|trust_safety|safetyOps|safety_ops)\\s*[:=]\\s*\\{(?![^}]*(?:transparency|public|disclose|publish|compliance))", "flags": "gi" }
|
|
2217
|
+
],
|
|
2218
|
+
"fix_suggestion": "Implement transparency report generation that publishes safety statistics including: content removal counts by category, average removal time, complaint resolution rates, and eSafety Commissioner notice compliance. AU OSA BOSE (s.109) requires platforms to be transparent about their safety practices.",
|
|
2219
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2220
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2221
|
+
"packs": ["au-osa"],
|
|
2222
|
+
"fixability": "flag-only",
|
|
2223
|
+
"transform_type": null,
|
|
2224
|
+
"scaffold_id": null,
|
|
2225
|
+
"guidance_url": null
|
|
2226
|
+
},
|
|
2227
|
+
{
|
|
2228
|
+
"id": "AU-OSA-009",
|
|
2229
|
+
"name": "Third-Party SDK Without Safety Vetting",
|
|
2230
|
+
"severity": "high",
|
|
2231
|
+
"confidence": "medium",
|
|
2232
|
+
"category": "online-safety",
|
|
2233
|
+
"description": "Third-party SDK, script, or external library loading detected without safety vetting or allowlisting. The AU Online Safety Act 2021 BOSE determination (s.109) requires platforms to ensure third-party services integrated into their products also comply with online safety requirements. Unvetted third-party code may introduce content safety, data handling, or age-verification gaps.",
|
|
2234
|
+
"patterns": [
|
|
2235
|
+
{ "pattern": "(?:loadScript|load_script|injectScript|inject_script|loadSDK|load_sdk|importSDK|import_sdk)\\s*\\((?![^)]*(?:vetted|approved|allowlist|allow_list|whitelist|white_list|trusted|verified|safety))", "flags": "gi" },
|
|
2236
|
+
{ "pattern": "document\\.createElement\\s*\\(\\s*['\"]script['\"]\\s*\\)[^;]*\\.src\\s*=(?![^;]*(?:vetted|approved|allowlist|allow_list|trusted|verified))", "flags": "gi" },
|
|
2237
|
+
{ "pattern": "(?:thirdParty|third_party|externalSDK|external_sdk|vendorScript|vendor_script)\\s*[:=]\\s*(?:\\[|\\{)(?![^\\]\\}]*(?:vetted|approved|allowlist|allow_list|verified|safety_check|safety_reviewed))", "flags": "gi" },
|
|
2238
|
+
{ "pattern": "(?:addPlugin|add_plugin|registerPlugin|register_plugin|installAddon|install_addon)\\s*\\((?![^)]*(?:vetted|approved|allowlist|allow_list|trusted|verified|safety))", "flags": "gi" }
|
|
2239
|
+
],
|
|
2240
|
+
"fix_suggestion": "Implement a third-party SDK vetting process. Maintain an allowlist of approved SDKs and verify each third-party integration for AU OSA compliance before deployment. Ensure third-party services handle minor data appropriately and support content moderation requirements. AU OSA BOSE (s.109) extends safety expectations to third-party integrations.",
|
|
2241
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2242
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2243
|
+
"packs": ["au-osa"],
|
|
2244
|
+
"fixability": "flag-only",
|
|
2245
|
+
"transform_type": null,
|
|
2246
|
+
"scaffold_id": null,
|
|
2247
|
+
"guidance_url": null
|
|
2248
|
+
},
|
|
2249
|
+
{
|
|
2250
|
+
"id": "AU-OSA-010",
|
|
2251
|
+
"name": "Missing Complaint Mechanism",
|
|
2252
|
+
"severity": "high",
|
|
2253
|
+
"confidence": "medium",
|
|
2254
|
+
"category": "online-safety",
|
|
2255
|
+
"description": "User-facing feature, dashboard, or settings page detected without an accessible complaint or safety reporting mechanism. The AU Online Safety Act 2021 s.46 requires platforms to provide users (including parents and guardians) with a clear and accessible way to report online safety concerns, including cyberbullying, harmful content, and image-based abuse.",
|
|
2256
|
+
"patterns": [
|
|
2257
|
+
{ "pattern": "(?:userDashboard|user_dashboard|userSettings|user_settings|profilePage|profile_page|accountPage|account_page)\\s*[:=]\\s*\\{(?![^}]*(?:report|complaint|feedback|supportTicket|support_ticket|helpCenter|help_center|safetyReport|safety_report))", "flags": "gi" },
|
|
2258
|
+
{ "pattern": "(?:renderProfile|render_profile|renderDashboard|render_dashboard|renderSettings|render_settings)\\s*\\((?![^\\n]*(?:report|complaint|feedback|support|safety|help))", "flags": "gi" },
|
|
2259
|
+
{ "pattern": "(?:menuItems|menu_items|navItems|nav_items|sidebarItems|sidebar_items)\\s*[:=]\\s*\\[(?![^\\]]*(?:report|complaint|feedback|support|safety|help))", "flags": "gi" },
|
|
2260
|
+
{ "pattern": "(?:UserProfile|Dashboard|Settings|Account)(?:Page|Screen|View|Component)\\s*(?:=|extends|implements)(?![^\\n]*(?:Report|Complaint|Feedback|Support|Safety|Help))", "flags": "gi" }
|
|
2261
|
+
],
|
|
2262
|
+
"fix_suggestion": "Add an accessible complaint and safety reporting mechanism to all user-facing pages. Users must be able to report cyberbullying, harmful content, and image-based abuse. AU OSA s.46 requires platforms to provide clear reporting pathways and respond to complaints in a timely manner.",
|
|
2263
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2264
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2265
|
+
"packs": ["au-osa"],
|
|
2266
|
+
"fixability": "flag-only",
|
|
2267
|
+
"transform_type": null,
|
|
2268
|
+
"scaffold_id": null,
|
|
2269
|
+
"guidance_url": null
|
|
2270
|
+
},
|
|
2271
|
+
{
|
|
2272
|
+
"id": "AU-OSA-011",
|
|
2273
|
+
"name": "Cross-Border Minor Data Transfer",
|
|
2274
|
+
"severity": "critical",
|
|
2275
|
+
"confidence": "low",
|
|
2276
|
+
"category": "online-safety",
|
|
2277
|
+
"description": "Transfer of child or minor user data to overseas servers, regions, or third-party international endpoints detected without adequate protection controls. The AU Online Safety Act 2021 BOSE (s.109) and Privacy Act 1988 APP 8 require that personal information transferred overseas receives equivalent protection. For minors' data, additional safeguards are expected.",
|
|
2278
|
+
"patterns": [
|
|
2279
|
+
{ "pattern": "(?:dataTransfer|data_transfer|syncToCloud|sync_to_cloud|replicateTo|replicate_to|exportData|export_data)\\s*\\([^)]*(?:overseas|international|foreign|offshore|cross.?border|eu-west|us-east|ap-southeast|cn-north)[^)]*\\)(?![^\\n]*(?:adequateProtection|adequate_protection|encryptedTransfer|encrypted_transfer|dataProtection|data_protection|safeguard))", "flags": "gi" },
|
|
2280
|
+
{ "pattern": "(?:childData|child_data|minorData|minor_data|kidData|kid_data|youthData|youth_data)[^\\n]*(?:transfer|sync|replicate|export|send|transmit)\\s*\\([^)]*(?:region|endpoint|server|host|bucket)(?![^)]*(?:domestic|local|au-|sydney|melbourne|protect|encrypt|safeguard))", "flags": "gi" },
|
|
2281
|
+
{ "pattern": "(?:transferTo|transfer_to|migrateData|migrate_data|moveData|move_data)\\s*\\([^)]*(?:region|server|endpoint)[^)]*\\)[^\\n]*(?:child|minor|kid|youth|under.?1[68])(?![^\\n]*(?:protect|encrypt|safeguard|consent|adequate))", "flags": "gi" },
|
|
2282
|
+
{ "pattern": "(?:CROSS_REGION|CROSS_BORDER|INTERNATIONAL|OVERSEAS)_(?:SYNC|TRANSFER|REPLICATION)\\s*[:=]\\s*(?:true|1|['\"]enabled['\"])(?![^\\n]*(?:minor.?protect|child.?safe|adequate.?protect|data.?protect))", "flags": "gi" }
|
|
2283
|
+
],
|
|
2284
|
+
"fix_suggestion": "Ensure minor data transferred internationally has equivalent protection. Implement encryption in transit, verify the receiving jurisdiction's data protection adequacy, and document safeguards. AU Privacy Act 1988 APP 8 requires reasonable steps to ensure overseas recipients handle data consistently with Australian Privacy Principles. BOSE (s.109) heightens expectations for minors.",
|
|
2285
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2286
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2287
|
+
"packs": ["au-osa"],
|
|
2288
|
+
"fixability": "flag-only",
|
|
2289
|
+
"transform_type": null,
|
|
2290
|
+
"scaffold_id": null,
|
|
2291
|
+
"guidance_url": null
|
|
2292
|
+
},
|
|
2293
|
+
{
|
|
2294
|
+
"id": "AU-OSA-012",
|
|
2295
|
+
"name": "Age-Restricted Content Without Re-Authentication",
|
|
2296
|
+
"severity": "high",
|
|
2297
|
+
"confidence": "medium",
|
|
2298
|
+
"category": "online-safety",
|
|
2299
|
+
"description": "Access to age-restricted, mature, or harmful content categories detected without re-authentication or age re-verification. The AU Online Safety Act 2021 s.109 BOSE expectations and the Restricted Access System Declaration require platforms to implement stepped access controls — users must re-verify their age or identity before viewing restricted content, even if previously authenticated.",
|
|
2300
|
+
"patterns": [
|
|
2301
|
+
{ "pattern": "(?:restrictedContent|restricted_content|matureContent|mature_content|adultContent|adult_content|ageGatedContent|age_gated_content|nsfw)\\s*(?:=|:|\\()(?![^\\n]*(?:reAuth|re_auth|reVerify|re_verify|confirmAge|confirm_age|ageCheck|age_check|verifyAge|verify_age|stepUp|step_up))", "flags": "gi" },
|
|
2302
|
+
{ "pattern": "(?:serveContent|serve_content|showContent|show_content|displayContent|display_content)\\s*\\([^)]*(?:restricted|mature|adult|nsfw|age.?gated|r18|r_18|classification)(?![^)]*(?:reAuth|re_auth|reVerify|re_verify|confirmAge|confirm_age|checkAge|check_age))", "flags": "gi" },
|
|
2303
|
+
{ "pattern": "(?:contentRating|content_rating|ageRating|age_rating|classification)\\s*[:=]\\s*['\"](?:R18|MA15|X18|restricted|mature|adult)['\"](?![^\\n]*(?:reAuth|re_auth|reVerify|re_verify|gate|confirm|check|stepUp|step_up))", "flags": "gi" },
|
|
2304
|
+
{ "pattern": "(?:accessRestricted|access_restricted|viewMature|view_mature|unlockContent|unlock_content)\\s*\\((?![^)]*(?:reAuth|re_auth|reVerify|re_verify|confirmAge|confirm_age|stepUpAuth|step_up_auth|identityCheck|identity_check))", "flags": "gi" }
|
|
2305
|
+
],
|
|
2306
|
+
"fix_suggestion": "Implement re-authentication or age re-verification before serving age-restricted content. Even if a user is already logged in, access to R18+ or MA15+ classified content should require a step-up verification (biometric, PIN, or identity re-check). AU OSA Restricted Access System Declaration and BOSE (s.109) require robust access controls for restricted material.",
|
|
2307
|
+
"penalty": "Up to AUD $49.5M (body corporate) or AUD $2.475M (individual)",
|
|
2308
|
+
"languages": ["typescript", "javascript", "python", "java", "swift", "kotlin"],
|
|
2309
|
+
"packs": ["au-osa"],
|
|
2310
|
+
"fixability": "flag-only",
|
|
2311
|
+
"transform_type": null,
|
|
2312
|
+
"scaffold_id": null,
|
|
2313
|
+
"guidance_url": null
|
|
2314
|
+
},
|
|
2315
|
+
{
|
|
2316
|
+
"id": "AI-RISK-001",
|
|
2317
|
+
"name": "Unconsented Behavioral Profiling",
|
|
2318
|
+
"severity": "critical",
|
|
2319
|
+
"confidence": "medium",
|
|
2320
|
+
"category": "ai-risk",
|
|
2321
|
+
"description": "Behavioral profiling of children without explicit opt-in consent violates EU AI Act Art. 9. Analytics platforms must gate identify() calls behind verified consent.",
|
|
2322
|
+
"patterns": [
|
|
2323
|
+
{ "pattern": "(?:analytics|mixpanel|segment|amplitude)\\.identify\\(", "flags": "gi" },
|
|
2324
|
+
{ "pattern": "(?:trackUser|identifyUser|profileUser)\\(", "flags": "gi" },
|
|
2325
|
+
{ "pattern": "userProfile\\.(?:set|update|create)\\(", "flags": "gi" }
|
|
2326
|
+
],
|
|
2327
|
+
"fix_suggestion": "Gate user identification behind explicit consent: if (hasParentalConsent) { analytics.identify(...) }",
|
|
2328
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac35M or 7% of global annual turnover",
|
|
2329
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2330
|
+
"packs": ["eu-ai-act"],
|
|
2331
|
+
"fixability": "guided",
|
|
2332
|
+
"transform_type": null,
|
|
2333
|
+
"scaffold_id": null,
|
|
2334
|
+
"guidance_url": null
|
|
2335
|
+
},
|
|
2336
|
+
{
|
|
2337
|
+
"id": "AI-RISK-002",
|
|
2338
|
+
"name": "Algorithmic Manipulation Without Audit",
|
|
2339
|
+
"severity": "high",
|
|
2340
|
+
"confidence": "medium",
|
|
2341
|
+
"category": "ai-risk",
|
|
2342
|
+
"description": "Content recommendation algorithms targeting children must have audit trails per EU AI Act Art. 9. Ranking and recommendation functions need logging hooks.",
|
|
2343
|
+
"patterns": [
|
|
2344
|
+
{ "pattern": "(?:rankContent|recommendNext|algorithmicFeed|personalizedFeed|contentRanking)\\(", "flags": "gi" },
|
|
2345
|
+
{ "pattern": "(?:getRecommendations|suggestContent|curateForUser)\\(", "flags": "gi" },
|
|
2346
|
+
{ "pattern": "sortBy:\\s*['\"](?:engagement|relevance|trending)['\"]", "flags": "gi" }
|
|
2347
|
+
],
|
|
2348
|
+
"fix_suggestion": "Add audit logging to recommendation functions: log input features, output ranking, and model version for each recommendation served.",
|
|
2349
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2350
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2351
|
+
"packs": ["eu-ai-act"],
|
|
2352
|
+
"fixability": "guided",
|
|
2353
|
+
"transform_type": null,
|
|
2354
|
+
"scaffold_id": null,
|
|
2355
|
+
"guidance_url": null
|
|
2356
|
+
},
|
|
2357
|
+
{
|
|
2358
|
+
"id": "AI-RISK-003",
|
|
2359
|
+
"name": "ML Model Without Fairness Testing",
|
|
2360
|
+
"severity": "medium",
|
|
2361
|
+
"confidence": "low",
|
|
2362
|
+
"category": "ai-risk",
|
|
2363
|
+
"description": "ML models processing children's data must undergo bias and fairness testing per EU AI Act Art. 9. Training pipelines need documented fairness checks.",
|
|
2364
|
+
"patterns": [
|
|
2365
|
+
{ "pattern": "model\\.(?:fit|train|finetune)\\(", "flags": "gi" },
|
|
2366
|
+
{ "pattern": "(?:trainModel|fitModel|trainPipeline)\\(", "flags": "gi" },
|
|
2367
|
+
{ "pattern": "(?:tensorflow|torch|sklearn|keras)\\.(?:fit|train)", "flags": "gi" }
|
|
2368
|
+
],
|
|
2369
|
+
"fix_suggestion": "Add fairness testing to ML pipeline: run bias audits (demographic parity, equalized odds) before deploying models that affect children.",
|
|
2370
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2371
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2372
|
+
"packs": ["eu-ai-act"],
|
|
2373
|
+
"fixability": "flag-only",
|
|
2374
|
+
"transform_type": null,
|
|
2375
|
+
"scaffold_id": null,
|
|
2376
|
+
"guidance_url": null
|
|
2377
|
+
},
|
|
2378
|
+
{
|
|
2379
|
+
"id": "AI-RISK-004",
|
|
2380
|
+
"name": "Synthetic Content Without Labeling",
|
|
2381
|
+
"severity": "high",
|
|
2382
|
+
"confidence": "medium",
|
|
2383
|
+
"category": "ai-risk",
|
|
2384
|
+
"description": "AI-generated images, text, or audio must be clearly labeled per EU AI Act Art. 50. Children especially need visible disclosure of synthetic content.",
|
|
2385
|
+
"patterns": [
|
|
2386
|
+
{ "pattern": "(?:generateImage|aiGenerate|textToImage|imageGeneration)\\(", "flags": "gi" },
|
|
2387
|
+
{ "pattern": "(?:syntheticContent|aiContent|generatedContent)", "flags": "gi" },
|
|
2388
|
+
{ "pattern": "(?:dall-e|stable-diffusion|midjourney|openai\\.images)", "flags": "gi" },
|
|
2389
|
+
{ "pattern": "(?:textToSpeech|voiceSynthesis|tts)\\.(?:generate|create|synthesize)", "flags": "gi" }
|
|
2390
|
+
],
|
|
2391
|
+
"fix_suggestion": "Add visible AI-generated content labels: include 'AI Generated' badge/watermark on all synthetic media shown to children.",
|
|
2392
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2393
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2394
|
+
"packs": ["eu-ai-act"],
|
|
2395
|
+
"fixability": "guided",
|
|
2396
|
+
"transform_type": null,
|
|
2397
|
+
"scaffold_id": null,
|
|
2398
|
+
"guidance_url": null
|
|
2399
|
+
},
|
|
2400
|
+
{
|
|
2401
|
+
"id": "AI-RISK-005",
|
|
2402
|
+
"name": "Automated Decision Without Human Appeal",
|
|
2403
|
+
"severity": "critical",
|
|
2404
|
+
"confidence": "medium",
|
|
2405
|
+
"category": "ai-risk",
|
|
2406
|
+
"description": "Automated decisions affecting children (bans, suspensions, access denial) must have a human appeal mechanism per EU AI Act Art. 14.",
|
|
2407
|
+
"patterns": [
|
|
2408
|
+
{ "pattern": "(?:banUser|suspendAccount|denyAccess|autoModerate|autoBan)\\(", "flags": "gi" },
|
|
2409
|
+
{ "pattern": "(?:blockUser|restrictUser|muteUser|shadowBan)\\(", "flags": "gi" },
|
|
2410
|
+
{ "pattern": "moderationAction:\\s*['\"](?:ban|suspend|restrict)['\"]", "flags": "gi" }
|
|
2411
|
+
],
|
|
2412
|
+
"fix_suggestion": "Add human appeal mechanism: implement an appeal/review endpoint and surface it in the moderation notification to the user.",
|
|
2413
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac35M or 7% of global annual turnover",
|
|
2414
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2415
|
+
"packs": ["eu-ai-act"],
|
|
2416
|
+
"fixability": "guided",
|
|
2417
|
+
"transform_type": null,
|
|
2418
|
+
"scaffold_id": null,
|
|
2419
|
+
"guidance_url": null
|
|
2420
|
+
},
|
|
2421
|
+
{
|
|
2422
|
+
"id": "AI-TRANSPARENCY-001",
|
|
2423
|
+
"name": "Missing AI Disclosure",
|
|
2424
|
+
"severity": "high",
|
|
2425
|
+
"confidence": "medium",
|
|
2426
|
+
"category": "ai-transparency",
|
|
2427
|
+
"description": "AI systems interacting with children must disclose they are AI per EU AI Act Art. 13. Chatbots, tutors, and assistants need visible AI disclosure.",
|
|
2428
|
+
"patterns": [
|
|
2429
|
+
{ "pattern": "(?:ChatBot|AIChatbot|VirtualAssistant|AITutor|ChatInterface)", "flags": "gi" },
|
|
2430
|
+
{ "pattern": "(?:createChatbot|initBot|botResponse|chatCompletion)\\(", "flags": "gi" },
|
|
2431
|
+
{ "pattern": "role:\\s*['\"](?:assistant|system|bot)['\"]", "flags": "gi" }
|
|
2432
|
+
],
|
|
2433
|
+
"fix_suggestion": "Add AI disclosure: show 'You are chatting with an AI' before first interaction and in the UI header.",
|
|
2434
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2435
|
+
"languages": ["typescript", "javascript", "python", "tsx", "jsx"],
|
|
2436
|
+
"packs": ["eu-ai-act"],
|
|
2437
|
+
"fixability": "guided",
|
|
2438
|
+
"transform_type": null,
|
|
2439
|
+
"scaffold_id": null,
|
|
2440
|
+
"guidance_url": null
|
|
2441
|
+
},
|
|
2442
|
+
{
|
|
2443
|
+
"id": "AI-TRANSPARENCY-002",
|
|
2444
|
+
"name": "No Training Data Disclosure",
|
|
2445
|
+
"severity": "medium",
|
|
2446
|
+
"confidence": "low",
|
|
2447
|
+
"category": "ai-transparency",
|
|
2448
|
+
"description": "High-risk AI systems must disclose training data sources per EU AI Act Art. 13. Children's AI products need model cards or equivalent documentation.",
|
|
2449
|
+
"patterns": [
|
|
2450
|
+
{ "pattern": "(?:loadModel|deployModel|serveModel)\\(", "flags": "gi" },
|
|
2451
|
+
{ "pattern": "(?:modelEndpoint|inferenceEndpoint|predictionService)", "flags": "gi" },
|
|
2452
|
+
{ "pattern": "(?:huggingface|openai|anthropic|cohere)\\.(?:create|complete|generate)", "flags": "gi" }
|
|
2453
|
+
],
|
|
2454
|
+
"fix_suggestion": "Create a model card documenting training data sources, intended use, limitations, and bias considerations.",
|
|
2455
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2456
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2457
|
+
"packs": ["eu-ai-act"],
|
|
2458
|
+
"fixability": "flag-only",
|
|
2459
|
+
"transform_type": null,
|
|
2460
|
+
"scaffold_id": null,
|
|
2461
|
+
"guidance_url": null
|
|
2462
|
+
},
|
|
2463
|
+
{
|
|
2464
|
+
"id": "AI-TRANSPARENCY-003",
|
|
2465
|
+
"name": "Algorithmic Decision Blackbox",
|
|
2466
|
+
"severity": "high",
|
|
2467
|
+
"confidence": "medium",
|
|
2468
|
+
"category": "ai-transparency",
|
|
2469
|
+
"description": "High-stakes decisions (content removal, access control) must have explainability mechanisms per EU AI Act Art. 13. Opaque automated decisions violate transparency requirements.",
|
|
2470
|
+
"patterns": [
|
|
2471
|
+
{ "pattern": "(?:moderateContent|flagContent|removeContent|hidePost)\\((?![^)]*reason)", "flags": "gi" },
|
|
2472
|
+
{ "pattern": "(?:filterContent|censorContent|suppressContent)\\(", "flags": "gi" },
|
|
2473
|
+
{ "pattern": "autoDecision\\((?![^)]*explain)", "flags": "gi" }
|
|
2474
|
+
],
|
|
2475
|
+
"fix_suggestion": "Add explainability: include a 'reason' parameter in automated decisions and surface it to affected users.",
|
|
2476
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2477
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2478
|
+
"packs": ["eu-ai-act"],
|
|
2479
|
+
"fixability": "guided",
|
|
2480
|
+
"transform_type": null,
|
|
2481
|
+
"scaffold_id": null,
|
|
2482
|
+
"guidance_url": null
|
|
2483
|
+
},
|
|
2484
|
+
{
|
|
2485
|
+
"id": "AI-TRANSPARENCY-004",
|
|
2486
|
+
"name": "Age-Based Personalization Not Disclosed",
|
|
2487
|
+
"severity": "medium",
|
|
2488
|
+
"confidence": "medium",
|
|
2489
|
+
"category": "ai-transparency",
|
|
2490
|
+
"description": "Personalized content that varies by age must disclose this to users per EU AI Act Art. 13. Children should know their experience is age-adapted.",
|
|
2491
|
+
"patterns": [
|
|
2492
|
+
{ "pattern": "(?:if|switch)\\s*\\([^)]*(?:age|userAge|childAge)\\s*[<>=]", "flags": "gi" },
|
|
2493
|
+
{ "pattern": "ageGroup:\\s*['\"](?:child|teen|minor|under13|under16)['\"]", "flags": "gi" },
|
|
2494
|
+
{ "pattern": "(?:ageFilter|ageGate|ageRestriction)\\([^)]*(?:content|feed|results)", "flags": "gi" }
|
|
2495
|
+
],
|
|
2496
|
+
"fix_suggestion": "Disclose age-based personalization: add a visible notice that 'Content is adapted for your age group' when age-specific filtering is active.",
|
|
2497
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2498
|
+
"languages": ["typescript", "javascript", "python", "tsx", "jsx"],
|
|
2499
|
+
"packs": ["eu-ai-act"],
|
|
2500
|
+
"fixability": "guided",
|
|
2501
|
+
"transform_type": null,
|
|
2502
|
+
"scaffold_id": null,
|
|
2503
|
+
"guidance_url": null
|
|
2504
|
+
},
|
|
2505
|
+
{
|
|
2506
|
+
"id": "AI-TRANSPARENCY-005",
|
|
2507
|
+
"name": "Missing AI Terms of Service",
|
|
2508
|
+
"severity": "medium",
|
|
2509
|
+
"confidence": "low",
|
|
2510
|
+
"category": "ai-transparency",
|
|
2511
|
+
"description": "AI-powered services for children need dedicated AI terms explaining capabilities, limitations, and data practices per EU AI Act Art. 13.",
|
|
2512
|
+
"patterns": [
|
|
2513
|
+
{ "pattern": "(?:aiService|aiFeature|mlService|aiEndpoint)\\.(?:init|start|enable)", "flags": "gi" },
|
|
2514
|
+
{ "pattern": "(?:enableAI|activateAI|aiPowered)\\s*[:=]\\s*true", "flags": "gi" },
|
|
2515
|
+
{ "pattern": "feature[Ff]lag.*['\"](?:ai|ml|chatbot|recommendation)['\"]", "flags": "gi" }
|
|
2516
|
+
],
|
|
2517
|
+
"fix_suggestion": "Add dedicated AI terms of service: create an /ai-terms page explaining how AI features work, their limitations, and child-specific protections.",
|
|
2518
|
+
"penalty": "EU AI Act Art. 99: Up to \u20ac15M or 3% of global annual turnover",
|
|
2519
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2520
|
+
"packs": ["eu-ai-act"],
|
|
2521
|
+
"fixability": "flag-only",
|
|
2522
|
+
"transform_type": null,
|
|
2523
|
+
"scaffold_id": null,
|
|
2524
|
+
"guidance_url": null
|
|
2525
|
+
},
|
|
2526
|
+
{
|
|
2527
|
+
"id": "CAI-PEDAGOGY-001",
|
|
2528
|
+
"name": "AI Tutor Bypass (Auto-Answering)",
|
|
2529
|
+
"severity": "medium",
|
|
2530
|
+
"confidence": "medium",
|
|
2531
|
+
"category": "constitutional-ai",
|
|
2532
|
+
"description": "Educational AI must scaffold learning, not provide direct answers. Auto-answering bypasses critical thinking development (Vygotsky's Zone of Proximal Development).",
|
|
2533
|
+
"patterns": [
|
|
2534
|
+
{ "pattern": "(?:getAnswer|solveQuestion|provideSolution|autoSolve)\\(", "flags": "gi" },
|
|
2535
|
+
{ "pattern": "(?:answerQuestion|generateAnswer|solveHomework)\\(", "flags": "gi" },
|
|
2536
|
+
{ "pattern": "(?:homeworkHelper|essayWriter|mathSolver)\\.(?:solve|answer|complete)", "flags": "gi" }
|
|
2537
|
+
],
|
|
2538
|
+
"fix_suggestion": "Replace auto-answering with scaffolded hints: provide progressive clues instead of complete solutions.",
|
|
2539
|
+
"penalty": "Constitutional AI Principle: Scaffolding Rule",
|
|
2540
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2541
|
+
"packs": ["eu-ai-act"],
|
|
2542
|
+
"fixability": "flag-only",
|
|
2543
|
+
"transform_type": null,
|
|
2544
|
+
"scaffold_id": null,
|
|
2545
|
+
"guidance_url": null
|
|
2546
|
+
},
|
|
2547
|
+
{
|
|
2548
|
+
"id": "CAI-DEPENDENCY-001",
|
|
2549
|
+
"name": "Emotional Over-Reliance Risk",
|
|
2550
|
+
"severity": "high",
|
|
2551
|
+
"confidence": "medium",
|
|
2552
|
+
"category": "constitutional-ai",
|
|
2553
|
+
"description": "AI companions/tutors must detect and mitigate emotional dependency in children. Extended interactions without disengagement prompts risk unhealthy attachment (IEEE 2089-2021).",
|
|
2554
|
+
"patterns": [
|
|
2555
|
+
{ "pattern": "(?:aiCompanion|virtualFriend|aiBuddy|chatCompanion)", "flags": "gi" },
|
|
2556
|
+
{ "pattern": "(?:emotionalSupport|moodTracker|feelings).*(?:ai|bot|assistant)", "flags": "gi" },
|
|
2557
|
+
{ "pattern": "(?:companionBot|friendBot|socialBot)\\.(?:init|create|start)", "flags": "gi" }
|
|
2558
|
+
],
|
|
2559
|
+
"fix_suggestion": "Add disengagement prompts: remind users to take breaks after extended sessions and suggest real-world activities.",
|
|
2560
|
+
"penalty": "Constitutional AI Principle: Anti-Dependency Clause (IEEE 2089-2021)",
|
|
2561
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2562
|
+
"packs": ["eu-ai-act"],
|
|
2563
|
+
"fixability": "flag-only",
|
|
2564
|
+
"transform_type": null,
|
|
2565
|
+
"scaffold_id": null,
|
|
2566
|
+
"guidance_url": null
|
|
2567
|
+
},
|
|
2568
|
+
{
|
|
2569
|
+
"id": "CAI-SYNTHESIS-001",
|
|
2570
|
+
"name": "Synthetic Content Without Child-Readable Labels",
|
|
2571
|
+
"severity": "medium",
|
|
2572
|
+
"confidence": "medium",
|
|
2573
|
+
"category": "constitutional-ai",
|
|
2574
|
+
"description": "AI-generated content shown to children must have labels comprehensible to the child's age group. Abstract disclaimers are insufficient — use visual indicators.",
|
|
2575
|
+
"patterns": [
|
|
2576
|
+
{ "pattern": "(?:generateForChild|childContent|kidsGenerate)\\(", "flags": "gi" },
|
|
2577
|
+
{ "pattern": "(?:aiStory|aiImage|aiVideo|generatedStory)(?![^\\n]*(?:label|badge|disclosure|watermark))", "flags": "gi" },
|
|
2578
|
+
{ "pattern": "(?:storyGenerator|imageGenerator|contentGenerator)\\.(?:create|generate)\\(", "flags": "gi" }
|
|
2579
|
+
],
|
|
2580
|
+
"fix_suggestion": "Add child-comprehensible AI labels: use emoji or visual badges (e.g., sparkle icon) instead of text-only 'AI Generated' disclaimers.",
|
|
2581
|
+
"penalty": "Constitutional AI Principle: Truth in Synthesis",
|
|
2582
|
+
"languages": ["typescript", "javascript", "python", "tsx", "jsx"],
|
|
2583
|
+
"packs": ["eu-ai-act"],
|
|
2584
|
+
"fixability": "flag-only",
|
|
2585
|
+
"transform_type": null,
|
|
2586
|
+
"scaffold_id": null,
|
|
2587
|
+
"guidance_url": null
|
|
2588
|
+
},
|
|
2589
|
+
{
|
|
2590
|
+
"id": "CAI-NUDGE-001",
|
|
2591
|
+
"name": "Engagement Optimization Without Disclosure",
|
|
2592
|
+
"severity": "high",
|
|
2593
|
+
"confidence": "medium",
|
|
2594
|
+
"category": "constitutional-ai",
|
|
2595
|
+
"description": "Algorithms optimizing for engagement/time-on-device in children's apps violate No-Nudge principles (IEEE 2089-2021). Must disclose engagement optimization and offer wellbeing modes.",
|
|
2596
|
+
"patterns": [
|
|
2597
|
+
{ "pattern": "optimizeFor:\\s*['\"](?:engagement|retention|timeOnApp|sessionDuration)['\"]", "flags": "gi" },
|
|
2598
|
+
{ "pattern": "(?:engagementScore|retentionMetric|dailyActiveMinutes|sessionLength)", "flags": "gi" },
|
|
2599
|
+
{ "pattern": "(?:maximizeEngagement|boostRetention|increaseTimeSpent)\\(", "flags": "gi" }
|
|
2600
|
+
],
|
|
2601
|
+
"fix_suggestion": "Disclose engagement optimization and add wellbeing features: implement screen time limits, usage dashboards, and 'take a break' reminders.",
|
|
2602
|
+
"penalty": "Constitutional AI Principle: No-Nudge Mandate (IEEE 2089-2021)",
|
|
2603
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2604
|
+
"packs": ["eu-ai-act"],
|
|
2605
|
+
"fixability": "flag-only",
|
|
2606
|
+
"transform_type": null,
|
|
2607
|
+
"scaffold_id": null,
|
|
2608
|
+
"guidance_url": null
|
|
2609
|
+
},
|
|
2610
|
+
{
|
|
2611
|
+
"id": "CAI-RESET-001",
|
|
2612
|
+
"name": "No User Identity Reset Mechanism",
|
|
2613
|
+
"severity": "medium",
|
|
2614
|
+
"confidence": "low",
|
|
2615
|
+
"category": "constitutional-ai",
|
|
2616
|
+
"description": "AI systems learning child preferences must offer periodic identity/preference reset capability. Children's interests change rapidly — stale profiles can create filter bubbles.",
|
|
2617
|
+
"patterns": [
|
|
2618
|
+
{ "pattern": "(?:userPreferences|learningProfile|interestProfile|userModel)\\.(?:save|persist|update)", "flags": "gi" },
|
|
2619
|
+
{ "pattern": "(?:personalizeFor|buildProfile|profileLearning)\\(", "flags": "gi" },
|
|
2620
|
+
{ "pattern": "(?:recommendationProfile|contentPreferences)\\.(?:set|update)", "flags": "gi" }
|
|
2621
|
+
],
|
|
2622
|
+
"fix_suggestion": "Add identity reset capability: implement 'Reset My Preferences' option and offer periodic 'Would you like to refresh your interests?' prompts.",
|
|
2623
|
+
"penalty": "Constitutional AI Principle: Right to Reset",
|
|
2624
|
+
"languages": ["typescript", "javascript", "python"],
|
|
2625
|
+
"packs": ["eu-ai-act"],
|
|
2626
|
+
"fixability": "flag-only",
|
|
2627
|
+
"transform_type": null,
|
|
2628
|
+
"scaffold_id": null,
|
|
2629
|
+
"guidance_url": null
|
|
1003
2630
|
}
|
|
1004
2631
|
]
|
|
1005
2632
|
}
|