Bruno Haible via Gnulib discussion list <[email protected]> writes:

> Simon Josefsson wrote:
>> Bruno Haible via Gnulib discussion list <[email protected]> writes:
>> 
>> >   - The security of the translations is guaranteed through the workflow
>> >     (xgettext marks the string with '#, c-format', then 'msgfmt -c' 
>> > verifies
>> >     the compatibility of the format string directives in the translation).
>> 
>> Is that protection really complete?  Consider a
>> 
>> printf (_("foo"));
>> 
>> expression, and a maliciously crafted translation.  Could that crash?
>
> For printf (string) to crash, string must be NULL — which cannot occur as
> the result of gettext() — or string must contain at least one format
> directive that consumes an argument — but 'msgfmt -c' prevents that.

The format directive must also match the types, do msgfmt -c check that?

I'm thinking if someone changed the translation file for

  int foo = 42;
  printf (_("foo %d"), foo);

so that _("foo %d") returned "foo %s", then this would become an
out-of-bounds memory de-reference.

>> I suppose the protection then is that translation files ought to be as
>> well protected as the binary itself
>
> Yes, unless some environment variable is specified (LANGUAGE or NLSPATH).
> But anyone who sets an environment variable can also change the PATH
> and thus cause a different program to be invoked than the intended one.

Agreed.

>> and that the code that loads the
>> translations are carefully written to never load anything that is
>> outside of a trusted installation.
>
> This is glibc code since 1998 or so.
>
>> But that seems a bit fragile.
>
> Please come up with an attack that is not defended against.

My argument was about complexity -- sometimes it is worth defending
against an entire class of attack that is theoretical if the price for
the defence is low.

Anything involving searching file paths, environment variables and
reading files that could be malicious -- and glibc 1998-era code :) --
may be concerns.

>> Some defense in depth against translation message confusion doesn't seem
>> entirely unreasonable IMHO, and the cost of changing the calls into
>> 
>> printf ("%s", _("foo"));
>
> Many format strings take arguments:
>   printf (_("foo %d bar"), i);
> and you can't change these easily. So, what do you gain by changing the
> printf calls with 0 arguments after the format string? Nothing. You have
> silenced a silly clang warning, and because this warning carries the
> word "security" in it, you think you have made your program more secure.
> But in fact, you have only been fooled into thinking that.

This seems like a deal-breaker though, as I don't see any reasonable way
to improve that snippet that doesn't make the code rather ugly, so now I
agree with you.

/Simon

Attachment: signature.asc
Description: PGP signature

Reply via email to