You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During exploratory testing of the Publishing Push publishing job management REST endpoints (/api/v1/publishing/*), 4 issues were identified related to error handling consistency, input validation, and error message quality.
Issues Found
1. GET /api/v1/publishing/{bundleId} — XSS characters in path return Tomcat HTML instead of JSON
When the bundleId path parameter contains characters like <script>, Tomcat rejects the request at the container level and returns an HTML 400 page instead of a JSON error response. All other error cases for this endpoint return well-formed JSON.
When an invalid deliveryStrategy value is submitted, the error message exposes the internal Java class name com.dotcms.publishing.PublisherConfig$DeliveryStrategy. This is inconsistent with other validation errors on this API which return clean, user-friendly messages.
3. GET /api/v1/publishing — Out-of-range page/per_page values are silently clamped instead of returning 400
Severity: Info Endpoint:GET /api/v1/publishing
The OpenAPI spec states valid range for per_page is 1-500 and page starts from 1. However, out-of-range values are silently clamped to the nearest valid value and a 200 is returned. The spec documents a 400 for "pagination out of range".
Input
Expected (per spec)
Actual behavior
per_page=0
400
200, clamped to perPage: 1
per_page=-1
400
200, clamped to perPage: 1
per_page=501
400
200, clamped to perPage: 500
page=0
400
200, clamped to currentPage: 1
Either the spec should be updated to document the clamping behavior, or the endpoint should return 400 for out-of-range values.
4. POST /api/v1/publishing/push/{bundleId} — Invalid date format bypasses validation (bundle lookup runs first)
Severity: Info Endpoint:POST /api/v1/publishing/push/{bundleId}
When publishDate contains an invalid format (e.g. "2025/03/15 14:30:00" instead of ISO 8601), the endpoint returns 404 (bundle not found) instead of 400 (invalid date format). This happens because the bundle DB lookup executes before the date format is validated.
GET /api/v1/publishing/{bundleId} returns a JSON error response for all invalid bundleId inputs, including those with special characters
POST /api/v1/publishing/retry returns a clean, user-friendly error message for invalid deliveryStrategy values without exposing internal Java class names
GET /api/v1/publishing behavior for out-of-range page/per_page is either documented (clamping) or enforced (400) — spec and implementation agree
POST /api/v1/publishing/push/{bundleId} validates publishDate/expireDate format before performing the bundle DB lookup
Summary
During exploratory testing of the
Publishing Push publishing job managementREST endpoints (/api/v1/publishing/*), 4 issues were identified related to error handling consistency, input validation, and error message quality.Issues Found
1.
GET /api/v1/publishing/{bundleId}— XSS characters in path return Tomcat HTML instead of JSONSeverity: Low
Endpoint:
GET /api/v1/publishing/{bundleId}When the
bundleIdpath parameter contains characters like<script>, Tomcat rejects the request at the container level and returns an HTML 400 page instead of a JSON error response. All other error cases for this endpoint return well-formed JSON.Steps to reproduce:
Expected: JSON response
{"error": "dotcms.api.error.bad_request: ..."}Actual: Tomcat HTML 400 page —
<html><title>HTTP Status 400 - Bad Request</title>...2.
POST /api/v1/publishing/retry— InvaliddeliveryStrategyexposes internal Java class nameSeverity: Low
Endpoint:
POST /api/v1/publishing/retryWhen an invalid
deliveryStrategyvalue is submitted, the error message exposes the internal Java class namecom.dotcms.publishing.PublisherConfig$DeliveryStrategy. This is inconsistent with other validation errors on this API which return clean, user-friendly messages.Steps to reproduce:
Actual response:
{"message":"Can not construct instance from value 'INVALID_STRATEGY': not a valid class com.dotcms.publishing.PublisherConfig$DeliveryStrategy value"}Expected response (consistent with other endpoints):
{"error":"dotcms.api.error.bad_request: Invalid deliveryStrategy: 'INVALID_STRATEGY'. Valid values: ALL_ENDPOINTS, FAILED_ENDPOINTS"}3.
GET /api/v1/publishing— Out-of-rangepage/per_pagevalues are silently clamped instead of returning 400Severity: Info
Endpoint:
GET /api/v1/publishingThe OpenAPI spec states valid range for
per_pageis 1-500 andpagestarts from 1. However, out-of-range values are silently clamped to the nearest valid value and a 200 is returned. The spec documents a 400 for "pagination out of range".per_page=0perPage: 1per_page=-1perPage: 1per_page=501perPage: 500page=0currentPage: 1Either the spec should be updated to document the clamping behavior, or the endpoint should return 400 for out-of-range values.
4.
POST /api/v1/publishing/push/{bundleId}— Invalid date format bypasses validation (bundle lookup runs first)Severity: Info
Endpoint:
POST /api/v1/publishing/push/{bundleId}When
publishDatecontains an invalid format (e.g."2025/03/15 14:30:00"instead of ISO 8601), the endpoint returns 404 (bundle not found) instead of 400 (invalid date format). This happens because the bundle DB lookup executes before the date format is validated.Steps to reproduce:
Expected: 400 — invalid date format
Actual: 404 — bundle not found (date validation never reached)
Date format validation should occur before the bundle DB lookup to provide accurate feedback.
Test Environment
GET /api/v1/publishing,GET/DELETE /api/v1/publishing/{bundleId},POST /api/v1/publishing/push/{bundleId},POST /api/v1/publishing/retry,DELETE /api/v1/publishing/purgeAcceptance Criteria
GET /api/v1/publishing/{bundleId}returns a JSON error response for all invalid bundleId inputs, including those with special charactersPOST /api/v1/publishing/retryreturns a clean, user-friendly error message for invaliddeliveryStrategyvalues without exposing internal Java class namesGET /api/v1/publishingbehavior for out-of-rangepage/per_pageis either documented (clamping) or enforced (400) — spec and implementation agreePOST /api/v1/publishing/push/{bundleId}validatespublishDate/expireDateformat before performing the bundle DB lookup