Skip to content

Catalog API admin mutation endpoints have no authentication - unauthenticated item creation, update, and deletion #997

Open

Description

@geo-chen

Summary

The Catalog API registers CreateItem, UpdateItem (v1 and v2), and DeleteItemById endpoints with no authentication or authorization requirement. Any unauthenticated network client can create, overwrite, or delete catalog items. Unlike every other microservice in the application (Ordering, Basket, Webhooks), the Catalog API does not call builder.AddDefaultAuthentication() in its Extensions.cs and does not apply .RequireAuthorization() to its mutation routes.

Details

In src/Catalog.API/Apis/CatalogApi.cs (lines 92-110), the mutation routes are registered as:

v1.MapPut("/items", UpdateItemV1)
v2.MapPut("/items/{id:int}", UpdateItem)
api.MapPost("/items", CreateItem)
api.MapDelete("/items/{id:int}", DeleteItemById)

None of these route registrations call .RequireAuthorization().

In src/Catalog.API/Program.cs, neither app.UseAuthentication() nor app.UseAuthorization() is called, and there is no global authorization middleware.

In src/Catalog.API/Extensions/Extensions.cs, the AddApplicationServices method does not call builder.AddDefaultAuthentication(), unlike the Basket API (src/Basket.API/Extensions/Extensions.cs line 10: builder.AddDefaultAuthentication()), the Ordering API (src/Ordering.API/Extensions/Extensions.cs line 10: builder.AddDefaultAuthentication()), and the Webhooks API.

This is confirmed in the AppHost configuration (src/eShop.AppHost/Program.cs): the catalogApi resource is the only service not passed Identity__Url as an environment variable. The basket, ordering, and webhooks services all receive .WithEnvironment("Identity__Url", identityEndpoint), which is what triggers the JWT bearer middleware registration. Catalog receives no such configuration.

Additionally, src/eShop.AppHost/Extensions.cs registers a YARP catch-all route /api/catalog/{*any} in ConfigureMobileBffRoutes that forwards all catalog API requests (including mutations) from the mobile BFF without adding any authentication layer.

PoC

(available upon request)

Impact

Any unauthenticated attacker with network access to the Catalog API (directly or via the YARP mobile BFF) can add fraudulent products at arbitrary prices, modify existing product prices to cause financial loss, or delete all catalog items to cause a denial of service for the storefront. In a production deployment this would allow price manipulation attacks (creating $0.01 items), catalog defacement, and complete inventory destruction.

Activity

  1. minahilatiqdev commented on Sep 30, 2026

    @minahilatiqdev

    Hi @geo-chen, thanks for the detailed report.

    I'd like to take this on. My plan is:

    • Add builder.AddDefaultAuthentication() to Catalog.API, consistent with Basket and Ordering
    • Enable UseAuthentication() / UseAuthorization() in Program.cs
    • Apply .RequireAuthorization() to the mutation routes (CreateItem, UpdateItem v1/v2, DeleteItemById), leaving the read endpoints anonymous
    • Pass Identity__Url to the catalog API resource in the AppHost
    • Update the functional tests accordingly

    One question for the maintainers: since there's no admin role in eShop today, would plain RequireAuthorization() (any authenticated user) be acceptable here, or would you prefer a dedicated admin policy?

    Happy to open a PR once I hear back, or sooner if no one else is working on it.

  2. minahilatiqdev commented on Oct 2, 2026

    @minahilatiqdev

    Just checking in; happy to proceed with plain RequireAuthorization() if that works, or wait for guidance on the admin policy approach. Let me know either way.

  3. sourabhj2023 commented on Oct 25, 2026

    @sourabhj2023

    I would suggest/vote to go with plain RequireAuthorization() for now and keep audit for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions