security: zero buffer pool contents before reuse
Previously, resetting slice length to 0 left previous protobuf data (device IDs, OID values, credentials) in the backing array. Now zeros the full capacity before returning to the pool.
This commit is contained in:
parent
442b019b0b
commit
13e923d251
2 changed files with 33 additions and 1 deletions
4
agent.go
4
agent.go
|
|
@ -144,7 +144,9 @@ func runSession(ctx context.Context, baseURL, token string) error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
encoded := base64.StdEncoding.EncodeToString(bin)
|
encoded := base64.StdEncoding.EncodeToString(bin)
|
||||||
*bp = bin[:0]
|
full := (*bp)[:cap(*bp)]
|
||||||
|
zeroBytes(full)
|
||||||
|
*bp = full[:0]
|
||||||
bufPool.Put(bp)
|
bufPool.Put(bp)
|
||||||
payload, _ := json.Marshal(map[string]string{"binary": encoded})
|
payload, _ := json.Marshal(map[string]string{"binary": encoded})
|
||||||
sendMsg(event, payload)
|
sendMsg(event, payload)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -352,6 +353,35 @@ func TestHandleMessageRejectsOversizedPayload(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBufferPoolZeroesOnReturn(t *testing.T) {
|
||||||
|
pool := &sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
b := make([]byte, 0, 64)
|
||||||
|
return &b
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a buffer, write some data, return it
|
||||||
|
bp := pool.Get().(*[]byte)
|
||||||
|
*bp = append((*bp)[:0], []byte("sensitive credentials data here")...)
|
||||||
|
full := (*bp)[:cap(*bp)]
|
||||||
|
|
||||||
|
// Simulate the zeroing that sendBinaryResult should do
|
||||||
|
zeroBytes(full)
|
||||||
|
*bp = full[:0]
|
||||||
|
pool.Put(bp)
|
||||||
|
|
||||||
|
// Get the buffer back and verify it's zeroed
|
||||||
|
bp2 := pool.Get().(*[]byte)
|
||||||
|
full2 := (*bp2)[:cap(*bp2)]
|
||||||
|
for i, b := range full2 {
|
||||||
|
if b != 0 {
|
||||||
|
t.Errorf("byte[%d] = %d, expected 0 — pool buffer not zeroed", i, b)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestZeroBytes(t *testing.T) {
|
func TestZeroBytes(t *testing.T) {
|
||||||
b := []byte{1, 2, 3, 4, 5}
|
b := []byte{1, 2, 3, 4, 5}
|
||||||
zeroBytes(b)
|
zeroBytes(b)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue