FreeAndNil commented on PR #329:
URL: https://github.com/apache/logging-log4net/pull/329#issuecomment-6122125149

   Implementation plan for #329, kept here for the record. Revised after the 
merge so that it describes the change as it landed.
   
   <details>
   <summary>Plan</summary>
   
   # PR #329: require transport security in the Ext.Mail SmtpAppender
   
   ## Context
   
   f026 of scan `da18b6fd`, the last undecided finding: `log4net.Ext.Mail`'s 
`SmtpAppender` defaults to
   `TransportSecurity = SmtpTransportSecurity.None`, so the mail body, and with 
`Basic` or `Ntlm`
   configured the SMTP credentials, cross the network in cleartext unless the 
operator finds the knob.
   A network-adjacent attacker on the path to the relay captures both 
passively. The panel split 3/2,
   the majority holding that an insecure security-relevant default in new code 
is not operator
   configuration, because the operator did nothing.
   
   **Decision: flip the default to `Required`.** Implicit TLS on port 465, 
mandatory `STARTTLS` on
   every other port, connection fails rather than continuing in cleartext. The 
opt-out is the existing
   setting, `TransportSecurity=None` or `EnableSsl=false`, so no new API.
   
   The package shipped in **3.4.0**, so this lands on existing users: a relay 
on port 25 that offers no
   `STARTTLS` stops working on upgrade. The blast radius is one to five users 
in total, so the
   compatibility argument that decided f005 does not reach here, and two things 
separate the cases
   anyway. Say both in the commit message and keep the changelog to the opt-out:
   
   - f005's raw-SQL fallback is a configuration the operator **chose**, is 
documented, and warns at
     startup. Removing it takes away a working deployment with no replacement.
   - f026 is a default **nobody chose**. The fix is one line of configuration 
away for anyone who
     really wants cleartext, and the failure is loud at connect time rather 
than silent on the wire.
   
   `#310` already built the machinery in 3.4.0: `TransportSecurity`, 
`EnableSsl` as its shorthand, and
   `ResolveSecureSocketOptions` deliberately avoiding MailKit's downgrade-prone 
`Auto`. This changes
   one initialiser and the documentation around it, in one commit.
   
   ## Branch
   
   `Feature/329-ext-mail-tls-default`, branched from the **#328 tip** 
(`81efd407`) while #328 is open,
   the way #324 branched off #323. `git switch -c` from the local branch, never 
off a remote ref.
   
   ## The change
   
   `src/log4net.Ext.Mail/Appender/SmtpAppender.cs`
   
   ```csharp
   public SmtpTransportSecurity TransportSecurity { get; set; } = 
SmtpTransportSecurity.Required;
   ```
   
   Everything else follows from it and must be updated in the same commit:
   
   - The `<value>` doc on `TransportSecurity` says "The default is `None`". It 
becomes `Required`, with
     one sentence naming `None` as the opt-out for a cleartext connection.
   - `EnableSsl` is `TransportSecurity != None`, so **its default flips from 
`false` to `true`**. Its
     `<remarks>` must say so: this is the property most configurations touch, 
and its old default
     matched `System.Net.Mail.SmtpClient.EnableSsl`, which it no longer does. 
The sentence reads
     "which matches the behaviour, though not the default, of" that property.
   - `Port` stays 25, so the default resolves to 
`SecureSocketOptions.StartTls`, not `SslOnConnect`.
     That is the behaviour users will actually meet.
   
   `src/log4net.Ext.Mail/README.md`
   
   - Line 86, "`enableSsl` - negotiate TLS/STARTTLS (true/false, default: 
false)" becomes "require
     TLS/STARTTLS (true/false, default: true)", and a `transportSecurity` 
bullet follows it listing
     the five values with `Required` marked as the default.
   - Lines 67 and 70 still describe the transport as "Full (Auto, Explicit, 
Implicit)" and `enableSsl`
     as "negotiates Auto/None", which #310 made wrong: `Required` never uses 
`Auto`. That is the text
     behind f027, which the scan filed as a false positive and which is 
nonetheless stale. The TLS row
     lists the four secured values, the `enableSsl` row shows both defaults, 
`false` built in and
     `true` here. Fix it here rather than leaving a contradiction in the file 
we are editing, and say
     so in the commit message.
   
   
`src/site/antora/modules/ROOT/pages/manual/configuration/appenders/smtpappender.adoc`
 documents both
   properties, so it changes in four places: the `enableSsl` row defaults to 
`true`, the
   `transportSecurity` row lists `Required` first as the default, the `None` 
and `Required` rows of the
   value table swap which one says "the default" (`None` becomes "the opt-out 
from the secure
   default"), and the migration paragraph says `enableSsl` keeps its meaning 
but not its default, so a
   configuration that set neither option now requires transport security.
   
   ## Tests
   
   `src/log4net.Ext.Mail.Tests/Appender/SmtpAppenderTest.cs`. The fixture 
drives a hand-written
   `FakeSmtpTransport` that records `SecureSocketOptions` from `Connect`, so 
every assertion here is
   exact and offline. Three existing tests encode the old default and must 
change:
   
   - `EnableSslOffConnectsWithoutTransportSecurity` calls `CreateAppender()` 
and asserts
     `SecureSocketOptions.None` **without ever setting `EnableSsl`**. It has to 
set
     `appender.EnableSsl = false` explicitly, which is what its name always 
claimed it did.
   - `EnableSslIsAShorthandForTransportSecurity` asserts a fresh appender is 
`None` and `EnableSsl`
     false. It starts by setting `EnableSsl = false` and asserting `None`, 
keeps the round trip
     through `Required` and `StartTlsWhenAvailable`, and closes by setting 
`TransportSecurity` to
     `None` and asserting `EnableSsl` false, so both directions of the 
shorthand are still covered.
   - `DefaultConstructorUsesTheMailKitTransport` asserts the defaults of a 
fresh appender, among them
     `EnableSsl` false, which becomes true.
   
   New, and red against the old code, each with a doc comment:
   
   - `TransportSecurityDefaultsToRequired`, a one-line property assertion.
   - `EnableSslDefaultsToTrue`, because that public property's default is part 
of the break.
   - `TheDefaultConnectionRequiresStartTls`: `CreateAppender()`, `Append`, 
assert
     `SecureSocketOptions.StartTls` on the default port 25. This is the 
regression test for the
     finding, and it takes the place of `EnableSslOnRequiresStartTls`, whose 
explicit `EnableSsl =
     true` now says nothing the default does not.
   
   ## Changelog
   
   `src/changelog/3.5.0/329-ext-mail-tls-by-default.xml`, `type="changed"`, 
issue 329 with both `id`
   and `link`. The description names the weakness class (CWE-319) and the 
opt-out, so an upgrade
   surprise is searchable, the way the `SendTimeoutMillis`, 
`MatchTimeoutMillis` and
   `LockTimeoutMillis` entries do, and closes with `(audit da18b6fd-f026, 
implemented by @FreeAndNil)`.
   Prose only, no bullets.
   
   Answer the scan on the finding as a decision: we took the majority position 
and accept the break
   it costs, and f005 went the other way for a reason that does not apply here.
   
   ## Verification
   
   ```
   dotnet build src/log4net.sln                                              # 
0 warnings, both TFMs
   dotnet test  src/log4net.Ext.Mail.Tests/log4net.Ext.Mail.Tests.csproj     # 
50 before, 52 after
   dotnet test  src/log4net.Tests/log4net.Tests.csproj -f net10.0            # 
424, unchanged
   ```
   
   - Revert the one-line default in place, no stash, and confirm the three new 
tests fail.
   - The whole change is offline: `FakeSmtpTransport` means no relay and no 
network in the suite.
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to