This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new 1158713b fix(parquet): reject truncated footer signatures (#1074)
1158713b is described below
commit 1158713bc40c9f63ac04a78cc4ab4e4125c4dc6a
Author: Minh Vu <[email protected]>
AuthorDate: Wed Aug 5 20:07:47 2026 +0200
fix(parquet): reject truncated footer signatures (#1074)
## Problem
`FileMetaData.VerifySignature` sliced the supplied signature into nonce
and tag fields before validating its length. A truncated signature could
therefore trigger an out-of-range panic instead of being rejected.
## Change
Return `false` when the signature is shorter than the required nonce
plus GCM tag length. Valid-length signature verification continues
through the existing constant-time comparison path.
## Coverage
The regression test covers every truncated length and the exact minimum
boundary, confirming that malformed input is rejected without panicking.
## Validation
`go test ./parquet/metadata`
---
parquet/metadata/file.go | 3 +++
parquet/metadata/file_signature_test.go | 44 +++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/parquet/metadata/file.go b/parquet/metadata/file.go
index 2d4cf1b4..20a1a2ab 100644
--- a/parquet/metadata/file.go
+++ b/parquet/metadata/file.go
@@ -478,6 +478,9 @@ func (f *FileMetaData) VerifySignature(signature []byte)
bool {
if f.FileDecryptor == nil {
panic("decryption not set properly, cannot verify signature")
}
+ if len(signature) < encryption.NonceLength+encryption.GcmTagLength {
+ return false
+ }
serializer := thrift.NewThriftSerializer()
data, _ := serializer.Write(context.Background(), f.FileMetaData)
diff --git a/parquet/metadata/file_signature_test.go
b/parquet/metadata/file_signature_test.go
new file mode 100644
index 00000000..745ec3ca
--- /dev/null
+++ b/parquet/metadata/file_signature_test.go
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package metadata_test
+
+import (
+ "testing"
+
+ "github.com/apache/arrow-go/v18/arrow/memory"
+ "github.com/apache/arrow-go/v18/parquet"
+ "github.com/apache/arrow-go/v18/parquet/internal/encryption"
+ "github.com/apache/arrow-go/v18/parquet/metadata"
+ "github.com/stretchr/testify/require"
+)
+
+func TestVerifySignatureRejectsTruncatedSignature(t *testing.T) {
+ props :=
parquet.NewFileDecryptionProperties(parquet.WithFooterKey("0123456789abcdef"))
+ meta := &metadata.FileMetaData{
+ FileDecryptor: encryption.NewFileDecryptor(props, "",
parquet.AesGcm, "", memory.DefaultAllocator),
+ }
+
+ for size := 0; size < encryption.NonceLength+encryption.GcmTagLength;
size++ {
+ if meta.VerifySignature(make([]byte, size)) {
+ t.Fatalf("truncated signature of length %d was
accepted", size)
+ }
+ }
+ require.NotPanics(t, func() {
+ require.False(t, meta.VerifySignature(make([]byte,
encryption.NonceLength+encryption.GcmTagLength)))
+ })
+}