markhoerth opened a new issue, #12760:
URL: https://github.com/apache/gravitino/issues/12760

   # Servlets mounted outside the /api/* pathspec receive no authentication and 
no audit
   
   ## Summary
   
   `GravitinoServer` binds Jersey and every filter to a single pathspec,
   `API_ANY_PATH = "/api/*"`. Servlets registered at root paths fall outside it 
and
   therefore run with no authentication, no audit, no versioning and no custom
   filters. Nothing in the build fails when a servlet is added this way. The
   mechanism fails open, in the same manner as the metadata authorization 
allowlist
   already reported.
   
   ## Evidence
   
   From `server/src/main/java/org/apache/gravitino/server/GravitinoServer.java`:
   
   ```
   server.addServlet(servlet, API_ANY_PATH);                       // Jersey
   server.addServlet(configServlet, "/configs");
   server.addServlet(new SecretProvidersConfigServlet(...),
                     "/configs/secrets/providers");
   server.addServlet(new HealthAliasServlet(), "/health/*");
   server.addServlet(new HealthAliasServlet(), "/health.html");
   
   server.addFilter(new RequestContextFilter(), API_ANY_PATH);
   server.addFilter(new HttpAuditFilter(...), API_ANY_PATH);
   server.addCustomFilters(API_ANY_PATH);
   server.addFilter(new VersioningFilter(), API_ANY_PATH);
   server.addSystemFilters(API_ANY_PATH);
   ```
   
   Every filter takes `API_ANY_PATH`. None of the four servlet paths is under 
it.
   
   ## Instances
   
   `ConfigServlet` at `/configs`. Ships today. Public access is intended, but 
the
   response content is not filtered by any policy and currently includes the
   service-admin list. Tracked separately.
   
   `SecretProvidersConfigServlet` at `/configs/secrets/providers`. On main 
only, so
   it does not ship in 1.3. It returns the name, type and URI of every 
configured
   secret provider. Its javadoc states that it uses the same auth model as
   `ConfigServlet` with no additional privilege check. The comparison is 
incomplete:
   `ConfigServlet` publishes a set an operator can extend through
   `gravitino.server.visibleConfigs`, whereas this servlet publishes the entire
   provider registry with no operator control and no way to disable it. On an
   install using an external secret manager the URIs identify internal Vault or
   OpenBao endpoints, and the request is not audited.
   
   `HealthAliasServlet` at `/health/*` and `/health.html`. Public by intent and
   correct as it stands.
   
   ## Effect on existing coverage claims
   
   A REST contract probe over the 242 endpoints found by scanning `@Path`
   annotations reported no unauthenticated access anywhere. That result was 
measured
   entirely under `/api/*`. Servlet-registered endpoints carry no `@Path`, so 
they
   were never in the inventory, and a filter bound to `/api/*` returns 401 for 
any
   path beneath it whether or not a resource exists there. The earlier finding
   should be read as authentication is enforced under `/api/*`, and as saying
   nothing about paths outside it.
   
   ## Requirement
   
   Filter coverage is enforced structurally rather than by convention. Either 
every
   servlet is mounted under a pathspec the filter chain covers, or each 
root-mounted
   servlet declares itself public and a test asserts that every path passed to
   `addServlet` is either covered by the filter chain or named in an explicit
   public list.
   
   Audit is a compliance requirement for our enterprise customers, so an 
endpoint
   that answers without appearing in the audit log is a gap independent of what 
it
   returns.
   
   A test of that shape would have caught both instances above before they were
   written, and it is the same control missing from the metadata authorization
   allowlist.
   
   ## Scope
   
   `apache/gravitino`. The `ConfigServlet` instance ships in 1.3 and the 
enterprise
   tree inherits it. The secrets servlet is on main and should be corrected 
before
   it ships.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to