GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix NoSQL Injection
in Poem

Executive Summary

NoSQL Injection in the Poem framework occurs when unsanitized user input is directly interpolated into a BSON query document. In the context of Rust and MongoDB, this typically happens when an attacker provides a JSON object where a string is expected, allowing them to use operators like '$ne' (not equal) or '$gt' (greater than) to bypass authentication or exfiltrate records. Even in a type-safe language like Rust, if the input is deserialized into a generic BSON type, the logic remains vulnerable.

The Vulnerable Pattern

VULNERABLE CODE
use poem::{handler, web::{Json, Query}, Result};
use mongodb::bson::{doc, Document};

#[derive(serde::Deserialize)] struct UserQuery { // If this is dynamic or generic, it allows operator injection username: serde_json::Value, }

#[handler] async fn get_user(Query(param): Query) -> Result<Json> { // VULNERABLE: Direct injection of a JSON Value into the BSON document // If param.username is {“$ne”: ""}, it returns all users. let filter = doc! { “username”: param.username }; let user = collection.find_one(filter, None).await?; Ok(Json(user)) }

The Secure Implementation

The exploit leverages the schemaless nature of BSON. By passing a JSON map instead of a string, an attacker can inject MongoDB query operators. The fix is two-fold: First, use strongly typed DTOs (Data Transfer Objects) in Poem's extractors to ensure input matches expected scalar types (e.g., String). Second, avoid using 'serde_json::Value' or 'bson::Document' for user-controlled fields within query builders. By enforcing 'String' types, the MongoDB driver automatically escapes the input as a literal value, neutralizing any nested operator logic.

SECURE CODE
use poem::{handler, web::{Json, Query}, Result};
use mongodb::bson::doc;

#[derive(serde::Deserialize)] struct UserQuery { // Enforce strict typing at the deserialization level username: String, }

#[handler] async fn get_user(Query(param): Query) -> Result<Json> { // SECURE: The ‘username’ is guaranteed to be a String. // BSON will treat it as a literal value, not a command object. let filter = doc! { “username”: &param.username }; let user = collection.find_one(filter, None).await?; Ok(Json(user)) }

System Alert • ID: 1560
Target: Poem API
Potential Vulnerability

Your Poem API might be exposed to NoSQL Injection

74% of Poem apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

Free Tier • No Credit Card • Instant Report

Verified by Ghost Labs Security Team

This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.