Password authentication leaves plaintext password copies in managed memory
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 45/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- csharp
- Lĩnh vực
- authentication, networking, security
Hướng nghiên cứu
Start with PasswordAuthenticationMethod.Authenticate and trace the flow through Session.SendMessage(RequestMessagePassword) and Session.SendPacket. Reproduce the memory-dump scenario with a unique test password, then add regression coverage for clearing password storage, serialized request data, and plaintext packet buffers after use.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description
SSH.NET password authentication appears to leave plaintext password data
in managed memory after authentication has completed.
This was discovered during a penetration test by inspecting a process memory
dump after establishing an SSH connection using password authentication.
There appear to be at least two sources of password residue.
PasswordAuthenticationMethod retains the password
PasswordAuthenticationMethod stores the supplied password internally as a
byte array.
When the string-based API is used, the password must additionally exist as a
System.String. Since System.String is immutable, that copy cannot be
explicitly cleared.
The internal byte[] containing the encoded password also appears to remain
allocated after authentication instead of being zeroed when it is no longer
required.
As a result, the plaintext password can remain recoverable from a process
memory dump after authentication.
Serialized SSH_MSG_USERAUTH_REQUEST remains in memory
Using the byte[] password overload reduces the problem because the caller can
clear its own password buffer.
However, this does not eliminate all plaintext copies.
During password authentication the password is serialized into the
SSH_MSG_USERAUTH_REQUEST message.
The relevant flow appears to be approximately:
PasswordAuthenticationMethod.Authenticate
-> Session.SendMessage(RequestMessagePassword)
-> message serialization
-> Session.SendPacket(...)
The serialized packet contains the password in plaintext before SSH transport
encryption is applied.
After the packet has been encrypted/sent, buffers containing the plaintext
packet do not appear to be explicitly zeroed.
In a process memory dump taken after authentication, we were able to locate a
complete plaintext SSH user authentication request containing the password.
Expected behavior
Sensitive authentication data should have the shortest practical lifetime in
memory.
After password authentication has completed, SSH.NET should explicitly clear
buffers that contain:
- the password stored by PasswordAuthenticationMethod;
- temporary encoded password representations;
- serialized SSH_MSG_USERAUTH_REQUEST payloads containing a password;
- temporary packet/plaintext buffers used before encryption.
For byte arrays/spans this could potentially use Array.Clear,
CryptographicOperations.ZeroMemory, or an equivalent mechanism appropriate
for the supported target frameworks.
The goal is not to guarantee that a password can never exist in plaintext
memory. Password authentication necessarily requires SSH.NET to process the
plaintext password.
The goal is to avoid leaving unnecessary plaintext copies recoverable from a
memory dump after those buffers are no longer required.
Why the byte[] overload alone does not solve this
Applications can avoid keeping a managed System.String by obtaining the
credential through a protected representation and creating a temporary byte[]
for SSH.NET.
The application can zero its own byte[] immediately afterwards.
However, once SSH.NET serializes SSH_MSG_USERAUTH_REQUEST, additional
plaintext copies are created internally. Those copies are outside the
caller's control and therefore cannot be cleared by the application.
Consequently this cannot be fully mitigated by callers of SSH.NET.
Security impact
An attacker or diagnostic process capable of obtaining a process memory dump
after SSH authentication may be able to recover the SSH password even though
authentication has already completed.
This is particularly relevant for long-running applications where SSH
connections are created periodically and credentials should not remain
recoverable for the lifetime of the process.
Environment
Observed with password authentication using Renci.SshNet / SSH.NET.
The same behavior should be reproducible by:
- Connect to an SSH server using password authentication.
- Allow authentication to complete.
- Disconnect and dispose the SSH client.
- Force GC if desired.
- Capture a process memory dump.
- Inspect the dump for the known test password.
A unique test password can be used to make identification unambiguous.
Possible direction
A complete fix probably requires handling this at more than one level.
- Avoid unnecessary conversion of password credentials to System.String.
- Clear PasswordAuthenticationMethod password storage when it is no longer
required. - Clear credential-containing RequestMessagePassword storage when
authentication completes. - Clear plaintext serialization/packet buffers after they have been
encrypted or are otherwise no longer needed. - Add regression tests verifying that sensitive buffers are zeroed after
use where practical.
- Ngôn ngữ chính
- C#
- Star
- 4.4k
- Fork
- 990
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của sshnet/SSH.NET
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
-
ShellStream.Expect over-discards on undecodable bytes, driving ArrayBuffer.ActiveLength negativeĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 68/100
-
Using SshClient on Linux under Wine throws System.Security.Cryptography.CryptographicExceptionĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 67/100
Tất cả issue của sshnet/SSH.NET
Issue tương tự
-
[C#]:主页联网更新的提示投稿横幅指向错误Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
PCL-Community/PCL-CE#3652 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area:frontend bug FE P3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
klasolsson81/jobbliggaren#2010 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[aw] Upgrade availableĐang mởagentic-workflows untriaged
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 1 ngày
-
area: homeblaze type: bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
RicoSuter/Namotion.Interceptor#630 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Akka.Hosting enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100