diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.model.json b/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.model.json new file mode 100644 index 000000000000..6d30ac4b1cc5 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.model.json @@ -0,0 +1,32 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + ["ActiveStorage::Filename!", "Method[new]", "Argument[0]", "ReturnValue", "taint"], + ["ActiveStorage::Filename", "Method[sanitized]", "Argument[self]", "ReturnValue", "taint"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "typeModel" + }, + "data": [ + // ActiveStorage::Blob.compose(blobs : [Blob]) : Blob + ["ActiveStorage::Blob", "ActiveStorage::Blob!", "Method[compose].ReturnValue"], + // ActiveStorage::Blob.create_and_upload! : Blob + ["ActiveStorage::Blob", "ActiveStorage::Blob!", "Method[create_and_upload!].ReturnValue"], + // ActiveStorage::Blob.create_before_direct_upload! : Blob + ["ActiveStorage::Blob", "ActiveStorage::Blob!", "Method[create_before_direct_upload!].ReturnValue"], + // ActiveStorage::Blob.find_signed(!) : Blob + ["ActiveStorage::Blob", "ActiveStorage::Blob!", "Method[find_signed,find_signed!].ReturnValue"] + ] + } + ] +} +// gives error: Invalid name 'Element' in access path +// - ['ActiveStorage::Blob', 'ActiveStorage::Blob!', 'Method[compose].Argument[0].Element[any]'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.model.yml deleted file mode 100644 index 2f1f2e56014f..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveStorage.model.yml +++ /dev/null @@ -1,22 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - - ['ActiveStorage::Filename!', 'Method[new]', 'Argument[0]', 'ReturnValue', 'taint'] - - ['ActiveStorage::Filename', 'Method[sanitized]', 'Argument[self]', 'ReturnValue', 'taint'] - - - addsTo: - pack: codeql/ruby-all - extensible: typeModel - data: - # ActiveStorage::Blob.compose(blobs : [Blob]) : Blob - - ['ActiveStorage::Blob', 'ActiveStorage::Blob!', 'Method[compose].ReturnValue'] - # ActiveStorage::Blob.create_and_upload! : Blob - - ['ActiveStorage::Blob', 'ActiveStorage::Blob!', 'Method[create_and_upload!].ReturnValue'] - # ActiveStorage::Blob.create_before_direct_upload! : Blob - - ['ActiveStorage::Blob', 'ActiveStorage::Blob!', 'Method[create_before_direct_upload!].ReturnValue'] - # ActiveStorage::Blob.find_signed(!) : Blob - - ['ActiveStorage::Blob', 'ActiveStorage::Blob!', 'Method[find_signed,find_signed!].ReturnValue'] - # gives error: Invalid name 'Element' in access path - # - ['ActiveStorage::Blob', 'ActiveStorage::Blob!', 'Method[compose].Argument[0].Element[any]'] \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.model.json b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.model.json new file mode 100644 index 000000000000..ea192c39c38e --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.model.json @@ -0,0 +1,39 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + // `ActiveSupport::SafeBuffer` wraps a string, providing HTML-safe methods + // for concatenation. + // It is possible to insert tainted data into `SafeBuffer` that won't get + // sanitized, and this taint is then propagated via most of the methods. + // + // TODO: SafeBuffer also reponds to all String methods. + // Can we model this without repeating all the existing summaries we have + // for String? + // SafeBuffer.new(x) does not sanitize x + ["ActionView::SafeBuffer!", "Method[new]", "Argument[0]", "ReturnValue", "taint"], + // These methods preserve taint in self + ["ActionView::SafeBuffer", "Method[concat,insert,prepend,to_s,to_param]", "Argument[self]", "ReturnValue", "taint"], + // SafeBuffer#safe_concat(x) does not sanitize x + ["ActionView::SafeBuffer", "Method[safe_concat]", "Argument[0]", "Argument[self]", "taint"], + ["ActionView::SafeBuffer", "Method[safe_concat]", "Argument[0]", "ReturnValue", "taint"], + ["ActiveSupport::JSON!", "Method[decode,load]", "Argument[0]", "ReturnValue", "taint"], + ["ActiveSupport::JSON!", "Method[encode,dump]", "Argument[0]", "ReturnValue", "taint"], + ["Pathname", "Method[existence]", "Argument[self]", "ReturnValue", "taint"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "typeModel" + }, + "data": [ + ["Pathname", "Pathname", "Method[existence].ReturnValue"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.model.yml deleted file mode 100644 index 8ec40cd4fbf1..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveSupport.model.yml +++ /dev/null @@ -1,30 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - # `ActiveSupport::SafeBuffer` wraps a string, providing HTML-safe methods - # for concatenation. - # It is possible to insert tainted data into `SafeBuffer` that won't get - # sanitized, and this taint is then propagated via most of the methods. - # - # TODO: SafeBuffer also reponds to all String methods. - # Can we model this without repeating all the existing summaries we have - # for String? - - # SafeBuffer.new(x) does not sanitize x - - ['ActionView::SafeBuffer!', 'Method[new]', 'Argument[0]', 'ReturnValue', 'taint'] - # These methods preserve taint in self - - ['ActionView::SafeBuffer', 'Method[concat,insert,prepend,to_s,to_param]', 'Argument[self]', 'ReturnValue', 'taint'] - # SafeBuffer#safe_concat(x) does not sanitize x - - ['ActionView::SafeBuffer', 'Method[safe_concat]', 'Argument[0]', 'Argument[self]', 'taint'] - - ['ActionView::SafeBuffer', 'Method[safe_concat]', 'Argument[0]', 'ReturnValue', 'taint'] - - ['ActiveSupport::JSON!', 'Method[decode,load]', 'Argument[0]', 'ReturnValue', 'taint'] - - ['ActiveSupport::JSON!', 'Method[encode,dump]', 'Argument[0]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[existence]', 'Argument[self]', 'ReturnValue', 'taint'] - - - addsTo: - pack: codeql/ruby-all - extensible: typeModel - data: - - ['Pathname', 'Pathname', 'Method[existence].ReturnValue'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Json.model.json b/ruby/ql/lib/codeql/ruby/frameworks/Json.model.json new file mode 100644 index 000000000000..bf0b2a8ac198 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Json.model.json @@ -0,0 +1,17 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + // Not all of these methods are strictly defined in the `json` gem. + // The `JSON` namespace is heavily overloaded by other JSON parsing gems such as `oj`, `json_pure`, `multi_json` etc. + // This summary covers common methods we've seen called on `JSON` in the wild. + ["JSON!", "Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse]", "Argument[0]", "ReturnValue", "taint"], + ["JSON!", "Method[parse,parse!,load,restore]", "Argument[0]", "ReturnValue", "taint"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Json.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/Json.model.yml deleted file mode 100644 index 3f53f9c224da..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/Json.model.yml +++ /dev/null @@ -1,11 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - # Not all of these methods are strictly defined in the `json` gem. - # The `JSON` namespace is heavily overloaded by other JSON parsing gems such as `oj`, `json_pure`, `multi_json` etc. - # This summary covers common methods we've seen called on `JSON` in the wild. - - ['JSON!', 'Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse]', 'Argument[0]', 'ReturnValue', 'taint'] - - ['JSON!', 'Method[parse,parse!,load,restore]', 'Argument[0]', 'ReturnValue', 'taint'] - \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.model.json b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.model.json new file mode 100644 index 000000000000..8084f4c357df --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.model.json @@ -0,0 +1,22 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + ["Mysql2::Client!", "Method[escape]", "Argument[0]", "ReturnValue", "taint"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "barrierModel" + }, + "data": [ + ["Mysql2::Client!", "Method[escape].ReturnValue", "sql-injection"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.model.yml deleted file mode 100644 index 1b6c8c754f57..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/Mysql2.model.yml +++ /dev/null @@ -1,11 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - - ['Mysql2::Client!', 'Method[escape]', 'Argument[0]', 'ReturnValue', 'taint'] - - addsTo: - pack: codeql/ruby-all - extensible: barrierModel - data: - - ['Mysql2::Client!', 'Method[escape].ReturnValue', 'sql-injection'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.model.json b/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.model.json new file mode 100644 index 000000000000..c290ed822da2 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.model.json @@ -0,0 +1,22 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + ["SQLite3::Database!", "Method[quote]", "Argument[0]", "ReturnValue", "taint"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "barrierModel" + }, + "data": [ + ["SQLite3::Database!", "Method[quote].ReturnValue", "sql-injection"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.model.yml deleted file mode 100644 index 13b7b5b48712..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/Sqlite3.model.yml +++ /dev/null @@ -1,11 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - - ['SQLite3::Database!', 'Method[quote]', 'Argument[0]', 'ReturnValue', 'taint'] - - addsTo: - pack: codeql/ruby-all - extensible: barrierModel - data: - - ['SQLite3::Database!', 'Method[quote].ReturnValue', 'sql-injection'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.model.json b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.model.json new file mode 100644 index 000000000000..425ab53a489c --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.model.json @@ -0,0 +1,17 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "typeModel" + }, + "data": [ + ["Mime::Type", "Mime!", "Method[fetch].ReturnValue"], + ["Mime::Type", "Mime::Type!", "Method[lookup].ReturnValue"], + ["Mime::Type", "Mime::Type!", "Method[lookup_by_extension].ReturnValue"], + ["Mime::Type", "Mime::Type!", "Method[register].ReturnValue"], + ["Mime::Type", "Mime::Type!", "Method[register_alias].ReturnValue"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.model.yml deleted file mode 100644 index 6d9827071d91..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Mime.model.yml +++ /dev/null @@ -1,10 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: typeModel - data: - - ['Mime::Type', 'Mime!', 'Method[fetch].ReturnValue'] - - ['Mime::Type', 'Mime::Type!', 'Method[lookup].ReturnValue'] - - ['Mime::Type', 'Mime::Type!', 'Method[lookup_by_extension].ReturnValue'] - - ['Mime::Type', 'Mime::Type!', 'Method[register].ReturnValue'] - - ['Mime::Type', 'Mime::Type!', 'Method[register_alias].ReturnValue'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.model.json b/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.model.json new file mode 100644 index 000000000000..11332bf7614b --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.model.json @@ -0,0 +1,13 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + ["Regexp!", "Method[escape,quote]", "Argument[0]", "ReturnValue", "taint"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.model.yml deleted file mode 100644 index bbeb585fe3d0..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Regexp.model.yml +++ /dev/null @@ -1,7 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - - ['Regexp!', 'Method[escape,quote]', 'Argument[0]', 'ReturnValue', 'taint'] - \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.json b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.json new file mode 100644 index 000000000000..4e44c891a5db --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.json @@ -0,0 +1,62 @@ +{ + "extensions": [ + // Make sure that the extensible model predicates have at least one definition + // to avoid errors about undefined extensionals. + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "sourceModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "sinkModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "barrierModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "barrierGuardModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "neutralModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "typeModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "typeVariableModel" + }, + "data": [] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml deleted file mode 100644 index ec68e8fcb380..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/empty.model.yml +++ /dev/null @@ -1,42 +0,0 @@ -extensions: - # Make sure that the extensible model predicates have at least one definition - # to avoid errors about undefined extensionals. - - addsTo: - pack: codeql/ruby-all - extensible: sourceModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: sinkModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: barrierModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: barrierGuardModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: neutralModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: typeModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: typeVariableModel - data: [] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/regexp/model.json b/ruby/ql/lib/codeql/ruby/frameworks/regexp/model.json new file mode 100644 index 000000000000..d62bf2978e62 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/regexp/model.json @@ -0,0 +1,13 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "barrierModel" + }, + "data": [ + ["Regexp!", "Method[escape,quote].ReturnValue", "regexp-injection"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/regexp/model.yml b/ruby/ql/lib/codeql/ruby/frameworks/regexp/model.yml deleted file mode 100644 index ca53942cedf5..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/regexp/model.yml +++ /dev/null @@ -1,6 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: barrierModel - data: - - ['Regexp!', 'Method[escape,quote].ReturnValue', 'regexp-injection'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.model.json b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.model.json new file mode 100644 index 000000000000..2dc29676d5d2 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.model.json @@ -0,0 +1,44 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + ["Pathname!", "Method[new]", "Argument[0]", "ReturnValue", "taint"], + ["Pathname", "Method[basename]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[cleanpath]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[dirname]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[each_filename]", "Argument[self]", "Argument[block].Parameter[0]", "taint"], + ["Pathname", "Method[expand_path]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[join]", "Argument[self,any]", "ReturnValue", "taint"], + ["Pathname", "Method[parent]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[realpath]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[relative_path_from]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[sub]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[sub_ext]", "Argument[self]", "ReturnValue", "taint"], + ["Pathname", "Method[to_path]", "Argument[self]", "ReturnValue", "taint"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "typeModel" + }, + "data": [ + ["Pathname", "Pathname", "Method[+].ReturnValue"], + ["Pathname", "Pathname", "Method[/].ReturnValue"], + ["Pathname", "Pathname", "Method[basename].ReturnValue"], + ["Pathname", "Pathname", "Method[cleanpath].ReturnValue"], + ["Pathname", "Pathname", "Method[expand_path].ReturnValue"], + ["Pathname", "Pathname", "Method[join].ReturnValue"], + ["Pathname", "Pathname", "Method[realpath].ReturnValue"], + ["Pathname", "Pathname", "Method[relative_path_from].ReturnValue"], + ["Pathname", "Pathname", "Method[sub].ReturnValue"], + ["Pathname", "Pathname", "Method[sub_ext].ReturnValue"], + ["Pathname", "Pathname", "Method[to_path].ReturnValue"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.model.yml deleted file mode 100644 index 1c1d128ccfc1..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.model.yml +++ /dev/null @@ -1,34 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - - ['Pathname!', 'Method[new]', 'Argument[0]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[basename]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[cleanpath]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[dirname]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[each_filename]', 'Argument[self]', 'Argument[block].Parameter[0]', 'taint'] - - ['Pathname', 'Method[expand_path]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[join]', 'Argument[self,any]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[parent]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[realpath]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[relative_path_from]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[sub]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[sub_ext]', 'Argument[self]', 'ReturnValue', 'taint'] - - ['Pathname', 'Method[to_path]', 'Argument[self]', 'ReturnValue', 'taint'] - - - addsTo: - pack: codeql/ruby-all - extensible: typeModel - data: - - ['Pathname', 'Pathname', 'Method[+].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[/].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[basename].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[cleanpath].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[expand_path].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[join].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[realpath].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[relative_path_from].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[sub].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[sub_ext].ReturnValue'] - - ['Pathname', 'Pathname', 'Method[to_path].ReturnValue'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Shellwords.model.json b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Shellwords.model.json new file mode 100644 index 000000000000..aee8d1d38fb0 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Shellwords.model.json @@ -0,0 +1,22 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + ["Shellwords!", "Method[escape,shellescape]", "Argument[0]", "ReturnValue", "taint"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "barrierModel" + }, + "data": [ + ["Shellwords!", "Method[escape,shellescape].ReturnValue", "command-injection"] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Shellwords.model.yml b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Shellwords.model.yml deleted file mode 100644 index 283b1daa8fa3..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Shellwords.model.yml +++ /dev/null @@ -1,12 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - - ['Shellwords!', 'Method[escape,shellescape]', 'Argument[0]', 'ReturnValue', 'taint'] - - - addsTo: - pack: codeql/ruby-all - extensible: barrierModel - data: - - ['Shellwords!', 'Method[escape,shellescape].ReturnValue', 'command-injection'] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/terrapin/model.json b/ruby/ql/lib/codeql/ruby/frameworks/terrapin/model.json new file mode 100644 index 000000000000..09c89aad3f43 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/terrapin/model.json @@ -0,0 +1,58 @@ +{ + "extensions": [ + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "sourceModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "sinkModel" + }, + "data": [ + ["Terrapin::CommandLine!", "Method[new].Argument[0]", "command-injection"], + ["Terrapin::CommandLine!", "Method[new].Argument[1]", "command-injection"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "summaryModel" + }, + "data": [ + ["Terrapin::CommandLine::Output!", "Method[new]", "Argument[1]", "ReturnValue", "value"], + ["Terrapin::CommandLine!", "Method[path=]", "Argument[0]", "ReturnValue", "taint"], + ["Terrapin::CommandLine!", "Method[new]", "Argument[2]", "ReturnValue", "taint"] + ] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "neutralModel" + }, + "data": [] + }, + { + "addsTo": { + "pack": "codeql/ruby-all", + "extensible": "typeModel" + }, + "data": [ + ["Terrapin::CommandLine::Output", "Terrapin::CommandLine::MultiPipe", "Method[output].ReturnValue"], + ["Terrapin::CommandLine::Output", "Terrapin::CommandLine::FakeRunner", "Method[call].ReturnValue"], + ["Terrapin::CommandLine::Output", "Terrapin::CommandLine::ProcessRunner", "Method[call].ReturnValue"], + ["Terrapin::CommandLine::Output", "Terrapin::CommandLine!", "Method[runner].ReturnValue.ReturnValue"], + ["Terrapin::CommandLine::FakeRunner", "Terrapin::CommandLine!", "Method[runner].ReturnValue"], + ["Terrapin::CommandLine::Output", "Terrapin::CommandLine!", "Method[fake!].ReturnValue.ReturnValue"], + ["Terrapin::CommandLine::FakeRunner", "Terrapin::CommandLine!", "Method[fake!].ReturnValue"], + ["Terrapin::CommandLine::Output", "Terrapin::CommandLine", "Method[output].ReturnValue"], + ["Terrapin::CommandLineError", "Terrapin::CommandNotFoundError", ""], + ["Terrapin::CommandLineError", "Terrapin::ExitStatusError", ""], + ["Terrapin::CommandLineError", "Terrapin::InterpolationError", ""] + ] + } + ] +} diff --git a/ruby/ql/lib/codeql/ruby/frameworks/terrapin/model.yml b/ruby/ql/lib/codeql/ruby/frameworks/terrapin/model.yml deleted file mode 100644 index c111ca5efbc5..000000000000 --- a/ruby/ql/lib/codeql/ruby/frameworks/terrapin/model.yml +++ /dev/null @@ -1,41 +0,0 @@ -extensions: - - addsTo: - pack: codeql/ruby-all - extensible: sourceModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: sinkModel - data: - - ["Terrapin::CommandLine!","Method[new].Argument[0]","command-injection"] - - ["Terrapin::CommandLine!","Method[new].Argument[1]","command-injection"] - - - addsTo: - pack: codeql/ruby-all - extensible: summaryModel - data: - - ["Terrapin::CommandLine::Output!","Method[new]","Argument[1]","ReturnValue","value"] - - ["Terrapin::CommandLine!","Method[path=]","Argument[0]","ReturnValue","taint"] - - ["Terrapin::CommandLine!","Method[new]","Argument[2]","ReturnValue","taint"] - - - addsTo: - pack: codeql/ruby-all - extensible: neutralModel - data: [] - - - addsTo: - pack: codeql/ruby-all - extensible: typeModel - data: - - ["Terrapin::CommandLine::Output","Terrapin::CommandLine::MultiPipe","Method[output].ReturnValue"] - - ["Terrapin::CommandLine::Output","Terrapin::CommandLine::FakeRunner","Method[call].ReturnValue"] - - ["Terrapin::CommandLine::Output","Terrapin::CommandLine::ProcessRunner","Method[call].ReturnValue"] - - ["Terrapin::CommandLine::Output","Terrapin::CommandLine!","Method[runner].ReturnValue.ReturnValue"] - - ["Terrapin::CommandLine::FakeRunner","Terrapin::CommandLine!","Method[runner].ReturnValue"] - - ["Terrapin::CommandLine::Output","Terrapin::CommandLine!","Method[fake!].ReturnValue.ReturnValue"] - - ["Terrapin::CommandLine::FakeRunner","Terrapin::CommandLine!","Method[fake!].ReturnValue"] - - ["Terrapin::CommandLine::Output","Terrapin::CommandLine","Method[output].ReturnValue"] - - ["Terrapin::CommandLineError","Terrapin::CommandNotFoundError",""] - - ["Terrapin::CommandLineError","Terrapin::ExitStatusError",""] - - ["Terrapin::CommandLineError","Terrapin::InterpolationError",""] diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index fe92d1089f2d..a4a73dc8a4d1 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -18,5 +18,7 @@ dependencies: dataExtensions: - codeql/ruby/frameworks/**/model.yml - codeql/ruby/frameworks/**/*.model.yml + - codeql/ruby/frameworks/**/model.json + - codeql/ruby/frameworks/**/*.model.json warnOnImplicitThis: true compileForOverlayEval: true diff --git a/ruby/ql/test/modelconversion/Empty.rb b/ruby/ql/test/modelconversion/Empty.rb new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ruby/ql/test/modelconversion/EnumerateModels.expected b/ruby/ql/test/modelconversion/EnumerateModels.expected new file mode 100644 index 000000000000..8909189de37e --- /dev/null +++ b/ruby/ql/test/modelconversion/EnumerateModels.expected @@ -0,0 +1,77 @@ +typeModels +| ActiveStorage::Blob | ActiveStorage::Blob! | Method[compose].ReturnValue | +| ActiveStorage::Blob | ActiveStorage::Blob! | Method[create_and_upload!].ReturnValue | +| ActiveStorage::Blob | ActiveStorage::Blob! | Method[create_before_direct_upload!].ReturnValue | +| ActiveStorage::Blob | ActiveStorage::Blob! | Method[find_signed,find_signed!].ReturnValue | +| Mime::Type | Mime! | Method[fetch].ReturnValue | +| Mime::Type | Mime::Type! | Method[lookup].ReturnValue | +| Mime::Type | Mime::Type! | Method[lookup_by_extension].ReturnValue | +| Mime::Type | Mime::Type! | Method[register].ReturnValue | +| Mime::Type | Mime::Type! | Method[register_alias].ReturnValue | +| Pathname | Pathname | Method[+].ReturnValue | +| Pathname | Pathname | Method[/].ReturnValue | +| Pathname | Pathname | Method[basename].ReturnValue | +| Pathname | Pathname | Method[cleanpath].ReturnValue | +| Pathname | Pathname | Method[existence].ReturnValue | +| Pathname | Pathname | Method[expand_path].ReturnValue | +| Pathname | Pathname | Method[join].ReturnValue | +| Pathname | Pathname | Method[realpath].ReturnValue | +| Pathname | Pathname | Method[relative_path_from].ReturnValue | +| Pathname | Pathname | Method[sub].ReturnValue | +| Pathname | Pathname | Method[sub_ext].ReturnValue | +| Pathname | Pathname | Method[to_path].ReturnValue | +| Terrapin::CommandLine::FakeRunner | Terrapin::CommandLine! | Method[fake!].ReturnValue | +| Terrapin::CommandLine::FakeRunner | Terrapin::CommandLine! | Method[runner].ReturnValue | +| Terrapin::CommandLine::Output | Terrapin::CommandLine | Method[output].ReturnValue | +| Terrapin::CommandLine::Output | Terrapin::CommandLine! | Method[fake!].ReturnValue.ReturnValue | +| Terrapin::CommandLine::Output | Terrapin::CommandLine! | Method[runner].ReturnValue.ReturnValue | +| Terrapin::CommandLine::Output | Terrapin::CommandLine::FakeRunner | Method[call].ReturnValue | +| Terrapin::CommandLine::Output | Terrapin::CommandLine::MultiPipe | Method[output].ReturnValue | +| Terrapin::CommandLine::Output | Terrapin::CommandLine::ProcessRunner | Method[call].ReturnValue | +| Terrapin::CommandLineError | Terrapin::CommandNotFoundError | | +| Terrapin::CommandLineError | Terrapin::ExitStatusError | | +| Terrapin::CommandLineError | Terrapin::InterpolationError | | +typeVariableModels +barrierGuardModels +barrierModels +| Mysql2::Client! | Method[escape].ReturnValue | sql-injection | +| Regexp! | Method[escape,quote].ReturnValue | regexp-injection | +| SQLite3::Database! | Method[quote].ReturnValue | sql-injection | +| Shellwords! | Method[escape,shellescape].ReturnValue | command-injection | +neutralModels +sinkModels +| Terrapin::CommandLine! | Method[new].Argument[0] | command-injection | +| Terrapin::CommandLine! | Method[new].Argument[1] | command-injection | +sourceModels +summaryModels +| ActionView::SafeBuffer | Method[concat,insert,prepend,to_s,to_param] | Argument[self] | ReturnValue | taint | +| ActionView::SafeBuffer | Method[safe_concat] | Argument[0] | Argument[self] | taint | +| ActionView::SafeBuffer | Method[safe_concat] | Argument[0] | ReturnValue | taint | +| ActionView::SafeBuffer! | Method[new] | Argument[0] | ReturnValue | taint | +| ActiveStorage::Filename | Method[sanitized] | Argument[self] | ReturnValue | taint | +| ActiveStorage::Filename! | Method[new] | Argument[0] | ReturnValue | taint | +| ActiveSupport::JSON! | Method[decode,load] | Argument[0] | ReturnValue | taint | +| ActiveSupport::JSON! | Method[encode,dump] | Argument[0] | ReturnValue | taint | +| JSON! | Method[generate,fast_generate,pretty_generate,dump,unparse,fast_unparse] | Argument[0] | ReturnValue | taint | +| JSON! | Method[parse,parse!,load,restore] | Argument[0] | ReturnValue | taint | +| Mysql2::Client! | Method[escape] | Argument[0] | ReturnValue | taint | +| Pathname | Method[basename] | Argument[self] | ReturnValue | taint | +| Pathname | Method[cleanpath] | Argument[self] | ReturnValue | taint | +| Pathname | Method[dirname] | Argument[self] | ReturnValue | taint | +| Pathname | Method[each_filename] | Argument[self] | Argument[block].Parameter[0] | taint | +| Pathname | Method[existence] | Argument[self] | ReturnValue | taint | +| Pathname | Method[expand_path] | Argument[self] | ReturnValue | taint | +| Pathname | Method[join] | Argument[self,any] | ReturnValue | taint | +| Pathname | Method[parent] | Argument[self] | ReturnValue | taint | +| Pathname | Method[realpath] | Argument[self] | ReturnValue | taint | +| Pathname | Method[relative_path_from] | Argument[self] | ReturnValue | taint | +| Pathname | Method[sub] | Argument[self] | ReturnValue | taint | +| Pathname | Method[sub_ext] | Argument[self] | ReturnValue | taint | +| Pathname | Method[to_path] | Argument[self] | ReturnValue | taint | +| Pathname! | Method[new] | Argument[0] | ReturnValue | taint | +| Regexp! | Method[escape,quote] | Argument[0] | ReturnValue | taint | +| SQLite3::Database! | Method[quote] | Argument[0] | ReturnValue | taint | +| Shellwords! | Method[escape,shellescape] | Argument[0] | ReturnValue | taint | +| Terrapin::CommandLine! | Method[new] | Argument[2] | ReturnValue | taint | +| Terrapin::CommandLine! | Method[path=] | Argument[0] | ReturnValue | taint | +| Terrapin::CommandLine::Output! | Method[new] | Argument[1] | ReturnValue | value | diff --git a/ruby/ql/test/modelconversion/EnumerateModels.ql b/ruby/ql/test/modelconversion/EnumerateModels.ql new file mode 100644 index 000000000000..4fe47473eabf --- /dev/null +++ b/ruby/ql/test/modelconversion/EnumerateModels.ql @@ -0,0 +1,34 @@ +import codeql.ruby.frameworks.data.internal.ApiGraphModelsExtensions + +/* + * Note: madId columns are ignored, since renaming extension files causes them to be loaded in a + * different order, and the generated values in that column do not match as a result. + */ + +query predicate typeModels(string type1, string type2, string path) { + typeModel(type1, type2, path) +} + +query predicate typeVariableModels(string name, string path) { typeVariableModel(name, path) } + +query predicate barrierGuardModels(string type, string path, string acceptingValue, string kind) { + barrierGuardModel(type, path, acceptingValue, kind, _) +} + +query predicate barrierModels(string type, string path, string kind) { + barrierModel(type, path, kind, _) +} + +query predicate neutralModels(string type, string path, string kind) { + neutralModel(type, path, kind) +} + +query predicate sinkModels(string type, string path, string kind) { sinkModel(type, path, kind, _) } + +query predicate sourceModels(string type, string path, string kind) { + sourceModel(type, path, kind, _) +} + +query predicate summaryModels(string type, string path, string input, string output, string kind) { + summaryModel(type, path, input, output, kind, _) +}