Skip to content

Commit 828064f

Browse files
committed
Close code injection vulnerabilit in LIST and NLST.
This is quick piece of plywood over the hole. It still allows arbitrary ls switches (yuck), and breaks globbing. LIST and NLST need to be rewritten to not shell out to ls. The vulnerability was discovered by Larry. W. Cashdollar.
1 parent 21016c1 commit 828064f

7 files changed

Lines changed: 16 additions & 15 deletions

File tree

Changelog.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
### dev
1+
### 0.2.2
22

33
Bug fixes
44

@@ -8,6 +8,9 @@ Bug fixes
88
PASS
99
* Open PASV mode data connection on same local IP as control connection.
1010
This is required by RFC 1123.
11+
* Disabled globbing in LIST (for now) due to code injection
12+
vulnerability. This patch also disables globbing in NLST, but NLST
13+
probably shouldn't do globbing.
1114

1215
Enhancements
1316

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ _and_ for advertising to the client which IP to connect to. Binding
103103
to 0.0.0.0 will work fine, but when the client tries to connect to
104104
0.0.0.0, it won't get to the server.
105105

106+
LIST doesn't accept globs. It has other problems (it accepts
107+
arbitrary ls arguments!) and needs to be rewritten to not shell out to
108+
"ls".
109+
106110
## RUBY COMPATABILITY
107111

108112
The tests pass with these Rubies:

doc/rfc-compliance.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Commands supported:
2929
CDUP Yes 0.1.0 Change to parent directory
3030
CWD Yes 0.1.0 Change working directory
3131
DELE Yes 0.1.0 Delete file
32-
HELP Yes dev Help
32+
HELP Yes 0.2.2 Help
3333
LIST Yes 0.1.0 List directory
3434
MKD Yes 0.2.1 Make directory
3535
MODE Yes 0.1.0 Set transfer mode
@@ -52,7 +52,7 @@ Commands supported:
5252
SMNT No --- Structure Mount
5353
STAT No --- Server status
5454
STOR Yes 0.1.0 Store file
55-
STOU Yes dev Store with unique name
55+
STOU Yes 0.2.2 Store with unique name
5656
STRU Yes 0.1.0 Set file structure
5757
Supports "File" structure only. "Record" and
5858
"Page" are not supported

features/ftp_server/list.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Feature: List
4242
And the file list should contain "foo"
4343

4444
Scenario: Glob
45+
Given PENDING "Disabled (for now) due to code injection vulnerability"
4546
Given a successful login
4647
And the server has file "foo"
4748
And the server has file "bar"

features/ftp_server/name_list.feature

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,6 @@ Feature: Name List
4141
Then the file list should be in short form
4242
And the file list should contain "foo"
4343

44-
Scenario: Glob
45-
Given a successful login
46-
And the server has file "foo"
47-
And the server has file "bar"
48-
When the client successfully name-lists the directory "f*"
49-
Then the file list should be in short form
50-
And the file list should contain "foo"
51-
And the file list should not contain "bar"
52-
5344
Scenario: Passive
5445
Given a successful login
5546
And the server has file "foo"

lib/ftpd.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'memoizer'
33
require 'openssl'
44
require 'pathname'
5+
require 'shellwords'
56
require 'socket'
67
require 'tmpdir'
78

lib/ftpd/disk_file_system.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ class DiskFileSystem
206206

207207
module Ls
208208

209+
include Shellwords
210+
209211
def ls(ftp_path, option)
210212
path = expand_ftp_path(ftp_path)
211213
dirname = File.dirname(path)
@@ -214,11 +216,10 @@ def ls(ftp_path, option)
214216
'ls',
215217
option,
216218
filename,
217-
'2>&1',
218-
].compact.join(' ')
219+
].compact
219220
if File.exists?(dirname)
220221
list = Dir.chdir(dirname) do
221-
`#{command}`
222+
`#{shelljoin(command)} 2>&1`
222223
end
223224
else
224225
list = ''

0 commit comments

Comments
 (0)