-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[PM-27575] Add support for loading Mailer templates from disk #6520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Claude finished @Hinton's task —— View job Code Review Complete
Summary of Changes Since Last ReviewThis PR adds the capability to load mail templates from disk for self-hosted instances, allowing template customization without recompilation. The latest commits addressed path traversal vulnerabilities with case-insensitive security checks and comprehensive testing. Recent changes:
Critical Issues1. Potential symlink bypass in path traversal protection (src/Core/Platform/Mailer/HandlebarMailRenderer.cs:97-106)Severity: High (Security) The current implementation resolves paths with // Current code
var diskPath = Path.GetFullPath(Path.Combine(_globalSettings.MailTemplateDirectory, template));
var baseDirectory = Path.GetFullPath(_globalSettings.MailTemplateDirectory);
if (!diskPath.StartsWith(baseDirectory + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) &&
!diskPath.Equals(baseDirectory, StringComparison.OrdinalIgnoreCase))
{
_logger.LogWarning("Template path traversal attempt detected: {Template}", template);
return null;
}Attack scenario:
Recommendation: Use var diskPath = Path.GetFullPath(Path.Combine(_globalSettings.MailTemplateDirectory, template));
var baseDirectory = Path.GetFullPath(_globalSettings.MailTemplateDirectory);
// Ensure the resolved path is within the configured directory
if (!diskPath.StartsWith(baseDirectory + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) &&
!diskPath.Equals(baseDirectory, StringComparison.OrdinalIgnoreCase))
{
_logger.LogWarning("Template path traversal attempt detected: {Template}", template);
return null;
}
// Check for symlinks
var fileInfo = new FileInfo(diskPath);
if (fileInfo.Exists && fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint))
{
_logger.LogWarning("Template is a symlink, which is not allowed: {Template}", template);
return null;
}2. Missing null check for
|
| return handlebars.Compile(source); | ||
| } | ||
|
|
||
| private static async Task<string> ReadSourceAsync(Assembly assembly, string template) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had to remove static from most functions because reading from disk relies on non static data.
|
Great job! No new security vulnerabilities introduced in this pull request |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6520 +/- ##
==========================================
+ Coverage 51.86% 51.88% +0.01%
==========================================
Files 1902 1902
Lines 84058 84090 +32
Branches 7501 7504 +3
==========================================
+ Hits 43598 43629 +31
- Misses 38766 38768 +2
+ Partials 1694 1693 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|

🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-27575
📔 Objective
Adds support for overloading mail templates from disk.
⏰ Reminders before review
🦮 Reviewer guidelines
:+1:) or similar for great changes:memo:) or ℹ️ (:information_source:) for notes or general info:question:) for questions:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion:art:) for suggestions / improvements:x:) or:warning:) for more significant problems or concerns needing attention:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt:pick:) for minor or nitpick changes