Open Bug 201030 Opened 22 years ago Updated 5 years ago

"All of the words" query shouldn't use quotemeta()

Categories

(Bugzilla :: Query/Bug List, defect)

2.17.3
defect
Not set
normal

Tracking

()

People

(Reporter: justdave, Unassigned)

References

(Blocks 1 open bug)

Details

If you create a keyword that contains a single quote and then try to search on it, it generates an SQL error because of an unclosed quote. This sounds dangerous, but fortunately, it's not easily exploitable, because it does check to make sure the keyword exists before it generates the SQL to query on it, so the admin would have had to put something dangerous as part of the keyword for it to break anything.
This only happens with "all of the keywords". Any other search method works.
Securing. It's more widespread than keywords. This happens any time you put a single quote in a search term on any of the text boxes and choose "all of the words" as the search type.
Group: webtools-security
Summary: Keywords not SqlQuoted in queries → "All of the words" not SqlQuoted in queries
Whiteboard: [want for 2.16.3][want for 2.17.4]
There is an SqlQuote call in there, but it also has a quotemeta call inside that... where is quotemeta defined? I can't find it in DBI or any of Bugzilla's modules....
ok, found quotemeta, it's a perl builtin. quotemeta Returns the value of EXPR with all non-"word" characters backslashed. (That is, all characters not matching "/[A-Za-z_0-9]/" will be preceded by a backslash in the returned string, regardless of any locale settings.) This is the internal function implementing the "\Q" escape in double-quoted strings. Which makes me wonder, because the ' is getting prefixed with a period, not a backslash, in the generated SQL
I can't repro this - can you give me a search string. (I did discover that Search.pm needs to |use Error| at the top, but thats a separate bug I'll deal with this evening)
OK, I think the exploitable part of this may be specific to Sybase... We get away with it on MySQL because MySQL uses the same escaping method that Perl does. It's the interaction between SqlQuote and quotemeta that's doing it. If you enter "can'tyell", then quotemeta turns it into "can\'tyell". SqlQuote on MySQL then turns it into "'can\\\'tyell'". SqlQuote on Sybase turns it into "'can\''tyell'". doubling the quote is the "official" method of quoting, so that's what $dbh->quote does on Sybase, but under some circumstances, \' works, too, so the first one looks like it's part of the string, and the second one ends the string in the middle.... BTW, the regexp got changed to a LIKE $word with $word = SqlQuote('%$word%'); Is this worth bothering to fix on the trunk? otherwise we should close as invalid and just call it part of the Sybase translation headache...
Well, quotemeta isn't the right thing to use, because using it assumes that perl regexps are the same as db regexps, which they're not. LIKE is probably better, anyway, although you have to escape _ and % inside the string.
Since the "security" aspect of this only affects Sybase, and that's not actually public anywhere yet, removing the security flag.
Blocks: bz-zippy
Group: webtools-security
Summary: "All of the words" not SqlQuoted in queries → "All of the words" query shouldn't use quotemeta()
Whiteboard: [want for 2.16.3][want for 2.17.4]
Assignee: endico → nobody
Blocks: bz-sybase
QA Contact: mattyt-bugzilla → default-qa
Assignee: nobody → query-and-buglist
Whiteboard: [good first bug]

Removing good-first-bug keyword because team does not have bandwidth to mentor at the moment.

Keywords: good-first-bug

Removing outreachy because team does not have bandwidth to mentor this cycle.

Keywords: outreachy
Whiteboard: [good first bug]
You need to log in before you can comment on or make changes to this bug.