GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix Shadow API Exposure
in Poem

Executive Summary

Shadow APIs represent the 'dark matter' of your attack surface—endpoints lurking in production that your security scanners and documentation don't see. In the Poem framework, this typically occurs when developers use catch-all wildcard routes for debugging or fail to synchronize their routing table with their OpenAPI specifications, leaving undocumented logic exposed to scanners like FFuf or Burp Suite.

The Vulnerable Pattern

VULNERABLE CODE
use poem::{handler, route, Route, web::Path, get};

#[handler] fn internal_debug(Path(cmd): Path) -> String { format!(“Executing internal command: {}”, cmd) }

#[handler] fn get_user() -> &‘static str { “User data” }

#[tokio::main] async fn main() { // VULNERABILITY: The ‘/debug’ wildcard is undocumented and exposed. // Attackers can fuzz this to find internal management functions. let app = Route::new() .at(“/api/user”, get(get_user)) .at(“/debug/*path”, get(internal_debug));

// Server::new(tcp_listener).run(app).await;

}

The Secure Implementation

To eliminate Shadow APIs in Poem, you must transition from manual `Route` definitions to `poem-openapi`. This enforces a schema-first approach where the code is the documentation. The fix involves: 1. Removing wildcard routes (`*path`) which act as catch-alls for undocumented logic. 2. Using `OpenApiService` to ensure every endpoint is explicitly declared in the OpenAPI spec. 3. Nesting sensitive routes under a specific prefix with mandatory authentication middleware, ensuring that even if an endpoint is 'hidden', it is not 'exposed' to unauthenticated actors.

SECURE CODE
use poem::{handler, route, Route, get, EndpointExt};
use poem_openapi::{OpenApi, OpenApiService};

struct Api;

#[OpenApi] impl Api { /// Returns user data - Documented and tracked #[oai(path = “/user”, method = “get”)] async fn get_user(&self) -> &‘static str { “User data” } }

#[tokio::main] async fn main() { let api_service = OpenApiService::new(Api, “Secure API”, “1.0”) .server(“https://api.production.com/v1”);

let ui = api_service.swagger_ui();

// SECURE: Use poem-openapi to ensure the routing table matches the documentation.
// Wildcards are removed. Internal routes are moved behind explicit middleware/auth.
let app = Route::new()
    .nest("/v1", api_service)
    .nest("/docs", ui);

// Server::new(tcp_listener).run(app).await;

}

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

Your Poem API might be exposed to Shadow API Exposure

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.