@@ -9,6 +9,7 @@ private import codeql.ruby.DataFlow
99private import codeql.ruby.dataflow.FlowSummary
1010private import codeql.ruby.ApiGraphs
1111private import codeql.ruby.frameworks.stdlib.Logger:: Logger as StdlibLogger
12+ private import codeql.ruby.frameworks.data.ModelsAsData
1213
1314/**
1415 * Modeling for `ActiveSupport`.
@@ -138,4 +139,28 @@ module ActiveSupport {
138139 }
139140 }
140141 }
142+
143+ /**
144+ * `ActiveSupport::SafeBuffer` wraps a string, providing HTML-safe methods
145+ * for concatenation.
146+ * It is possible to insert tainted data into `SafeBuffer` that won't get
147+ * sanitized, and this taint is then propagated via most of the methods.
148+ */
149+ private class SafeBufferSummary extends ModelInput:: SummaryModelCsv {
150+ // TODO: SafeBuffer also reponds to all String methods.
151+ // Can we model this without repeating all the existing summaries we have
152+ // for String?
153+ override predicate row ( string row ) {
154+ row =
155+ [
156+ // SafeBuffer.new(x) does not sanitize x
157+ "activesupport;;Member[ActionView].Member[SafeBuffer].Method[new];Argument[0];ReturnValue;taint" ,
158+ // SafeBuffer#safe_concat(x) does not sanitize x
159+ "activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat];Argument[0];ReturnValue;taint" ,
160+ "activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[safe_concat];Argument[0];Argument[self];taint" ,
161+ // These methods preserve taint in self
162+ "activesupport;;Member[ActionView].Member[SafeBuffer].Instance.Method[concat,insert,prepend,to_s,to_param];Argument[self];ReturnValue;taint" ,
163+ ]
164+ }
165+ }
141166}
0 commit comments