Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Automated Dark Pattern Detector

A web-based tool that utilizes Azure Foundry Tools and Azure AI Content Understanding to indentify hidden dark patterns in websites.


What are "Dark Patterns" ?

Dark patterns are design strategies intentionally crafted to manipulate users into actions they might not otherwise take. These actions typically favor business goals over user autonomy, clarity, or consent. They rely on deceptive UI choices, emotional pressure, or forced decisions making it difficult for users to make informed or voluntary choices.


Why Does it matter ?

Ethically, dark patterns are dishonest. They are often driven by marketing and sales pressures, reusing psychological tactics that may improve short-term metrics but damage long-term trust. From a user’s perspective, these patterns feel invasive, manipulative, and exhausting — pushing people to abandon flows, products, or even entire brands.


What this system does:

You give it a website address. It opens the site in a real browser, clicks through the cookie banner the way a visitor would, and tells you which manipulative design tricks it found — and which GDPR article each one breaks.

Current features

  • Explores the consent flow on its own. Clicks Accept, Reject, Manage, opens preference panels, and follows the flow through nested screens — including panels that only appear after a click.
  • Detects 14 dark patterns, each mapped to the GDPR article it puts at risk — pre-ticked tracking, a hidden reject button, a maze of screens to refuse, buttons that do nothing, no way to withdraw consent, and more.
  • Measures the page, doesn't guess. Colour contrast, font size and button area are read from the live web page, so a claim like "the reject link is 1.9:1 contrast" is a measurement, not an AI opinion.
  • Points at the evidence. Every finding highlights the exact button on a screenshot of the real page.
  • Shows the full consent flow as a map, so you can see how many clicks accepting takes versus refusing.
  • Reports nothing when there is nothing to report. A clean site returns an empty result rather than an invented one.
  • Protects itself from the sites it audits. A page cannot hide instructions in its text or images to talk the AI out of reporting it.
  • Shareable reports. Each completed scan gets its own link.

Findings are advisory, not legal advice.


Screenshots

Main Screen
Main_Screen

Report
reports_page


How it works

target URL → crawl → prune → Content Understanding → Prompt Shields → agent → report
  1. Target URL — you submit a website address in the web app.
  2. Crawl — a real browser opens the site with no saved cookies and clicks through every consent choice it can find, saving a screenshot of each screen it reaches.
  3. Prune — most of what a page contains is irrelevant. Only the screens where a real decision happens are kept, which keeps the AI cost down.
  4. Content Understanding — reads each saved screenshot and returns the text on it plus the position of every button and toggle.
  5. Prompt Shields — checks the website's own words for hidden instructions aimed at the AI, before the AI ever sees them.
  6. Agent — weighs the measurements against fixed rules and decides which dark patterns are actually proven.
  7. Report — the findings, each with its GDPR article and the exact button highlighted on the screenshot.

Repository layout

azure/     Configuration and prompts used for azure tools.    
backend/      Python + FastAPI
  app/        API, crawler, Azure pipeline
  playbooks/  Cookie banner selectors
  tests/      Offline test suite
frontend/   React + Typescript
test-run/   sample test run reports 

Quick start

1. Local development

You need Python 3.11+, Node 20+, and the Azure CLI. Sign in first with az login — the app uses that login to reach Azure.

Backend (first terminal):

cd backend
python3 -m venv .venv           # create a virtual environment
source .venv/bin/activate       # switch into it
pip install -r requirements.txt # install Python packages
playwright install chromium     # download the browser it drives
cp .env.example .env            # then fill in your Azure values (see below)
uvicorn app.main:app --port 8000

Frontend (second terminal):

cd frontend
npm install
npm run dev

Open http://localhost:5173.

Or run everything in Docker instead:

docker compose up --build       # then open http://localhost:8080

Containers cannot use your az login. To run this way, add AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_CLIENT_SECRET for a service principal to backend/.env. For everyday work the two-terminal setup above is simpler.

Create the service principal with:

az ad sp create-for-rbac --name dark-pattern-detector-local

Then give it the same roles listed under Azure setup below. The roles must be assigned on every resource group involved — the AI resources and the storage account may live in different ones, and a scan fails at the first call into whichever group was missed.


2. Azure setup

Six Azure resources are needed. Create them in the portal, then give the app permission to use them.

Create this What it does here
Azure AI Foundry project Hosts the GPT agent that decides what counts as a dark pattern
Azure AI Content Understanding Reads the screenshots and finds where each button sits
Azure AI Content Safety Blocks hidden instructions planted by the audited site
Storage account (1 blob container + 1 table) Stores screenshots and reports, and tracks scan progress
Azure AI Search Index of GDPR and EU DSA articles the agent searches to confirm a citation
Application Insights (optional) Times each scan stage and records errors
Key Vault (optional) Fallback for local runs if you cannot grant storage permissions

Then set up the two AI tools. Neither is created by code — you configure them in their portals using the files in the azure/ folder, which explains each one in detail:

Tool Paste this file into the portal Then put the ID in
Content Understanding analyzer azure/consent-surface-analyzer.json AZURE_CU_ANALYZER_ID
Foundry agent azure/agent-instructions.md and azure/agent-output-schema.json AZURE_FOUNDRY_AGENT_ID

The agent also has an azure_ai_search tool over an index of the GDPR and EU DSA articles. It is attached in the portal, and used only to confirm which article a proven finding cites — never to decide that a finding exists.

Finally, grant permissions. The app signs in as itself rather than using API keys, so each resource needs a role assigned to it:

On this resource Give it this role
Storage account Storage Blob Data Contributor
Storage account Storage Table Data Contributor
Foundry project Azure AI User
Content Understanding Cognitive Services User
Azure AI Search Search Index Data Reader
Key Vault (only if using the fallback) Key Vault Secrets User

Leaving AZURE_STORAGE_ACCOUNT_NAME blank switches storage to the Key Vault fallback, which then needs the Key Vault role as well. Filling it in is the simpler path.


3. Evaluation and monitoring

How good are the findings? Score a finished scan with the built-in Azure evaluators:

pip install -r requirements-eval.txt
python -m evaluation.evaluate <run_id>

Each finding gets two scores out of 5. Groundedness — is the reasoning backed by the evidence the agent was given? Relevance — does the proof answer the question? Results land in backend/evaluation/RESULTS.md, one row per scan, tagged with the agent version. The judge is a language model too, so it scores the same finding differently each time. Each is scored three times and averaged, and every row shows a Spread — the gap between the highest and lowest verdict. At 1.0 or above, ignore that row. Compare groundedness across agent versions, never one row on its own.

Run it after editing azure/agent-instructions.md to check a prompt change actually helped. It re-scores a stored scan, so it costs a fraction of an audit and needs no new crawl.


4. Model

This project uses GPT-5.4-mini deployed at 50,000 TPM (tokens per minute).

Any comparable low-tier reasoning model works just as well — the agent's behaviour comes from its instructions, not the model. See azure/agent-instructions.md for exactly what the agent is told to do.

The 50k TPM is not optional. One audit sends about 28,000 tokens in a single request. On a smaller deployment that one request is bigger than the entire per-minute allowance, so Azure rejects it immediately — and it keeps rejecting everything, even a one-word test message, which looks like a rate limit that never clears. Raising the limit costs nothing extra: you are billed for tokens you actually use, not for the size of the allowance.


5. Local Environment Configuration

backend/.env — copy .env.example and fill it in.

Variable What it is
FOUNDRY_PROJECT_ENDPOINT Address of your Foundry project, ending in /api/projects/<project>
AZURE_FOUNDRY_AGENT_ID Name and version of the agent, e.g. dark-pattern-auditor:5
CONTENT_UNDERSTANDING_ENDPOINT Address of your Content Understanding resource
AZURE_CU_ANALYZER_ID Name you gave the analyzer when creating it
CONTENT_SAFETY_ENDPOINT Address of your Content Safety resource, used for Prompt Shields
AZURE_STORAGE_ACCOUNT_NAME Storage account name. Filled in = sign in as the app; left blank = use the Key Vault fallback
AZURE_BLOB_CONTAINER Container that holds screenshots and reports
AZURE_TABLE_NAME Table that tracks whether a scan is running or finished
AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_CLIENT_SECRET Service principal, only needed to run the backend in Docker. Set all three or none
APPLICATIONINSIGHTS_CONNECTION_STRING Application Insights. Blank turns telemetry off
AZURE_KEY_VAULT_URL Key Vault address, only for the local fallback
STORAGE_CONNECTION_STRING_SECRET Name of the secret in Key Vault holding the storage connection string
MAX_STATES Most screens one crawl may visit
MAX_DEPTH How many clicks deep the crawl may go
WALL_CLOCK_BUDGET_SECONDS Time limit for a single crawl
MAX_ANALYZED_STATES Screens sent to Azure AI — the main lever on cost per scan

Future improvements

  • Bounding-box accuracy metric — measure how closely each returned box matches the element actually measured.
  • Non-English consent vocabulary — recognise German, French, Spanish and Italian banners, not just English ones.
  • Verify consent is actually honoured — compare cookies before and after clicking Reject, and flag trackers set anyway.
  • Nagging / Continuous Prompting — revisit a site over several days to catch banners that keep reappearing.
  • Multi-step cancellation and unsubscribe flows — audit account-closure journeys, not just cookie consent.
  • Mobile viewport auditing — run a second pass at phone size, where consent UI is often worse.
  • Pay-or-consent walls — treat "accept tracking or subscribe" as its own pattern with its own evidence rules.
  • Scan history and run comparison — list past audits and diff two runs of the same site to see what changed.
  • Scheduled monitoring — re-audit a set of sites on a schedule and alert on new findings.
  • Report improvements — add an executive summary page, the consent-flow graph, and a JSON export.
  • Deploy to Azure Container Apps — run the written deployment pipeline against live infrastructure.
  • Durable scan execution — move scans to a queue so a restart cannot abandon one mid-run.
  • Cache Content Understanding results — skip re-analysing screens that have not changed.

How to Contribute and Report Issues

Contributions are welcome! If you want to contribute, please follow these steps:

  • Fork the Repository: Create your own branch from main.
  • Create a Feature Branch: git checkout -b feature/AmazingFeature
  • Commit your Changes: Write clear commit messages.
  • Push to the Branch: git push origin feature/AmazingFeature
  • Open a Pull Request: Describe the changes you made and the problem they solve.

Reporting Issues

If you find a bug or have a feature request, please use the GitHub Issues tab. Include the following in your report:

  • A clear title.
  • Steps to reproduce the bug.
  • Expected vs. actual behavior.
  • Screenshots or error logs if you have them.

About

A web-based tool that utilizes Azure Foundry Tools and Azure AI Content Understanding to indentify hidden dark patterns in websites.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages