markhoerth opened a new issue, #14417:
URL: https://github.com/apache/gravitino/issues/14417
### Version
main branch, commit bb634defdc5663a8124be5fca1c8d9e52ac096ac (2.0.0-SNAPSHOT)
### Describe what's wrong
A client sends a POST to the Iceberg REST service with no request body, or
with `{}` where the Iceberg REST spec requires `namespace` or
`source`/`destination`. The client expects a 400 that names the problem, as
`planTableScan` already returns ("Missing request body for plan table scan").
Instead, eleven endpoints return a 500 with a `NullPointerException`, a 500
"Authorization failed due to system internal error", or a 403 that claims the
request is not authorized. Any caller sees it, including the server admin.
Two gaps in Gravitino's own code produce it:
1. The REST handlers pass the null request on without checking it. Only
`planTableScan` checks
(`iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergTableOperations.java:565-567`,
helper at `:703-706`). The other handlers dereference it later:
- `IcebergNamespaceOperations.java:279` `updateNamespace`, NPE in
`IcebergCatalogWrapper.updateNamespaceProperties`
(`iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergCatalogWrapper.java:206`)
- `IcebergNamespaceOperations.java:319` `registerTable` and `:361`
`registerView`
- `IcebergTableOperations.java:184` `createTable`, NPE at
`IcebergTableEventDispatcher.java:101`
- `IcebergTableOperations.java:225` `updateTable`, NPE at
`IcebergTableOperationExecutor.java:122`
- `IcebergTableOperations.java:427` `reportTableMetrics`, NPE at `:452`
- `IcebergViewOperations.java:143` `createView` and `:224` `replaceView`
2. The authorization handlers that read the body run before the handler and
do not validate it:
-
`iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/server/web/filter/CreateNamespaceAuthzHandler.java:64-65`
dereference `request.namespace()` and `namespace.length()`. The NPE is caught
by the generic `catch (Exception ex)` in
`server-common/src/main/java/org/apache/gravitino/server/web/filter/BaseMetadataAuthorizationMethodInterceptor.java:353-365`,
which turns it into a 500 "Authorization failed due to system internal error".
- `RenameTableAuthzHandler.java:68-69` and
`RenameViewAuthzHandler.java:67-68` throw `ForbiddenException`
("RenameTableRequest not found in parameters") when the body is missing, so a
malformed request gets a 403.
- `RenameTableAuthzHandler.java:87` and `RenameViewAuthzHandler.java:86`
dereference `source()` without a null check, so `{}` gives the same 500.
### Error message and/or stacktrace
```
POST /iceberg/v1/namespaces (no body)
500 {"error":{"message":"Authorization failed due to system internal error,
User: 'admin', Operation:
'createNamespace'","type":"RuntimeException","code":500,...
Caused by: java.lang.NullPointerException: Cannot invoke
"org.apache.iceberg.rest.requests.CreateNamespaceRequest.namespace()" because
"request" is null
at
org.apache.gravitino.server.web.filter.CreateNamespaceAuthzHandler.process(CreateNamespaceAuthzHandler.java:64)
POST /iceberg/v1/namespaces/ns/tables (no body)
500 {"error":{"message":"Cannot invoke
\"org.apache.iceberg.rest.requests.CreateTableRequest.name()\" because
\"createTableRequest\" is null","type":"NullPointerException","code":500,...
at
org.apache.gravitino.iceberg.service.dispatcher.IcebergTableEventDispatcher.createTable(IcebergTableEventDispatcher.java:101)
POST /iceberg/v1/tables/rename (no body)
403 {"error":{"message":"RenameTableRequest not found in
parameters","type":"ForbiddenException","code":403,...
POST /iceberg/v1/tables/rename {}
500 {"error":{"message":"Authorization failed due to system internal error,
User: 'admin', Operation: 'renameTable'",...
Caused by: java.lang.NullPointerException: Cannot invoke
"org.apache.iceberg.catalog.TableIdentifier.namespace()" because the return
value of "org.apache.iceberg.rest.requests.RenameTableRequest.source()" is null
at
org.apache.gravitino.server.web.filter.RenameTableAuthzHandler.process(RenameTableAuthzHandler.java:87)
```
### How to reproduce
1. Start the Gravitino server with the Iceberg REST service and simple
authentication.
2. Create a namespace and a table to target:
```
curl -u admin:x -H 'Content-Type: application/json' -X POST
http://127.0.0.1:9001/iceberg/v1/namespaces -d '{"namespace":["ns"]}'
curl -u admin:x -H 'Content-Type: application/json' -X POST
http://127.0.0.1:9001/iceberg/v1/namespaces/ns/tables -d
'{"name":"t","schema":{"type":"struct","schema-id":0,"fields":[{"id":1,"name":"id","required":false,"type":"long"}]}}'
```
3. Send each POST with no body and note the status:
```
for p in namespaces namespaces/ns/properties namespaces/ns/tables
namespaces/ns/tables/t namespaces/ns/tables/t/metrics namespaces/ns/register
namespaces/ns/register-view namespaces/ns/views namespaces/ns/views/v
tables/rename views/rename namespaces/ns/tables/t/plan; do
printf '%s ' "$p"; curl -s -o /dev/null -w '%{http_code}\n' -u admin:x
-H 'Content-Type: application/json' -X POST
"http://127.0.0.1:9001/iceberg/v1/$p"
done
```
Every path returns 500 or 403 except `.../plan`, which returns 400.
4. Send `{}` to the three endpoints with required fields; each returns 500:
```
for p in namespaces tables/rename views/rename; do curl -s -o /dev/null
-w '%{http_code}\n' -u admin:x -H 'Content-Type: application/json' -X POST
"http://127.0.0.1:9001/iceberg/v1/$p" -d '{}'; done
```
### Additional context
#12788 and #12834 fixed the same null-body pattern in the Gravitino REST API
(`server/`), and #12769 fixed it for `createView` there; none of them covers
the Iceberg REST service. The 2.0 OSS test suite checks
`test_request_without_body_is_400` and
`test_request_missing_required_fields_is_400` found it. The NPEs and the 403
come from Gravitino's own handlers and authorization filters, not from the
Iceberg library.
--
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]