{"record":{"id":"9575f074adc5b589","repo":"larksuite/cli","slug":"mime-nesting-too-deep-max-d-levels","errorCode":null,"errorMessage":"MIME nesting too deep (max %d levels)","messagePattern":"MIME nesting too deep \\(max (.+?) levels\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/parse.go","lineNumber":127,"sourceCode":"\t\tHeaders: append([]Header{}, partHeaders...),\n\t}\n\tif len(partHeaders) == 0 {\n\t\tpart.MediaType = \"text/plain\"\n\t\tpart.MediaParams = map[string]string{\"charset\": \"UTF-8\"}\n\t\tpart.TransferEncoding = \"7bit\"\n\t\tpart.Body = body\n\t\tpart.RawEntity = append([]byte{}, body...)\n\t\treturn part, nil\n\t}\n\trawEntity := buildRawEntity(filterRawEntityHeaders(partHeaders), body)\n\treturn parsePart(partHeaders, body, \"1\", rawEntity, 0)\n}\n\nconst maxMIMEDepth = 50\n\nfunc parsePart(headers []Header, body []byte, partID string, rawEntity []byte, depth int) (*Part, error) {\n\tif depth > maxMIMEDepth {\n\t\treturn nil, fmt.Errorf(\"MIME nesting too deep (max %d levels)\", maxMIMEDepth)\n\t}\n\tpart := &Part{\n\t\tPartID:                partID,\n\t\tHeaders:               append([]Header{}, headers...),\n\t\tMediaType:             \"text/plain\",\n\t\tMediaParams:           map[string]string{},\n\t\tContentDispositionArg: map[string]string{},\n\t\tRawEntity:             append([]byte{}, rawEntity...),\n\t}\n\tif ct := headerValue(headers, \"Content-Type\"); ct != \"\" {\n\t\tmediaType, params, err := mime.ParseMediaType(ct)\n\t\tif err != nil {\n\t\t\t// Fallback: treat as opaque binary so the part is still accessible\n\t\t\t// and can round-trip through RawEntity. The original Content-Type\n\t\t\t// header is preserved for serialization.\n\t\t\tpart.MediaType = \"application/octet-stream\"\n\t\t\tpart.EncodingProblem = true\n\t\t} else {","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/parse.go#L109-L145","documentation":"parsePart recurses into nested MIME entities (multipart/* and message/rfc822) and enforces maxMIMEDepth of 50 levels. Exceeding it means the message tree is pathologically nested — either genuinely crafted or cyclic/malformed. The parser aborts to bound recursion and memory rather than risk stack exhaustion.","triggerScenarios":"Parsing a decoded EML whose MIME part nesting exceeds 50 levels: e.g. deeply nested multipart/mixed>alternative>related>... chains or message/rfc822 attachments recursively embedding messages.","commonSituations":"Maliciously crafted emails (mailbomb nesting), automation that repeatedly wraps/forwards messages (each forward adds a multipart layer), or a bug in code that regenerates attachments as nested multiparts.","solutions":["Flatten the message before parsing: unwrap redundant multipart layers or re-emit the EML with a shallower structure","Inspect the decoded EML's Content-Type tree to find what generates the deep nesting","If legitimately deep messages are common, extract top-level parts separately instead of full recursive parse; do not raise maxMIMEDepth, it guards against stack exhaustion"],"exampleFix":"// before\npart, err := draft.Parse(rawEML) // errors on deeply nested MIME\n// after\nif depth, ok := mimeDepthOf(rawEML); ok && depth > 50 {\n    return fmt.Errorf(\"refusing to parse: MIME nesting depth %d exceeds limit 50\", depth)\n}\npart, err := draft.Parse(rawEML)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"part, err := draft.Parse(rawEML)\nif err != nil && strings.Contains(err.Error(), \"MIME nesting too deep\") {\n    // treat message as untrusted: quarantine, notify sender/owner, skip parsing\n    return fmt.Errorf(\"draft rejected: malformed or malicious MIME nesting: %w\", err)\n}","preventionTips":["Treat >50-level nesting as hostile; never loosen the parser limit","When re-forwarding or re-wrapping messages programmatically, flatten instead of nesting","Log the draft ID and Content-Type chain when this triggers to find the nesting source"],"tags":["mail","draft","mime","recursion-limit"],"backgroundTag":"mime-nesting-too-deep","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}