Skip to content

Unauthenticated full CRUD on AI memory layer — single request can wipe entire ChromaDB knowledge base #26

@tg12

Description

@tg12

Summary

The entire AI memory management API — list, delete-by-id, delete-all, and update — is exposed without authentication. A single unauthenticated HTTP request can permanently wipe all operational AI memory, or silently overwrite any stored memory with attacker-controlled content. This is a separate and more destructive attack surface than the unauthenticated write path documented in issue #25.

Evidence

app.py lines 1463–1540 — four unauthenticated routes with no login_required decorator:

@app.route('/api/geosentialai/memory', methods=['GET'])
def get_memories():                   # enumerate all memory IDs and content

@app.route('/api/geosentialai/memory/<memory_id>', methods=['DELETE'])
def delete_memory(memory_id):          # delete any individual memory entry

@app.route('/api/geosentialai/memory/all', methods=['DELETE'])
def clear_all_memories():
    all_ids = memory_collection.get()['ids']
    if all_ids:
        memory_collection.delete(ids=all_ids)   # wipes every entry in ChromaDB
    return jsonify({"success": True, "count": len(all_ids)})

@app.route('/api/geosentialai/memory/<memory_id>', methods=['PUT'])
def update_memory(memory_id):
    new_content = data.get('content')
    memory_collection.update(ids=[memory_id], documents=[new_content])  # overwrite any entry

The application has no login_required decorator applied anywhere in app.py — confirmed by zero matches for login_required, @login, or equivalent auth guards in the codebase.

Why this matters

The AI assistant's responses are shaped by vector-retrieved memory. Destroying all memory (DELETE /api/geosentialai/memory/all) silently degrades every subsequent AI response to context-free generation. Overwriting memory entries (PUT) plants false intelligence that persists across all future sessions for all users. Neither operation is detectable without explicit audit logging, which is also absent.

Attack or failure scenario

  1. Attacker sends DELETE /api/geosentialai/memory/all — one unauthenticated HTTP request.
  2. All ChromaDB entries are deleted. The AI assistant loses all historical context.
  3. Analysts using the system receive responses that are no longer informed by prior intelligence.
  4. The application returns {"success": true, "count": N} — no alert, no log, no recovery path.

Separately: an attacker who first GETs all memory IDs, then PUTs fabricated content to high-value entries, silently corrupts future AI outputs without triggering any anomaly.

Root cause

The memory CRUD endpoints were built as internal UI helpers and never subjected to the same access-control requirements applied to other routes. Combined with the application's complete absence of auth middleware, the entire memory layer is globally reachable.

Recommended fix

  1. Add @login_required (or the project's equivalent session/JWT guard) to all four memory endpoints.
  2. Restrict destructive operations (DELETE /all, PUT /<id>) to a privileged admin role.
  3. Log all memory mutations (actor, operation, affected IDs, timestamp) to an immutable audit trail.
  4. Add a soft-delete / snapshot mechanism so memory can be recovered after destructive operations.

Acceptance criteria

  • DELETE /api/geosentialai/memory/all without a valid session returns 401.
  • PUT /api/geosentialai/memory/<id> without a valid session returns 401.
  • All successful mutations are recorded in an audit log with actor identity.

Suggested labels

security, bug

Priority

P0

Severity

Critical — unauthenticated one-request destruction of the entire AI memory layer; no recovery path.

Confidence

Confirmed — all four routes exist in app.py:1463-1540 with no auth decorator; login_required usage count is zero across the file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions