惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
Google DeepMind News
Google DeepMind News
罗磊的独立博客
Martin Fowler
Martin Fowler
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
Last Week in AI
Last Week in AI
The GitHub Blog
The GitHub Blog
B
Blog
C
Check Point Blog
WordPress大学
WordPress大学
G
Google Developers Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
量子位
月光博客
月光博客
U
Unit 42
Engineering at Meta
Engineering at Meta
有赞技术团队
有赞技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 【当耐特】
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Jina AI
Jina AI
S
Secure Thoughts
aimingoo的专栏
aimingoo的专栏
D
Darknet – Hacking Tools, Hacker News & Cyber Security
I
Intezer
Latest news
Latest news
V
Vulnerabilities – Threatpost
D
Docker
Attack and Defense Labs
Attack and Defense Labs
Help Net Security
Help Net Security
S
Security @ Cisco Blogs
Forbes - Security
Forbes - Security
MongoDB | Blog
MongoDB | Blog
云风的 BLOG
云风的 BLOG
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
Cloudbric
Cloudbric
Spread Privacy
Spread Privacy

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
I Audited My Own Open-Source Project With 26 AI Agents (and Found a Real Vulnerability)
Odilon HUGONNOT · 2026-05-29 · via DEV Community

ShareBox is my self-hosted streaming server: a PHP thing I built because I just wanted to send someone a link to a movie without installing Plex and its ten gigabytes of dependencies. It runs on my seedbox, serves my users, and one morning I notice it's starting to pick up a few stars on GitHub.

And then, that little voice: "does this thing actually hold up?" Because between "works on my machine" and "code that strangers are going to install on their own box," there's a chasm. A chasm full of flaws I can't see anymore, because I've had my nose in it for weeks.

Normally, you re-read your code. Except re-reading 22,000 lines alone, honestly, you do it badly: you skim over what you think you already know. So I tried something else — unleashing a pack of 26 AI agents on it, each with a precise mission, and seeing what surfaced. Spoiler: they found a flaw that had been sitting right under my eyes from the start.

26 agents to comb through my own code

The idea wasn't "AI, tell me if my code is good" — that always produces the same encouraging, useless mush. The idea was to orchestrate: split the audit into roles, run the agents in parallel, then have a final, deliberately harsh agent tear apart the conclusions.

The pipeline looked like this: eleven readers start in parallel, each swallowing an entire slice of the code (the core, the streaming handlers, the API, the front end, the tests, the Docker setup…). Their reports flow up into an architecture synthesis and a test-coverage analysis. Then twelve "radar" agents each score one single axis — security, performance, architecture, tests… And finally, a "verdict" agent re-reads every score in adversarial mode: its job is to knock down the ones that are too kind.

Audit pipeline: 11 readers in parallel, then synthesis, then 12 radar agents, then an adversarial verdict. 11 readers in parallel each slice of the code read in full Architecture + coverage synthesis connect the pieces, measure the gaps 12 radar agents one agent = one scored axis Adversarial verdict knocks down kind scores → final score + roadmap

The pipeline: read in parallel, connect, score axis by axis, then have it all torn apart by a deliberately harsh final agent.

The verdict came in: 5.04 out of 10. Deliberately harsh calibration — the final agent was told to score like a demanding staff engineer, keeping in mind that "a few-weeks-old PHP media server is not Jellyfin." It stings in the moment. But a low, well-argued score is worth a thousand complacent "great project!"s.

The flaw that was right under my eyes

The moment that justifies the whole exercise on its own: one of the security agents flags the Docker startup script. My entrypoint.sh generates config.php from environment variables. And right above it sat a comment, in my own hand: "Sanitize strings to prevent PHP injection."

Except the sanitization only covered strings. Three numeric/boolean variables were interpolated raw into the generated PHP file:

define('STREAM_MAX_CONCURRENT', ${MAX_CONCURRENT});

Enter fullscreen mode Exit fullscreen mode

Translation: if someone deploys the container with an environment variable like:

SHAREBOX_STREAM_MAX_CONCURRENT='1);system($_GET[x]);//'

Enter fullscreen mode Exit fullscreen mode

…then the generated config.php contains executable PHP. Arbitrary code execution, in the config file, right under a comment that claimed to prevent it. The kind of thing you stop seeing because you wrote it yourself and you trust it.

Warning — always verify the agents. Before taking the agent's word for it, I went and re-read the source myself. That's the golden rule: an agent that says "vulnerability confirmed" can be wrong, and so can one that says "all good." Here the flaw was real. The fix: validate that these variables really are integers (or true|false) before writing them, otherwise fall back to a safe value.

Along the way, the audit also flagged write endpoints (TMDB poster management) reachable by anyone holding a public link, an unbounded ZIP export that could monopolize the server, and a database backup triggered on every web request. Seven "quick win" fixes in total — each verified in a real Docker container with an end-to-end test suite before touching production.

When my own fix introduced a bug

Here's the most instructive moment, and the most humbling. After applying my seven fixes, I ran another agent cycle — this time to re-score and hunt for regressions. And one of them found a bug. In my fix.

By moving the database backup out of the web request (good idea), I'd wired it onto container startup. But that code runs as root, and SQLite in WAL mode creates side files (-wal, -shm). The result: on restart over an already-populated volume, those files were owned by root, and the web server (running as www-data) could no longer write to the database. A fix that works on first launch and breaks on the second. The worst kind of bug.

No rushed human re-runs a full audit right after "finishing." That's exactly where the agent pack wins: it doesn't get tired, it doesn't congratulate itself, it re-reads the diff with the same cold rigor the second time as the first. Bug fixed, re-tested on restart, and this time for real.

Tests that read the code vs. tests that run it

The other slap from the audit landed on my tests. I had hundreds of them, I was proud of my little green badge. Except an agent put its finger on a comfortable lie: a large chunk of those tests read the source code and checked that a string was present in it — instead of running the code and checking its behavior.

// What the test did (reading the source):
$source = file_get_contents('functions.php');
$this->assertStringContainsString('aresample=async=1', $source);

// What a real test does (execution):
$args = buildFilterGraph(720, 0, burnSub: 2);
$this->assertStringContainsString('overlay', $args); // the filter is ACTUALLY built

Enter fullscreen mode Exit fullscreen mode

The difference is huge. The first test stays green even if the function is broken, as long as the string is lying around somewhere in the file. It's fake coverage. The code that actually serves a file's bytes (HTTP Range handling, the heart of a streaming server) was never executed in a test.

So I converted the critical paths into real execution tests: an ephemeral PHP server that serves a file and checks the 206 Partial Content responses byte by byte, real calls to the ffmpeg command builders, the security gate tested over real HTTP. The "E2E coverage" axis went from 3 to 5 on the radar — the biggest jump of the whole exercise, and the most deserved.

The audit's best advice: don't follow it all the way

By the end, the score had climbed from 5.04 to 5.72. And the natural urge is to keep climbing. The verdict clearly pointed at the ceiling: two monolithic files of ~2,300 lines each, mixing routing, auth, business logic and views. The "textbook" answer: split it all up, introduce a router, controllers, namespaces.

And there, the final agent did something I didn't expect from an audit: it advised me not to.

A good audit also tells you what NOT to do. Rewriting 4,700 lines of procedural code that works, whose core (the ffmpeg pipeline) isn't even covered by execution tests, for a solo open-source project: weeks of work, a huge regression risk, and zero added value for the user. The risk/value ratio is bad. Keeping a deliberate procedural architecture is a defensible choice.

Instead, the highest-leverage move was invisible and risk-free: extend static analysis (PHPStan) to those never-analyzed big files, freezing the existing debt in a baseline. Result: ~4,700 of the riskiest lines are now under a net — any new regression fails CI, without forcing me to clean everything up today. Five minutes of config beat three weeks of rewrite.

What to take away

The agent pack didn't "audit in my place." It did what a lone human does badly: actually read every line, no skimming, no author's blind spot, in parallel, and start over after the fixes without getting bored. It found a real vulnerability, exposed fake test coverage, and even caught a bug in my own fix.

But at no point did it decide for me. I'm the one who verified the flaw in the source before believing it. I'm the one who decided one fix deserved a deploy and another deserved to wait. And it was the adversarial agent, not the complacent one, that produced the real value — by scoring harshly, and by saying "stop, don't overdo it."

The real win isn't the rising score. It's knowing, with numbers to back it, where the debt is, which part is worth repaying, and — the hardest thing for a developer — which part you should accept and leave alone.