Deporia
Media aporia no more!
Deporia is a web extension intended for the non-tech savvy that identifies AI-generated pictures. Users see a simple red or green border on all loaded images.
Why?
Even the most hardened whiskey-drinking detectives can't always figure out when media is AI-manipulated. Our project leverages the fact that the crowd is often better at making a judgement call than anybody alone. Anybody can submit a report if a piece of media is AI-generated/manipulated or human-generated.
Static demo (must have extension installed to see borders)
AI-manipulated image

Safe, human-generated image

Screenshots
If you haven't installed the extension, here are some examples of what an annotated website will look like:



Inspiration
We were inspired by the following crowdsourced safety solutions:
What it does
- Users vote "trust" or "distrust" on flagged images by right clicking on images
- Displays the current "trustworthiness" of an image with a colored border ranging from red to green
- Requires very little effort
- This was a key design goal, since we realized that >85% of people were not going to want to jump through hoops
- Keeping the design as accessible as possible will enable more people to be aware of if media they consume is AI-generated or not
How we built it
- Frontend: Browser extension (JS, WebExtension API, & Firefox)
- Backend: FastAPI with async endpoints, hosted on Vultr and brought up with a systemd unit
- Storage: Valkey for fast key-value lookups
You can try out the project by downloading the extension from our GitHub repository.
Challenges we ran into
- Couldn't get a
.techdomain, even through GitHub Student Pack; We pivoted into using ngrok which required custom headers on every request.- This was an issue since we used the
crypto.subtleWeb APIs for hashing, which require the site to be loaded in an HTTPS context. - Let's Encrypt and other services could have let us get a TLS certificate on the
.techdomain quickly. We had preferred running Fedora on the VPS, but since Certbot is primarily distributed as a snap we instead chose Ubuntu - We would have loved
deporia.techif.techhad been working: short & easy to pronounce
- This was an issue since we used the
- Vultr took a while to setup, but once setup it worked well
- When we tried all hitting the server at once, it was possible to get the server to write invalid reputations to the database.
- We fixed the race condition with thread-safe updates provided by
aiorwlockto do R/W locking that let us keep speed high.
- We fixed the race condition with thread-safe updates provided by
- SHA256 hash matching requires exact pixel match - minor edits/reencoding create new hashes.
- CORS (Cross-origin resource sharing) made it difficult for our extension to get images out of webpages
- We had to do some deep dives into Browser API documentation to learn why we were experiencing the errors we were, and what we needed to do instead
- Final solution works reliably, but it took a good chunk of our devtime
Accomplishments that we're proud of
- Built a working crowdsourced reputation system in 24 hours
- Clean async API in Python with proper concurrency control
- Making use of the Valkey and Vultr tracks organically rather than simply shoving them in for extra points
- Very simple and low-cognitive-load UI
- Made our first WebExtension
- We made minimal use of LLMs in our dev process
- We used Claude primarily as a "souped-up search engine"
- Paraphrasing sample code snippets ourselves rather than blind vibe coding left us with a much better understanding of what our code did and why web architecture is structured the way it currently is
- Collaborated effectively with Git & a GitHub repository
What we learned
- Valkey was a good pick for this use case
- Fast + simple = nothing better
- Let us focus on the important parts rather than how data would be stored, if we had used a relational DB we would have spent more time worrying about how to store data and what to store
- Crowdsourcing works but needs critical mass of users
- We believe that since "early adopters" tend to be more technical, they tend to be better at identifiying AI-manipulated images too
- This will help bootstrap our project with good quality ratings early on
- Whenever the extension sees an image for the first time, it marks it as "somewhat trustworthy" which may cause a user to put trust into a publication that is manipulated
- Hash-based identification is fast but brittle to image edits
- We had planned to re-encode all images to JPEG before hashing, but the lossy compression behaved a little different on every computer and didn't produce the same hash
What's next for Deporia
- Perceptual hashing (one solution is called pHash) to catch edited versions of same image or same image in different encoding
- We want to keep image hashing client-side for privacy, but this also makes spoofing easier
- TPM/Attestation solution could work, but browser APIs aren't available broadly yet
- Video / Audio flagging
- ML model to provide initial reputation score before community votes, currently it starts out at a flat "70%" or "somewhat trustworthy"
- Alternatively, we could also choose to abstain from showing a rating until enough people have rated the image
- This is how some of our inspirations (notably Google Safe Browsing) work
- Better spoofing detection to prevent reputation manipulation, currently just a simple rate-limit
- Publishing & on Chrome extension store to reach more users through organic sharing
- Accessibility-friendly way to share reputation rating
- Currently we just attach an aria label to each image we modify
- None of us personally use screen readers, so we would like to get in contact with someone who does to learn what works best for them
Built With
- javascript
- python
- valkey
- vultr
- webextensions
Log in or sign up for Devpost to join the conversation.