Skip to content

Commit 97e8e0b

Browse files
committed
Add String Manipulation Method Calls & CGI.escapeHTML() support
1 parent f7f0564 commit 97e8e0b

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

ruby/ql/lib/codeql/ruby/experimental/UnicodeBypassValidationQuery.qll

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ private import ruby
66
private import codeql.ruby.dataflow.RemoteFlowSources
77
private import codeql.ruby.Concepts
88
private import codeql.ruby.TaintTracking
9+
private import codeql.ruby.ApiGraphs
910
import UnicodeBypassValidationCustomizations::UnicodeBypassValidation
1011

1112
/** A state signifying that a logical validation has not been performed. */
@@ -39,8 +40,40 @@ class Configuration extends TaintTracking::Configuration {
3940
exists(Escaping escaping | nodeFrom = escaping.getAnInput() and nodeTo = escaping.getOutput())
4041
or
4142
exists(RegexExecution re | nodeFrom = re.getString() and nodeTo = re)
42-
// or
43-
// stringManipulation(nodeFrom, nodeTo)
43+
or
44+
// String Manipulation Method Calls
45+
// https://ruby-doc.org/core-2.7.0/String.html
46+
exists(DataFlow::CallNode cn |
47+
cn.getMethodName() =
48+
[
49+
[
50+
"ljust", "lstrip", "succ", "next", "rjust", "capitalize", "chomp", "gsub", "chop",
51+
"downcase", "swapcase", "uprcase", "scrub", "slice", "squeeze", "strip", "sub",
52+
"tr", "tr_s", "reverse"
53+
] + ["", "!"], "concat", "dump", "each_line", "replace", "insert", "inspect", "lines",
54+
"partition", "prepend", "replace", "rpartition", "scan", "split", "undump",
55+
"unpack" + ["", "1"]
56+
] and
57+
nodeFrom = cn.getReceiver() and
58+
nodeTo = cn
59+
)
60+
or
61+
exists(DataFlow::CallNode cn |
62+
cn.getMethodName() =
63+
[
64+
"casecmp" + ["", "?"], "center", "count", "each_char", "index", "rindex", "sum",
65+
["delete", "delete_prefix", "delete_suffix"] + ["", "!"],
66+
["start_with", "end_with" + "eql", "include"] + ["?", "!"], "match" + ["", "?"],
67+
] and
68+
nodeFrom = cn.getReceiver() and
69+
nodeTo = nodeFrom
70+
)
71+
or
72+
exists(DataFlow::CallNode cn |
73+
cn = API::getTopLevelMember("CGI").getAMethodCall("escapeHTML") and
74+
nodeFrom = cn.getArgument(0) and
75+
nodeTo = cn
76+
)
4477
) and
4578
stateFrom instanceof PreValidation and
4679
stateTo instanceof PostValidation

0 commit comments

Comments
 (0)