cookie-auditor
Skill20 starsChanged 10 months agoMITView on GitHub
Audit web pages for GDPR and CCPA cookie consent compliance. Start with a clean browser state: Before any interaction, record what cookies are set: Classify cookies by purpose: Look for cookie consent elements: Check consent UI for compliance: Accept Button Detection: Reject Button Detection: Preference Detection: Load criteria from criteria.json:
In this repository13 other files it gives its agents.
- ab-testingSkill
- critical-pathsSkill
- form-fuzzerSkill
- github-prSkill
- link-checkerSkill
- network-throttlingSkill
- persona-generatorSkill
- screenshot-annotatorSkill
- session-recorderSkill
- smoke-testingSkill
- stripe-checkoutSkill
- user-testingSkill
- wcag-auditorSkill
The file
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 11 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 17
Start with a clean browser state:
- Distinctive: line 37
Before any interaction, record what cookies are set:
- Distinctive: line 67
Look for cookie consent elements:
- Distinctive: line 85
Check consent UI for compliance:
- Distinctive: line 272
Detection: Check cookies before any user interaction
- Distinctive: line 279
Fix: Default all non-essential to unchecked
- Distinctive: line 290
Detection: Search footer/privacy areas
- Distinctive: line 291
Fix: Add compliant opt-out link
- Distinctive: line 295
Test Fresh Sessions: Always clear cookies before audit
- Distinctive: line 298
Deep Pages: Check if consent persists across navigation
- Distinctive: line 299
Screenshots: Document violations with annotated screenshots
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Cookie Auditor Skill
Audit web pages for GDPR and CCPA cookie consent compliance.
When to Use
- Verifying GDPR compliance before EU launch
- Checking CCPA compliance for California users
- Pre-deployment privacy compliance checks
- Auditing third-party vendors' consent implementation
- CI/CD compliance gates
Audit Approach
Phase 1: Fresh Session Setup
Start with a clean browser state:
// Via browser_run_code
async (page) => {
// Clear all cookies
await page.context().clearCookies();
// Clear local storage
await page.evaluate(() => {
localStorage.clear();
sessionStorage.clear();
});
return 'Session cleared';
}Phase 2: Pre-Consent Cookie Capture
Before any interaction, record what cookies are set:
async (page) => {
const cookies = await page.context().cookies();
return cookies.map(c => ({
name: c.name,
domain: c.domain,
path: c.path,
expires: c.expires,
httpOnly: c.httpOnly,
secure: c.secure,
sameSite: c.sameSite
}));
}Phase 3: Cookie Classification
Classify cookies by purpose:
| Pattern | Category | Essential |
session, csrf, auth | Necessary | Yes |
_ga, _gid, analytics | Analytics | No |
_fbp, _gcl, ads | Marketing | No |
prefs, theme, lang | Personalization | No |
Phase 4: Banner Detection
Look for cookie consent elements:
// Common selectors for cookie banners
const bannerSelectors = [
'[class*="cookie"]',
'[id*="cookie"]',
'[class*="consent"]',
'[id*="consent"]',
'[class*="gdpr"]',
'[class*="privacy-banner"]',
'[aria-label*="cookie"]',
'[role="dialog"][class*="modal"]'
];Phase 5: Consent Mechanism Analysis
Check consent UI for compliance:
Accept Button Detection:
const acceptSelectors = [
'button:has-text("Accept")',
'button:has-text("Allow")',
'button:has-text("Agree")',
'button:has-text("OK")',
'[class*="accept"]'
];Reject Button Detection:
const rejectSelectors = [
'button:has-text("Reject")',
'button:has-text("Decline")',
'button:has-text("Deny")',
'a:has-text("Reject")',
'[class*="reject"]',
'[class*="decline"]'
];Preference Detection:
const preferenceSelectors = [
'button:has-text("Settings")',
'button:has-text("Preferences")',
'button:has-text("Manage")',
'button:has-text("Customize")'
];GDPR Criteria Reference
Load criteria from criteria.json:
| ID | Criterion | Severity | Check Method |
| GDPR-1 | Banner before cookies | Critical | Pre-consent cookie check |
| GDPR-2 | No pre-checked boxes | Critical | Checkbox state analysis |
| GDPR-3 | Reject option prominent | Major | Button comparison |
| GDPR-4 | Granular consent | Major | Category options check |
| GDPR-5 | Withdrawal mechanism | Major | Settings accessibility |
| GDPR-6 | Cookie policy link | Minor | Link presence check |
CCPA Criteria Reference
| ID | Criterion | Severity | Check Method |
| CCPA-1 | Do Not Sell link | Critical | Footer link search |
| CCPA-2 | Opt-out mechanism | Critical | Functional test |
| CCPA-3 | Privacy policy | Major | Link presence check |
| CCPA-4 | Rights disclosure | Minor | Content analysis |
Detection Methods
Pre-Checked Box Detection
async (page) => {
const checkboxes = await page.$$('input[type="checkbox"]');
const preChecked = [];
for (const checkbox of checkboxes) {
const isChecked = await checkbox.isChecked();
const label = await checkbox.evaluate(el => {
const label = el.closest('label') ||
document.querySelector(`label[for="${el.id}"]`);
return label?.textContent || '';
});
if (isChecked && !isNecessary(label)) {
preChecked.push({ label, checked: true });
}
}
return preChecked;
}Button Prominence Comparison
async (page) => {
const accept = await page.$('button:has-text("Accept")');
const reject = await page.$('button:has-text("Reject")');
if (!accept || !reject) return { prominent: false, reason: 'Missing button' };
const acceptBox = await accept.boundingBox();
const rejectBox = await reject.boundingBox();
// Compare sizes
const acceptArea = acceptBox.width * acceptBox.height;
const rejectArea = rejectBox.width * rejectBox.height;
// Reject should be at least 50% the size of accept
return {
prominent: rejectArea >= acceptArea * 0.5,
acceptSize: acceptArea,
rejectSize: rejectArea
};
}CCPA Link Detection
async (page) => {
const ccpaPatterns = [
'Do Not Sell',
'Do Not Share',
'Opt-Out',
'Your Privacy Choices',
'Your California Privacy Rights'
];
for (const pattern of ccpaPatterns) {
const link = await page.$(`a:has-text("${pattern}")`);
if (link) {
return { found: true, text: pattern };
}
}
return { found: false };
}Scoring
function calculateScore(results) {
const weights = {
critical: 3,
major: 2,
minor: 1
};
let maxScore = 0;
let actualScore = 0;
for (const result of results) {
const weight = weights[result.severity];
maxScore += weight;
if (result.status === 'pass') {
actualScore += weight;
}
}
const percentage = Math.round((actualScore / maxScore) * 100);
const grade =
percentage >= 90 ? 'A' :
percentage >= 80 ? 'B' :
percentage >= 70 ? 'C' :
percentage >= 60 ? 'D' : 'F';
return { percentage, grade };
}Report Generation
Issue Format
### FAIL: [ID] - [Title]
- **Severity**: [Critical/Major/Minor]
- **Finding**: [What was observed]
- **Location**: [Where on the page]
- **Fix**: [Remediation guidance]Pass Format
### PASS: [ID] - [Title]
- **Finding**: [What was observed that indicates compliance]Common Violations
1. Analytics Before Consent
Pattern: Google Analytics (_ga, _gid) cookies set on page load Detection: Check cookies before any user interaction Fix: Defer analytics until after consent
2. Pre-Checked Marketing
Pattern: "Marketing cookies" checkbox checked by default Detection: Inspect checkbox state in banner Fix: Default all non-essential to unchecked
3. Hidden Reject Option
Pattern: "Reject" is a small link, "Accept" is a large button Detection: Compare element sizes Fix: Make both options equally prominent
4. Missing CCPA Link
Pattern: No "Do Not Sell" link on California-targeted site Detection: Search footer/privacy areas Fix: Add compliant opt-out link
Best Practices
- Test Fresh Sessions: Always clear cookies before audit
- Geo-Simulation: Some banners only show to EU/CA visitors
- Mobile Check: Banner behavior may differ on mobile
- Deep Pages: Check if consent persists across navigation
- Screenshots: Document violations with annotated screenshots
Limitations
- Geo-Targeting: Banner may not appear without EU/CA IP
- A/B Tests: Different users may see different consent UIs
- Dynamic Loading: Some consent tools load asynchronously
- Third-Party Tools: Complex consent managers may need special handling
- Legal Interpretation: This tool checks technical compliance, not legal advice
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

