anxkhn opened a new pull request, #3655:
URL: https://github.com/apache/parquet-java/pull/3655

   
   ### Rationale for this change
   
   When an encrypted file is written with a plaintext (signed) footer, the 
footer
   carries an AES-GCM authentication tag. On read,
   `ParquetMetadataConverter.verifyFooterIntegrity` recomputes the tag and 
compares
   it against the stored one to detect tampering.
   
   That comparison used `java.util.Arrays.equals`, which returns as soon as it 
hits
   a mismatching byte, so its running time depends on how many leading bytes 
match.
   Comparing a secret authentication tag this way is a timing side channel
   (CWE-208): an attacker who can measure verification time over many crafted 
files
   could, in principle, recover the correct tag byte by byte. Constant-time
   comparison is the standard practice for MAC/authentication-tag checks.
   
   ### What changes are included in this PR?
   
   - In `ParquetMetadataConverter.verifyFooterIntegrity`, replace
     `Arrays.equals(gcmTag, calculatedTag)` with
     `MessageDigest.isEqual(gcmTag, calculatedTag)` and add
     `import java.security.MessageDigest;`. A short comment notes the CWE-208
     rationale. `MessageDigest.isEqual` has the same boolean contract (true iff 
both
     arrays are non-null, of equal length, and byte-for-byte equal) but is
     implemented to run in time independent of the number of matching bytes, so 
the
     change is behavior-preserving: tampered footers are still rejected with a
     `TagVerificationException`. (The `Arrays` import stays; it is used 
elsewhere in
     the file.)
   - Add `TestFooterIntegrity` in `parquet-hadoop` covering the signed
     plaintext-footer path end to end: a valid signature is accepted, and a 
footer
     whose GCM tag has one byte flipped is rejected with 
`TagVerificationException`.
   
   The other `Arrays.equals` calls in the crypto module compare non-secret
   identifiers (AAD prefix, key-metadata reuse checks), not a secret MAC, so 
they
   are intentionally left unchanged.
   
   ### Are these changes tested?
   
   Yes.
   
   - `mvn -pl parquet-hadoop -Dtest=TestFooterIntegrity test` -> both cases 
pass.
   - The existing encryption suites still pass with the change:
     `mvn -pl parquet-hadoop 
-Dtest='ColumnEncryptorTest,TestPropertiesDrivenEncryption,TestFooterIntegrity' 
test`
     -> 43 tests, 0 failures, 0 errors.
   - The negative test was confirmed to be meaningful: temporarily neutralizing 
the
     tag check makes `tamperedFooterSignatureIsRejected` fail (nothing thrown),
     which shows the tampered bytes actually reach the reader and the tag check 
is
     what rejects them.
   
   A true timing measurement is impractical to assert deterministically in a 
unit
   test, so this PR verifies functional equivalence (accept valid, reject 
tampered)
   rather than the timing property itself.
   
   ### Are there any user-facing changes?
   
   No. This is an internal hardening of the footer-signature check with 
identical
   observable behavior (same acceptance and rejection outcomes, same exception 
on
   mismatch). No API, format, or configuration changes.
   


-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to