fix: project inline binary metadata and protect private markup attributes
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Inline attachments remain opaque in every log format, regardless of the
|
||||
// carrier field or element. Only standard-decoded media type and byte count
|
||||
// are projected; malformed declarations never restore their payload.
|
||||
var inlineDataURI = regexp.MustCompile(`(?i)\bdata:[^,\s<>"']*,[^\s<>"']*`)
|
||||
|
||||
func redactInlineBinary(s string) string {
|
||||
if strings.HasPrefix(strings.ToLower(strings.TrimSpace(s)), "data:") {
|
||||
return inlineBinarySummary(strings.TrimSpace(s))
|
||||
}
|
||||
return inlineDataURI.ReplaceAllStringFunc(s, inlineBinarySummary)
|
||||
}
|
||||
|
||||
// Repeated formatting must retain only our typed attachment projection.
|
||||
func isInlineBinarySummary(s string) bool {
|
||||
if !strings.HasPrefix(s, "[BINARY ") || !strings.HasSuffix(s, "]") {
|
||||
return false
|
||||
}
|
||||
fields := strings.Fields(s[len("[BINARY ") : len(s)-1])
|
||||
if len(fields) != 2 && len(fields) != 3 {
|
||||
return false
|
||||
}
|
||||
if !strings.HasPrefix(fields[0], "type=") || !strings.HasPrefix(fields[1], "bytes=") {
|
||||
return false
|
||||
}
|
||||
kind := strings.TrimPrefix(fields[0], "type=")
|
||||
if kind != "unknown" {
|
||||
media, params, err := mime.ParseMediaType(kind)
|
||||
if err != nil || media != kind || !strings.Contains(media, "/") || len(params) != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
count := strings.TrimPrefix(fields[1], "bytes=")
|
||||
if count != "unknown" {
|
||||
if _, err := strconv.ParseUint(count, 10, 64); err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return len(fields) == 2 || fields[2] == "error=invalid_data_uri"
|
||||
}
|
||||
|
||||
func inlineBinarySummary(uri string) string {
|
||||
header, payload, ok := strings.Cut(uri[5:], ",")
|
||||
if !ok {
|
||||
return "[BINARY type=unknown bytes=unknown error=invalid_data_uri]"
|
||||
}
|
||||
encoded := strings.HasSuffix(strings.ToLower(header), ";base64")
|
||||
if encoded {
|
||||
header = header[:len(header)-7]
|
||||
}
|
||||
if header == "" {
|
||||
header = "text/plain;charset=US-ASCII"
|
||||
}
|
||||
media, _, err := mime.ParseMediaType(header)
|
||||
if err != nil || !strings.Contains(media, "/") {
|
||||
return "[BINARY type=unknown bytes=unknown error=invalid_data_uri]"
|
||||
}
|
||||
raw, err := url.PathUnescape(payload)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("[BINARY type=%s bytes=unknown error=invalid_data_uri]", media)
|
||||
}
|
||||
data := []byte(raw)
|
||||
if encoded {
|
||||
data, err = base64.StdEncoding.DecodeString(raw)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("[BINARY type=%s bytes=unknown error=invalid_data_uri]", media)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("[BINARY type=%s bytes=%d]", media, len(data))
|
||||
}
|
||||
Reference in New Issue
Block a user