v0.13.4
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 4s

This commit is contained in:
mdecimus 2025-09-30 15:54:53 +02:00
parent 4a96357b2b
commit b39b4ec141
34 changed files with 246 additions and 113 deletions

View file

@ -2,6 +2,27 @@
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
## [0.13.4] - 2025-09-30
If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking changes** to the message queue and MTA configuration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions.
## Added
## Changed
- JMAP: Protocol layer rewrite for zero-copy deserialization and architectural improvements.
## Fixed
- JMAP: References to previous method fail when there are no results (#1507).
- JMAP: Enforce quota checks on `Blob/copy`.
- JMAP: `Mailbox/get` fails without `accountId` argument (#1936).
- JMAP: Do not return `invalidProperties` when email update doesn't contain changes (#1139)
- IMAP: Unbounded memory allocation in request parser.
- IMAP: Wrong permission checked for GETACL.
- iTIP: Include date properties in `REPLY` (#2102).
- OIDC: Do not set `username` field if it is the same as the `email` field.
- Telemetry: Fix `calculateMetrics` housekeeper task (#2155).
- Directory: Always use `rsplit` to extract the domain part from email addresses.
## [0.13.3] - 2025-09-10
If you are upgrading from v0.11.x or v0.12.x, this version includes **breaking changes** to the message queue and MTA configuration. Please read the [UPGRADING.md](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING.md) file for more information on how to upgrade from previous versions.

60
Cargo.lock generated
View file

@ -1220,7 +1220,7 @@ dependencies = [
[[package]]
name = "common"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"aes-gcm-siv",
"ahash",
@ -1761,7 +1761,7 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
[[package]]
name = "dav"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"calcard",
"chrono",
@ -1783,7 +1783,7 @@ dependencies = [
[[package]]
name = "dav-proto"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"calcard",
"chrono",
@ -1976,7 +1976,7 @@ dependencies = [
[[package]]
name = "directory"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"argon2",
@ -2249,7 +2249,7 @@ dependencies = [
[[package]]
name = "email"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"aes",
"aes-gcm",
@ -2369,7 +2369,7 @@ dependencies = [
[[package]]
name = "event_macro"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"proc-macro2",
"quote",
@ -2844,7 +2844,7 @@ dependencies = [
[[package]]
name = "groupware"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"calcard",
@ -3144,7 +3144,7 @@ dependencies = [
[[package]]
name = "http"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"async-stream",
"base64 0.22.1",
@ -3255,7 +3255,7 @@ dependencies = [
[[package]]
name = "http_proto"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"common",
"compact_str",
@ -3562,7 +3562,7 @@ checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c"
[[package]]
name = "imap"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"common",
@ -3589,7 +3589,7 @@ dependencies = [
[[package]]
name = "imap_proto"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"chrono",
@ -3861,7 +3861,7 @@ dependencies = [
[[package]]
name = "jmap"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"aes-gcm",
"aes-gcm-siv",
@ -3947,7 +3947,7 @@ dependencies = [
[[package]]
name = "jmap_proto"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"compact_str",
@ -4421,7 +4421,7 @@ dependencies = [
[[package]]
name = "managesieve"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"common",
@ -4530,7 +4530,7 @@ checksum = "c797b9d6bb23aab2fc369c65f871be49214f5c759af65bde26ffaaa2b646b492"
[[package]]
name = "migration"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"base64 0.22.1",
"bincode 1.3.3",
@ -4767,7 +4767,7 @@ dependencies = [
[[package]]
name = "nlp"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"bincode 1.3.3",
@ -5532,7 +5532,7 @@ dependencies = [
[[package]]
name = "pop3"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"common",
"directory",
@ -5729,7 +5729,7 @@ dependencies = [
[[package]]
name = "proc_macros"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"proc-macro2",
"quote",
@ -7381,7 +7381,7 @@ dependencies = [
[[package]]
name = "services"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"aes-gcm",
"aes-gcm-siv",
@ -7591,7 +7591,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "smtp"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"blake3",
@ -7693,7 +7693,7 @@ dependencies = [
[[package]]
name = "spam-filter"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"common",
"compact_str",
@ -7757,14 +7757,14 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "stalwart"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"common",
"dav",
"directory",
"email",
"groupware",
"http 0.13.3",
"http 0.13.4",
"imap",
"jemallocator",
"jmap",
@ -7783,7 +7783,7 @@ dependencies = [
[[package]]
name = "stalwart-cli"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"clap",
"console",
@ -7814,7 +7814,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "store"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"arc-swap",
@ -8023,7 +8023,7 @@ dependencies = [
[[package]]
name = "tests"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"async-trait",
@ -8044,7 +8044,7 @@ dependencies = [
"form_urlencoded",
"futures",
"groupware",
"http 0.13.3",
"http 0.13.4",
"http-body-util",
"http_proto",
"hyper 1.7.0",
@ -8579,7 +8579,7 @@ dependencies = [
[[package]]
name = "trc"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"base64 0.22.1",
@ -8660,7 +8660,7 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "types"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"blake3",
"compact_str",
@ -8857,7 +8857,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "utils"
version = "0.13.3"
version = "0.13.4"
dependencies = [
"ahash",
"base64 0.22.1",

135
SECURITY_TEMPLATE.md Normal file
View file

@ -0,0 +1,135 @@
# Stalwart Security Advisory
**CVE ID:** CVE-YYYY-NNNNN
**Publication Date:** YYYY-MM-DD
**Last Updated:** YYYY-MM-DD
## Summary
[Provide a brief, non-technical summary of the vulnerability in 1-2 sentences]
## Affected Products and Versions
**Product:** Stalwart Mail and Collaboration Server
**Affected Versions:**
- Version X.X.X through Y.Y.Y
- [List specific affected version ranges]
**Fixed Versions:**
- Version Z.Z.Z and later
- [List all versions that include the fix]
## Vulnerability Details
### Description
[Detailed technical description of the vulnerability, including how it can be exploited]
### Impact
[Describe the potential impact if this vulnerability is exploited]
### CVSS Score
**CVSS v3.1 Base Score:** X.X ([SEVERITY])
**Vector String:** CVSS:3.1/AV:X/AC:X/PR:X/UI:X/S:X/C:X/I:X/A:X
**Severity Breakdown:**
- **Attack Vector:** [Network/Adjacent/Local/Physical]
- **Attack Complexity:** [Low/High]
- **Privileges Required:** [None/Low/High]
- **User Interaction:** [None/Required]
- **Scope:** [Unchanged/Changed]
- **Confidentiality Impact:** [None/Low/High]
- **Integrity Impact:** [None/Low/High]
- **Availability Impact:** [None/Low/High]
### CWE Classification
**CWE-XXX:** [Weakness Name]
## Technical Details
### Root Cause
[Explain the underlying cause of the vulnerability]
### Attack Scenario
[Describe a realistic attack scenario or proof of concept, without providing exploit code]
### Prerequisites
[List any conditions that must be met for successful exploitation]
## Remediation
### Recommended Actions
1. **Immediate:** Upgrade to version Z.Z.Z or later
2. **Short-term:** [Any temporary mitigation measures]
3. **Long-term:** [Any additional security hardening recommendations]
### Upgrade Instructions
```bash
# Example upgrade commands
[Provide specific upgrade instructions for Stalwart]
```
### Workarounds
[If applicable, describe any temporary workarounds for systems that cannot be immediately upgraded]
**Note:** Workarounds are temporary measures and do not fully resolve the vulnerability. Upgrading is strongly recommended.
## Detection
### Indicators of Compromise
[List any logs, patterns, or indicators that may suggest exploitation attempts]
### Log Entries
```
[Example log entries that administrators should look for]
```
## Timeline
- **YYYY-MM-DD:** Vulnerability discovered [by researcher/team name]
- **YYYY-MM-DD:** Vendor notified
- **YYYY-MM-DD:** Vendor acknowledged issue
- **YYYY-MM-DD:** Fix developed and tested
- **YYYY-MM-DD:** Fixed version released
- **YYYY-MM-DD:** Public disclosure
## Credits
This vulnerability was discovered by [Researcher Name / Organization].
## References
- Stalwart Mail Server: https://stalw.art/
- CVE Entry: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-YYYY-NNNNN
- GitHub Advisory: [Link to GitHub Security Advisory if applicable]
- Release Notes: [Link to release notes with fix]
## Contact Information
For questions or concerns regarding this advisory, please contact:
**Security Team:** hello@stalw.art
**Website:** https://stalw.art
To report security vulnerabilities in Stalwart, please follow our [responsible disclosure policy](https://github.com/stalwartlabs/stalwart/security/policy).
## Disclaimer
This advisory is provided "as is" without warranty of any kind. The information contained in this advisory is subject to change without notice.
---
**Document Version:** 1.0
**Classification:** Public

View file

@ -5,7 +5,7 @@ authors = ["Stalwart Labs LLC <hello@stalw.art>"]
license = "AGPL-3.0-only OR LicenseRef-SEL"
repository = "https://github.com/stalwartlabs/cli"
homepage = "https://github.com/stalwartlabs/cli"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
readme = "README.md"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "common"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"
build = "build.rs"

View file

@ -1,6 +1,6 @@
[package]
name = "dav-proto"
version = "0.13.3"
version = "0.13.4"
edition = "2021"
[dependencies]

View file

@ -1,6 +1,6 @@
[package]
name = "dav"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "directory"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "email"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -139,7 +139,13 @@ impl MessageMetadata {
}
HeaderName::From | HeaderName::To | HeaderName::Cc | HeaderName::Bcc => {
if !seen_headers[header.name.id() as usize] {
let property = property_from_header(&header.name);
let property = match &header.name {
HeaderName::From => EmailField::From,
HeaderName::To => EmailField::To,
HeaderName::Cc => EmailField::Cc,
HeaderName::Bcc => EmailField::Bcc,
_ => unreachable!(),
};
let mut sort_text = SortedAddressBuilder::new();
let mut found_addr = false;
@ -336,7 +342,13 @@ impl ArchivedMessageMetadata {
| ArchivedHeaderName::Cc
| ArchivedHeaderName::Bcc => {
if !seen_headers[header.name.id() as usize] {
let property = property_from_archived_header(&header.name);
let property = match &header.name {
ArchivedHeaderName::From => EmailField::From,
ArchivedHeaderName::To => EmailField::To,
ArchivedHeaderName::Cc => EmailField::Cc,
ArchivedHeaderName::Bcc => EmailField::Bcc,
_ => unreachable!(),
};
let mut sort_text = SortedAddressBuilder::new();
let mut found_addr = false;
@ -1035,39 +1047,3 @@ impl<T: TrimTextValue> TrimTextValue for Vec<T> {
self.into_iter().map(|v| v.trim_text(length)).collect()
}
}
pub fn property_from_header(header: &HeaderName) -> EmailField {
match header {
HeaderName::Subject => EmailField::Subject,
HeaderName::From => EmailField::From,
HeaderName::To => EmailField::To,
HeaderName::Cc => EmailField::Cc,
HeaderName::Date => EmailField::SentAt,
HeaderName::Bcc => EmailField::Bcc,
HeaderName::ReplyTo => EmailField::ReplyTo,
HeaderName::Sender => EmailField::Sender,
HeaderName::InReplyTo => EmailField::InReplyTo,
HeaderName::MessageId => EmailField::MessageId,
HeaderName::References => EmailField::References,
HeaderName::ResentMessageId => EmailField::EmailIds,
_ => unreachable!(),
}
}
pub fn property_from_archived_header(header: &ArchivedHeaderName) -> EmailField {
match header {
ArchivedHeaderName::Subject => EmailField::Subject,
ArchivedHeaderName::From => EmailField::From,
ArchivedHeaderName::To => EmailField::To,
ArchivedHeaderName::Cc => EmailField::Cc,
ArchivedHeaderName::Date => EmailField::SentAt,
ArchivedHeaderName::Bcc => EmailField::Bcc,
ArchivedHeaderName::ReplyTo => EmailField::ReplyTo,
ArchivedHeaderName::Sender => EmailField::Sender,
ArchivedHeaderName::InReplyTo => EmailField::InReplyTo,
ArchivedHeaderName::MessageId => EmailField::MessageId,
ArchivedHeaderName::References => EmailField::References,
ArchivedHeaderName::ResentMessageId => EmailField::EmailIds,
_ => unreachable!(),
}
}

View file

@ -1,6 +1,6 @@
[package]
name = "groupware"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "http_proto"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "http"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "imap_proto"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "imap"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "jmap_proto"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "jmap"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -7,7 +7,7 @@ homepage = "https://stalw.art"
keywords = ["imap", "jmap", "smtp", "email", "mail", "webdav", "server"]
categories = ["email"]
license = "AGPL-3.0-only OR LicenseRef-SEL"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "managesieve"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "migration"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -232,6 +232,7 @@ pub(crate) async fn migrate_emails(server: &Server, account_id: u32) -> trc::Res
}
// Delete messageId index, now in References
const MESSAGE_ID_FIELD: u8 = 11;
server
.store()
.delete_range(
@ -240,7 +241,7 @@ pub(crate) async fn migrate_emails(server: &Server, account_id: u32) -> trc::Res
key: KeySerializer::new(U64_LEN)
.write(account_id)
.write(u8::from(Collection::Email))
.write(u8::from(EmailField::MessageId))
.write(MESSAGE_ID_FIELD)
.finalize(),
},
AnyKey {
@ -248,7 +249,7 @@ pub(crate) async fn migrate_emails(server: &Server, account_id: u32) -> trc::Res
key: KeySerializer::new(U64_LEN)
.write(account_id)
.write(u8::from(Collection::Email))
.write(u8::from(EmailField::MessageId))
.write(MESSAGE_ID_FIELD)
.write(&[u8::MAX; 8][..])
.finalize(),
},

View file

@ -1,6 +1,6 @@
[package]
name = "nlp"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "pop3"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "services"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -7,7 +7,7 @@ homepage = "https://stalw.art/smtp"
keywords = ["smtp", "email", "mail", "server"]
categories = ["email"]
license = "AGPL-3.0-only OR LicenseRef-SEL"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "spam-filter"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "store"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "trc"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "event_macro"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
[lib]

View file

@ -1,6 +1,6 @@
[package]
name = "types"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -44,11 +44,11 @@ pub enum EmailField {
To,
Cc,
Bcc,
ReplyTo,
Sender,
InReplyTo,
MessageId,
EmailIds,
//ReplyTo,
//Sender,
//InReplyTo,
//MessageId,
//EmailIds,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -108,24 +108,24 @@ impl From<CalendarField> for u8 {
impl From<EmailField> for u8 {
fn from(value: EmailField) -> Self {
match value {
EmailField::From => 87,
EmailField::To => 35,
EmailField::Cc => 74,
EmailField::Bcc => 69,
EmailField::Subject => 29,
EmailField::Size => 27,
EmailField::Metadata => 71,
EmailField::Subject => 29,
EmailField::References => 20,
EmailField::MailboxIds => 7,
EmailField::ReceivedAt => 19,
EmailField::MessageId => 11,
EmailField::ReplyTo => 21,
EmailField::Sender => 25,
EmailField::SentAt => 26,
EmailField::To => 35,
EmailField::Bcc => 69,
EmailField::Cc => 74,
EmailField::EmailIds => 84,
EmailField::From => 87,
EmailField::HasAttachment => 89,
EmailField::InReplyTo => 96,
EmailField::Archive => ARCHIVE_FIELD,
//EmailField::MessageId => 11,
//EmailField::ReplyTo => 21,
//EmailField::Sender => 25,
//EmailField::EmailIds => 84,
//EmailField::InReplyTo => 96,
}
}
}

View file

@ -1,6 +1,6 @@
[package]
name = "utils"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"

View file

@ -1,6 +1,6 @@
[package]
name = "proc_macros"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
[lib]

View file

@ -1,6 +1,6 @@
[package]
name = "tests"
version = "0.13.3"
version = "0.13.4"
edition = "2024"
resolver = "2"