On Wed, Oct 04, 2017 at 05:07:07AM +0200, Willy Tarreau wrote:
> On Wed, Oct 04, 2017 at 04:40:53AM +0200, Willy Tarreau wrote:
> > On Tue, Oct 03, 2017 at 06:57:45PM +0200, Marcus Ulbrich wrote:
> > > Hey Jarno,
> > >
> > > This seems to work stable!
> > > The idea for this acl was to prevent attackers testing for example MySQL
> > > injection by sleep command. ,,sleep" is in none of our URLs!
> > > Do you have an idea about an acl about this not crashing haproxy?
> >
> > I wouldn't be surprized if there was an issue for example with a %00 causing
> > a length mismatch between two parts. At least now we have an idea where to
> > look for the bug. It shouldn't take very long anymore to spot the problem.
>
> I'm seeing an issue in the url_dec sample converter :
>
> static int sample_conv_url_dec(const struct arg *args, struct sample
> *smp, void
> *private)
> {
> /* If the constant flag is set or if not size is avalaible at
> * the end of the buffer, copy the string in other buffer
> * before decoding.
> */
> if (smp->flags & SMP_F_CONST || smp->data.u.str.size <=
> smp->data.u.str.
> len) {
> struct chunk *str = get_trash_chunk();
> memcpy(str->str, smp->data.u.str.str,
> smp->data.u.str.len);
>
> Here it's missing a check to ensure that str.len <= str.size. Normally there
> is no known case where this could happen, but the preferred smp_dup() performs
> the check and truncates the input if needed. I don't know if there's a reason
> for this to ever happen. Hmmm in fact there's one theorical case where it
> could
> happen, it's if the sample contains a full buffer (str.len == str.size), and
> then we can overflow the block by one byte when writing the trailing zero. But
> it's not possible in HTTP since the request is at least a few bytes long, and
> there's the reserve.
>
> smp->data.u.str.str = str->str;
> smp->data.u.str.size = str->size;
> smp->flags &= ~SMP_F_CONST;
> }
>
> So if you're interested, you can replace the block above by this :
> if (smp->flags & SMP_F_CONST || smp->data.u.str.size <=
> smp->data.u.str.
> len)
> smp_dup(smp);
>
> If this stops crashing we'll have to try to figure in which situation the
> case above may happen :-/
By the way if you manage to print the contents of "smp" in
sample_conv_str2lower() it could help, at least to find smp->str.{len,size}.
Willy