ConradIrwin / em-imap

An event machine based IMAP client
MIT License
69 stars 31 forks source link

Security Fix for Man-in-the-Middle - huntr.dev #27

Closed huntr-helper closed 4 years ago

huntr-helper commented 4 years ago

https://huntr.dev/users/alromh87 has fixed the Man-in-the-Middle vulnerability 🔨. alromh87 has been awarded $25 for fixing the vulnerability through the huntr bug bounty program 💵. Think you could fix a vulnerability like this?

Get involved at https://huntr.dev/

Q | A Version Affected | ALL Bug Fix | YES Original Pull Request | https://github.com/418sec/em-imap/pull/1 GitHub Issue | https://github.com/ConradIrwin/em-imap/issues/25 Vulnerability README | https://github.com/418sec/huntr/blob/master/bounties/rubygems/em-imap/1/README.md

User Comments:

📊 Metadata *

em-imap is a gem that allows you to connect to an IMAP4rev1 server in a non-blocking fashion.

Affected versions of this package are vulnerable to Man-in-the-Middle (MitM). The hostname in a TLS server certificate is not verified. An attacker can acquire the identity of a trusted server and implement malicious data.

Bounty URL: https://www.huntr.dev/bounties/1-rubygems-em-imap/

⚙️ Description *

SSL validation was not implemented making em-imap vulnerable to MiM attacks, fixed adding validations.

💻 Technical Description *

ssl_verify_peer param is eneabled when calling connect from EventMachine::Connection, this will call ssl_verify_peer and ssl_handshake_completed of the connection module for the calling programm to implement validation logic.

Validation of Server certificate was implemented using openssl based on code from: https://github.com/lostisland/faraday/commit/63cf47c95b573539f047c729bd9ad67560bc83ff

🐛 Proof of Concept (PoC) *

  1. Add a fake DNS entry to /etc/hosts. echo "127.0.0.1 test.imap.gmail.com" | sudo tee -a /etc/hosts

  2. Create a certificate. openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes

  3. Listen on port 443 with TLS enabled. openssl s_server -key key.pem -cert cert.pem -accept 443

  4. Create sample client:

    
    #clientPoc.rb
    require 'rubygems'
    require 'em-imap'

EM::run do client = EM::IMAP.new('test.imap.gmail.com', 993, true) client.connect.errback do |error| puts "Connecting failed: #{error}" end.callback do |hello_response| puts "Connecting succeeded!" puts hello_response end.bothback do EM::stop end end


5. Run the test client
`ruby clientPoc.rb`
6. Client will connect ignoring the self signed certificate

![Captura de pantalla de 2020-09-14 01-48-21](https://user-images.githubusercontent.com/7505980/93030555-98c0fd80-f62c-11ea-866d-7906e2c768db.png)

### 🔥 Proof of Fix (PoF) *

After fix Invalid certificate is detected and connection terminated

![Captura de pantalla de 2020-09-14 01-49-05](https://user-images.githubusercontent.com/7505980/93030553-9494e000-f62c-11ea-9ce0-1f4e466ce708.png)

Valid certificate for wrong server will also be detected and connection aborted

![imapWrogN](https://user-images.githubusercontent.com/7505980/93030414-98743280-f62b-11ea-9ca6-ae9c2edf5c49.png)

### 👍 User Acceptance Testing (UAT)

After fix functionality is unafected

![imapOK](https://user-images.githubusercontent.com/7505980/93030424-ab870280-f62b-11ea-8cbf-defe5394367a.png)
ConradIrwin commented 4 years ago

Thanks!