Ritesh Shukla created HDDS-17600:
------------------------------------
Summary: S3G: request XML with mixed content is accepted and read
as only its trailing text
Key: HDDS-17600
URL: https://issues.apache.org/jira/browse/HDDS-17600
Project: Apache Ozone
Issue Type: Bug
Components: S3
Reporter: Ritesh Shukla
Assignee: Ritesh Shukla
h3. Problem
The S3 Gateway unmarshals request bodies (DeleteObjects,
CompleteMultipartUpload, PutBucketLifecycleConfiguration) with JAXB. When an
element that should hold only text also holds a child element, JAXB keeps only
the text after the last child and drops the rest. The gateway then acts on a
value the request does not literally contain.
For a multi-object delete:
{code:xml}
<Delete><Object><Key>dir/<a/>file</Key></Object></Delete>
{code}
is read as key {{file}}, not {{dir/file}}, and the gateway deletes {{file}}.
Likewise {{<Key><a>dir/</a>file</Key>}} is read as {{file}}.
No S3 request body has mixed content, so these bodies are malformed and should
be rejected rather than silently reinterpreted.
h3. Cause
{{MessageUnmarshaller}} feeds the SAX stream through {{XmlNamespaceFilter}}
into JAXB's {{UnmarshallerHandler}}, and nothing rejects an element holding
both text and child elements. (HDDS-14857 already made the parser reject
DOCTYPE declarations; this is a separate gap.)
h3. Proposed fix
In {{XmlNamespaceFilter}}, which every request unmarshaller uses, track for
each open element whether it has seen non-whitespace text and whether it has
seen a child element, and reject the request if it has both. Whitespace between
elements stays allowed. A rejected body takes the existing parse-error path
({{InvalidRequest}}).
h3. Testing
* Unit: {{TestMultiDeleteRequestUnmarshaller}} checks that both mixed-content
shapes above are rejected (they fail before the fix: the body is accepted),
that a key containing an escaped {{<}} is still read as one key, and that an
indented body still parses. All s3gateway unit tests pass with the change.
* Acceptance: a new case in {{s3/objectmultidelete.robot}} sends
{{<Key>dir/<a/>PREFIX-mixed</Key>}} through a presigned DeleteObjects URL
({{presigned_url_helper.py}} gains the helper; the AWS CLI escapes {{<}} in
keys). On the {{ozone}} compose cluster, on master it returns {{200 OK}} with
{{<Deleted><Key>PREFIX-mixed</Key></Deleted>}}, deleting a key the request did
not name; with the fix it is rejected and the object is kept.
h3. Note
Multi-delete parse errors map to {{InvalidRequest}}, while the
CompleteMultipartUpload unmarshaller maps them to {{MalformedXML}}, which is
AWS's code for a malformed body. Aligning that is left out of this change.
----
🤖 Generated with [Claude Code|https://claude.com/claude-code]
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]