{"slug": "what-i-learned-auditing-an-open-source-ai-memory-sdk-and-the-bug-i-found-in-it", "title": "What I learned auditing an open-source AI-memory SDK (and the bug I found in it)", "summary": "A developer auditing the open-source MemWal (Walrus Memory) SDK, which provides persistent cross-session memory for AI agents, found an authorization bug in a sample chatbot app's vote endpoint: the existence check was scoped only by messageId while the update was scoped by messageId and chatId, letting any logged-in user silently block another user's vote on a public message with a 200 response and no error. The maintainers confirmed and shipped a fix within days by scoping the existence check the same way as the update, and the developer also found a sibling login-flow app missing an on-chain verification step its near-identical twin performed.", "body_md": "Most chatbots forget everything the moment a conversation ends. I spent \n\na few days digging into an open-source project (MemWal / Walrus Memory) \n\nthat tries to fix that — persistent, cross-session memory for AI agents \n\n— and ended up doing a full security review of the codebase along the \n\nway. Here's what actually stood out.\n\n**## The interesting part wasn't the AI**\n\nEveryone talks about embeddings and semantic recall when they talk about \n\n\"AI memory.\" The part that actually breaks in production is much more \n\nboring: **ownership checks**.\n\nAny system where User A's data must never leak into User B's session \n\nlives or dies on a handful of `WHERE user_id = ?` clauses. Get one of \n\nthem wrong, and no amount of good embedding quality saves you.\n\n**## The bug**\n\nWhile reviewing a sample chatbot app built on this SDK, I found a vote \n\nendpoint with a subtle but real bug:\n\n`messageId`.` UPDATE` was scoped by `messageId AND chatId`.\nAny user who could see a message in a public chat (message IDs are \n\nrendered right in the UI) could submit a vote using **their own** chat \n\nID but a **stranger's** message ID. Since no vote existed yet for that \n\nmessage, it silently inserted a mismatched row.\n\nThe nasty part: the *next* time the actual message owner tried to vote \n\non their own message, the lookup found the attacker's row (again, \n\nscoped only by `messageId`), the `UPDATE` matched zero rows because the \n\n`chatId` didn't match, and the API returned `200 \"Message voted\"` — \n\nwhile silently doing nothing. The real owner could never vote on that \n\nmessage again, and had no way of knowing why.\n\nZero errors thrown. Zero logs. Just a permanently broken feature for \n\none specific user, triggered by any other logged-in user.\n\nI filed it, the maintainers confirmed and shipped a fix within days: \n\nscope the existence check the same way as the update.\n\n**## The bigger lesson**\n\nThe core SDK, the auth layer, the on-chain contract — all of it was \n\nextremely well hardened. Constant-time comparisons, quarantine states, \n\ncounter-based replay protection, the works. The bug wasn't in any of \n\nthat. It was in a sample app that gets far less scrutiny than the \n\n\"real\" infrastructure around it.\n\nIf you're reviewing (or building) a system like this, the example apps \n\nand demos are usually where the actual bugs hide — not the core library \n\neveryone stares at.\n\n**## A second, quieter finding **\nI also found a spot where one sibling app (a login flow) had an \non-chain verification step that its near-identical twin app was \nmissing entirely — same function available in the codebase, just never \ncalled on one specific path. Lower severity (the affected app is \nexplicitly demo-only and the riskiest downstream action was already \ndisabled), but the same underlying lesson: **when you fix a security \nissue in one place, check every place that duplicates that logic.** \n\nIf you're building anything with persistent memory/state across \n\nsessions for an AI agent, happy to talk through what to watch for. \n\nThis was part of a hackathon bug-bounty track, but the lessons apply \n\nto basically any multi-tenant app.\n\nIf any of this sounds interesting, Walrus Sessions 8: \"Chatbots That \n\nRemember\" is a live hackathon session running **Sept 18 – Oct 9, 2026**, \n\nwith **$2,500 in WAL prizes**. The challenge: build (or retrofit) a \n\nchatbot that uses Walrus Memory to remember context across sessions, \n\nusers, and devices — any use case counts (support, onboarding, tutoring, \n\ngame NPCs, community bots).\n\nThere's also a standalone **Bug Bounty track** (5 × $100) if finding \n\nbugs like the one above is more your thing than building a full chatbot \n\n— no chatbot required, just a reproducible bug filed on GitHub.", "url": "https://wpnews.pro/news/what-i-learned-auditing-an-open-source-ai-memory-sdk-and-the-bug-i-found-in-it", "canonical_source": "https://dev.to/walgo/what-i-learned-auditing-an-open-source-ai-memory-sdk-and-the-bug-i-found-in-it-13hc", "published_at": "2026-09-24 02:05:46+00:00", "updated_at": "2026-09-24 02:26:48.234735+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-safety"], "entities": ["MemWal", "Walrus Memory", "Walrus Sessions 8", "Walrus", "GitHub"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/what-i-learned-auditing-an-open-source-ai-memory-sdk-and-the-bug-i-found-in-it", "markdown": "https://wpnews.pro/news/what-i-learned-auditing-an-open-source-ai-memory-sdk-and-the-bug-i-found-in-it.md", "text": "https://wpnews.pro/news/what-i-learned-auditing-an-open-source-ai-memory-sdk-and-the-bug-i-found-in-it.txt", "jsonld": "https://wpnews.pro/news/what-i-learned-auditing-an-open-source-ai-memory-sdk-and-the-bug-i-found-in-it.jsonld"}}