Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Mailer] EsmtpTransport throws too much information into TransportException #45308

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

Closed
wikando-ck opened this issue Feb 4, 2022 · 1 comment
Closed

Comments

@wikando-ck
Copy link
Contributor

Symfony version(s) affected

4.3-6.1

Description

When throwing a TransportException during authentication in EsmtpTransport, multiple authenticators are tried and their exceptions are collected in an array.
To generate the exception message for the resulting TransportException, this array is iterated and the exception is cast to string, leading to a full stack trace being passed inside the exception message.

        # https://github.com/symfony/mailer/blob/6.1/Transport/Smtp/EsmtpTransport.php:190
        $message = sprintf('Failed to authenticate on SMTP server with username "%s" using the following authenticators: "%s".', $this->username, implode('", "', $authNames));
        foreach ($errors as $name => $error) {
            $message .= sprintf(' Authenticator "%s" returned "%s".', $name, $error);
        }

When displaying the exception message to a user, there is way too much information about the backend inside and it is unreadable.

How to reproduce

Use a mailer with SMTPS, with invalid credentials and catch the resulting exception.
echo $exception->getMessage()

Possible Solution

Instead of the exception being cast to a string, $error->getMessage() should be used.

        $message = sprintf('Failed to authenticate on SMTP server with username "%s" using the following authenticators: "%s".', $this->username, implode('", "', $authNames));
        foreach ($errors as $name => $error) {
-            $message .= sprintf(' Authenticator "%s" returned "%s".', $name, $error);
+            $message .= sprintf(' Authenticator "%s" returned "%s".', $name, $error->getMessage());
        }

Additional Context

I'm happy to provide a PR.

@wikando-ck wikando-ck added the Bug label Feb 4, 2022
@wikando-ck wikando-ck changed the title [Mailer] ESmtpTransport throws too much information into TransportException [Mailer] EsmtpTransport throws too much information into TransportException Feb 4, 2022
@fabpot
Copy link
Member

fabpot commented Feb 4, 2022

Looks good to me, please submit a PR on 4.4.

@fabpot fabpot closed this as completed Feb 7, 2022
fabpot added a commit that referenced this issue Feb 8, 2022
…ator in EsmtpTransport (wikando-ck)

This PR was merged into the 4.4 branch.

Discussion
----------

[Mailer] Fix string-cast of exceptions thrown by authenticator in EsmtpTransport

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #45308
| License       | MIT

Replace an exception that was being cast to string with a call to `getMessage()`.
This prevents information about the system leaking into the exception, (files/directories, stack trace).

Additionally (see https://symfony.com/releases):

I wasn't able to inject mocked authenticators, as they are instantiated in the constructor.
This makes unit testing very hard.
I was able to reproduce the problem with this test, but it will hit a real smtp server and should not be added to a testsuite.

```php
   // EsmtpTransportTest.php

    public function testAuthExceptionContainsNoStackTrace()
    {
        $transport = new EsmtpTransport('smtp.ionos.de', 465, true);
        $transport->setUsername("test");
        $transport->setPassword("test");
        $message = new Message();
        $message->setHeaders(new Headers(
            new MailboxListHeader("From", [Address::create('[email protected]')]),
            new MailboxListHeader("To", [Address::create('[email protected]')]))
        );
        try {
            $transport->send($message);
            $this->fail("Expected TransportException");
        } catch (TransportExceptionInterface $e) {
            $this->assertStringNotContainsString("Stack trace:", $e->getMessage());
            $this->assertStringNotContainsString('Symfony\Component\Mailer\Transport\Smtp', $e->getMessage());
        }
    }
```

Commits
-------

7310ea5 [Mailer] Fix string-cast of exceptions thrown by authenticator in EsmtpTransport
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants