fix: security & privacy (rate limiter fix, csrf session cookie, logout on server, drafts stale token passw, login timing, password over 72b, JWT_SECRET complexity, SMTP TLS, CSV export neutralised, fonts bundled, upload metadata, hourly cleanup job, privacy.md report)
This commit is contained in:
1 parent
e2812ee0b9
commit
ea98c5ec05
118 files changed
+3828
-130
No files matched your search
@@ -0,0 +1,88 @@
|
||||
package imaging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
const (
|
||||
riffHeaderSize = 12
|
||||
riffChunkHeaderSize = 8
|
||||
webpVP8X = "VP8X"
|
||||
webpEXIF = "EXIF"
|
||||
webpXMP = "XMP "
|
||||
webpEXIFFlag = 0x08
|
||||
webpXMPFlag = 0x04
|
||||
)
|
||||
|
||||
func stripWebP(data []byte) ([]byte, error) {
|
||||
if len(data) < riffHeaderSize || string(data[:4]) != "RIFF" || string(data[8:12]) != "WEBP" {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
declared := int(binary.LittleEndian.Uint32(data[4:])) + riffChunkHeaderSize
|
||||
if declared > len(data) || declared < riffHeaderSize {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
data = data[:declared]
|
||||
|
||||
var chunks [][]byte
|
||||
orientation := uint16(uprightOrientation)
|
||||
for pos := riffHeaderSize; pos < len(data); {
|
||||
available := len(data) - pos - riffChunkHeaderSize
|
||||
if available < 0 {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
size := binary.LittleEndian.Uint32(data[pos+4:])
|
||||
padded := uint64(size) + uint64(size%2)
|
||||
if padded > uint64(available) {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
kind := string(data[pos : pos+4])
|
||||
payload := data[pos+riffChunkHeaderSize : pos+riffChunkHeaderSize+int(size)]
|
||||
end := pos + riffChunkHeaderSize + int(padded)
|
||||
switch kind {
|
||||
case webpEXIF:
|
||||
if found, ok := exifOrientation(payload); ok {
|
||||
orientation = found
|
||||
}
|
||||
case webpXMP:
|
||||
default:
|
||||
chunks = append(chunks, bytes.Clone(data[pos:end]))
|
||||
}
|
||||
pos = end
|
||||
}
|
||||
|
||||
if len(chunks) == 0 {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
if string(chunks[0][:4]) == webpVP8X {
|
||||
if len(chunks[0]) <= riffChunkHeaderSize {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
flags := &chunks[0][riffChunkHeaderSize]
|
||||
*flags &^= webpEXIFFlag | webpXMPFlag
|
||||
if needsOrientation(orientation) {
|
||||
*flags |= webpEXIFFlag
|
||||
chunks = append(chunks, riffChunk(webpEXIF, orientationOnlyTIFF(orientation)))
|
||||
}
|
||||
}
|
||||
return riffContainer(chunks), nil
|
||||
}
|
||||
|
||||
func riffChunk(kind string, payload []byte) []byte {
|
||||
chunk := append([]byte(kind), binary.LittleEndian.AppendUint32(nil, uint32(len(payload)))...)
|
||||
chunk = append(chunk, payload...)
|
||||
if len(payload)%2 == 1 {
|
||||
chunk = append(chunk, 0)
|
||||
}
|
||||
return chunk
|
||||
}
|
||||
|
||||
func riffContainer(chunks [][]byte) []byte {
|
||||
body := []byte("WEBP")
|
||||
for _, chunk := range chunks {
|
||||
body = append(body, chunk...)
|
||||
}
|
||||
out := append([]byte("RIFF"), binary.LittleEndian.AppendUint32(nil, uint32(len(body)))...)
|
||||
return append(out, body...)
|
||||
}
|
||||
Reference in new issue
Block a user