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,86 @@
|
||||
package imaging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
const (
|
||||
pngChunkHeaderSize = 8
|
||||
pngChunkCRCSize = 4
|
||||
pngIHDR = "IHDR"
|
||||
pngIEND = "IEND"
|
||||
pngEXIF = "eXIf"
|
||||
)
|
||||
|
||||
var pngSignature = []byte("\x89PNG\r\n\x1a\n")
|
||||
|
||||
var pngMetadataChunks = map[string]bool{
|
||||
pngEXIF: true,
|
||||
"tEXt": true,
|
||||
"zTXt": true,
|
||||
"iTXt": true,
|
||||
"tIME": true,
|
||||
}
|
||||
|
||||
func stripPNG(data []byte) ([]byte, error) {
|
||||
if !bytes.HasPrefix(data, pngSignature) {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
|
||||
out := bytes.Clone(pngSignature)
|
||||
orientation := uint16(uprightOrientation)
|
||||
insertAt := 0
|
||||
|
||||
for pos := len(pngSignature); pos < len(data); {
|
||||
available := len(data) - pos - pngChunkHeaderSize - pngChunkCRCSize
|
||||
if available < 0 {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
size := binary.BigEndian.Uint32(data[pos:])
|
||||
if uint64(size) > uint64(available) {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
kind := string(data[pos+4 : pos+pngChunkHeaderSize])
|
||||
payload := data[pos+pngChunkHeaderSize : pos+pngChunkHeaderSize+int(size)]
|
||||
end := pos + pngChunkHeaderSize + len(payload) + pngChunkCRCSize
|
||||
|
||||
if pngMetadataChunks[kind] {
|
||||
if kind == pngEXIF {
|
||||
if found, ok := exifOrientation(payload); ok {
|
||||
orientation = found
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out = append(out, data[pos:end]...)
|
||||
if kind == pngIHDR {
|
||||
insertAt = len(out)
|
||||
}
|
||||
}
|
||||
pos = end
|
||||
|
||||
if kind == pngIEND {
|
||||
return withPNGOrientation(out, insertAt, orientation)
|
||||
}
|
||||
}
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
|
||||
func withPNGOrientation(out []byte, insertAt int, orientation uint16) ([]byte, error) {
|
||||
if !needsOrientation(orientation) {
|
||||
return out, nil
|
||||
}
|
||||
if insertAt == 0 {
|
||||
return nil, errMalformedContainer
|
||||
}
|
||||
chunk := pngChunk(pngEXIF, orientationOnlyTIFF(orientation))
|
||||
return append(out[:insertAt:insertAt], append(chunk, out[insertAt:]...)...), nil
|
||||
}
|
||||
|
||||
func pngChunk(kind string, payload []byte) []byte {
|
||||
chunk := binary.BigEndian.AppendUint32(nil, uint32(len(payload)))
|
||||
chunk = append(chunk, kind...)
|
||||
chunk = append(chunk, payload...)
|
||||
return binary.BigEndian.AppendUint32(chunk, crc32.ChecksumIEEE(chunk[4:]))
|
||||
}
|
||||
Reference in new issue
Block a user