On Tue, 1 May 2007 19:42:02 +1000, "John Beckett"
<[EMAIL PROTECTED]> wrote:

> Matthew Winn wrote:
> > If there was a security problem in Vim do you really think it
> > couldn't be exploited in 100 characters? That's a pretty shaky
> > foundation on which to build your security.
> 
> I am quite surprised at the lack of appreciation for the merits
> of "defense in depth" here. I am not claiming that a length
> limit would preclude damage, just that a modeline should be
> sanity checked before execution, and a reasonable length would
> be the first check.

What constitutes a "reasonable length"? Vim has to load the entire
document including its modeline into memory anyway, so there's no
denial-of-service implications in allowing unlimited modelines.
Your suggestion amounts to "I won't use a modeline longer than X,
so nobody will use a modeline longer than X".

My objection to your idea is that it won't improve security by even
the tiniest bit. It's not defence in depth at all. It's a worthless
measure that can't achieve anything useful and can only get in the
way of legitimate uses. Any modeline long enough to be useful for a
legitimate purpose must also be long enough to be useful for a hostile
one.

> It's sensational that Vim can process files with very long
> lines, for the occasions we need that. But it would be absurd
> for Vim to process a multi-megabyte modeline.

Where do you draw the line between absurd and reasonable? When I write
options I spell out the names in full so they're easier to understand
for someone who doesn't know Vim well. That means that my modelines
are quite long. But someone who wanted to save space could use the
abbreviated form of an option. That means that if a modeline can be
long enough to satisfy me it would give an attacker the ability to use
several times as many options to craft their exploit as are needed for
general use.

> By all means abuse me for my cheeky suggestion to limit
> modelines to 100 bytes, but while doing that you might agree
> that some limit under 1MB should be enforced.

Why?

In some places there are good reasons for limiting sizes. For example,
RFC2822 places a limit of 998 characters on the length of a line. The
reason for this is so that RFC2822-conforming applications don't have
to deal with data of arbitrary length and allocate unlimited buffers
to handle it. They can allocate a buffer 1001 characters long and
discard anything that won't fit in the buffer, thereby preventing the
possibility of denial-of-service attacks from someone sending a line
several hundred megabytes long.

Vim doesn't have that issue because it must load the entire file into
memory anyway. Vim already knows how to deal with long lines, so
there's no extra penalty incurred by a multi-megabyte modeline.

> > A web browser should be able to handle anything thrown at it
> > in a way that doesn't compromise security. _Every_ application
> > should be able to handle anything thrown at it in a way that
> > doesn't compromise security.
> 
> Even if a program is perfect now, a later change can introduce a
> bug. Any program which can automatically execute untrusted code
> should sanity-check the input as a separate step from
> sandboxing. That is standard Security 101 stuff - not my idea.

I've been working with computer security for over two decades. I know
about standard security stuff. I also know that security that doesn't
work is worse than no security at all, because it creates an illusion
of protection where none exists.

> > Perl and Vim have exactly the same requirements: the need to
> > safely handle code taken from an untrustworthy source. It
> > makes no difference whether it comes directly from a network
> > or from a disk. (If, like me, you use Vim as your source
> > viewer for web pages, the need for the same level of security
> > is obvious.)
> 
> It doesn't matter, but for the record, Perl's tainting system is
> not related to the scenario you describe. Perl wants to make
> sure that untrusted input is not later used as the basis for
> some expression that could do harm, such as executing SQL code.

That's what I meant, and that's exactly what Vim needs as well. Both
applications read data from a source that can't be trusted, and both
need to ensure that untrusted data can't be used in a situation where
it could be dangerous. In Vim's case it needs to make sure that an
expression used in an option set from a modeline can't be used later
in a way that would cause harm, such as executing a command.

Take a look at the original message. It sets foldmethod to something
that triggers the execution of an external command after the modeline
has been processed. Imagine you have a web page that contains the
following (with the real command removed so it can't cause problems,
just in case someone does view this in Vim; think of "rm -rf /"):

    <!--
    vim: fdm=expr fde=feedkeys("\\:!dangerous-command-here\\<cr>")
    -->

Now imagine that someone uses Vim as their browser's "view source"
application. That's _exactly_ the thing Perl's tainting mechanism is
designed to prevent, and that's exactly what Vim must prevent too.

-- 
Matthew Winn

Reply via email to