Merge branch 'main' into nickrolfe/ruby-overlay-extraction

This commit is contained in:
Nick Rolfe
2025-06-25 05:46:26 -04:00
committed by GitHub
1014 changed files with 71445 additions and 22605 deletions

View File

@@ -1,3 +1,7 @@
## 4.1.9
No user-facing changes.
## 4.1.8
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 4.1.9
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 4.1.8
lastReleaseVersion: 4.1.9

View File

@@ -1,5 +1,5 @@
name: codeql/ruby-all
version: 4.1.9-dev
version: 4.1.10-dev
groups: ruby
extractor: ruby
dbscheme: ruby.dbscheme

View File

@@ -0,0 +1,6 @@
/**
* @kind test-postprocess
*/
import codeql.ruby.frameworks.data.internal.ApiGraphModels
import codeql.dataflow.test.ProvenancePathGraph::TestPostProcessing::TranslateProvenanceResults<interpretModelForTest/2>

View File

@@ -1,3 +1,10 @@
## 1.4.0
### Query Metadata Changes
* Update query metadata tags for `rb/database-query-in-loop` and `rb/useless-assignment-to-local` to align with the established
[Query file metadata and alert message style guide](https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md#quality-query-sub-category-tags).
## 1.3.2
No user-facing changes.

View File

@@ -1,5 +1,6 @@
---
category: queryMetadata
---
## 1.4.0
### Query Metadata Changes
* Update query metadata tags for `rb/database-query-in-loop` and `rb/useless-assignment-to-local` to align with the established
[Query file metadata and alert message style guide](https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md#quality-query-sub-category-tags).

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.3.2
lastReleaseVersion: 1.4.0

View File

@@ -1,5 +1,5 @@
name: codeql/ruby-queries
version: 1.3.3-dev
version: 1.4.1-dev
groups:
- ruby
- queries

View File

@@ -1,32 +1,49 @@
models
| 1 | Sink: Terrapin::CommandLine!; Method[new].Argument[0]; command-injection |
| 2 | Sink: Terrapin::CommandLine!; Method[new].Argument[1]; command-injection |
#select
| CommandInjection.rb:7:10:7:15 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:7:10:7:15 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:8:16:8:18 | cmd | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:8:16:8:18 | cmd | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:10:14:10:16 | cmd | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:10:14:10:16 | cmd | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:11:17:11:22 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:11:17:11:22 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:13:9:13:14 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:13:9:13:14 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:30:19:30:24 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:30:19:30:24 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:34:24:34:36 | "echo #{...}" | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:34:24:34:36 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:35:39:35:51 | "grep #{...}" | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:35:39:35:51 | "grep #{...}" | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:51:24:51:36 | "echo #{...}" | CommandInjection.rb:47:15:47:20 | call to params | CommandInjection.rb:51:24:51:36 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:47:15:47:20 | call to params | user-provided value |
| CommandInjection.rb:60:14:60:16 | cmd | CommandInjection.rb:55:13:55:18 | call to params | CommandInjection.rb:60:14:60:16 | cmd | This command depends on a $@. | CommandInjection.rb:55:13:55:18 | call to params | user-provided value |
| CommandInjection.rb:75:14:75:29 | "echo #{...}" | CommandInjection.rb:74:18:74:23 | number | CommandInjection.rb:75:14:75:29 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:74:18:74:23 | number | user-provided value |
| CommandInjection.rb:83:14:83:34 | "echo #{...}" | CommandInjection.rb:82:23:82:33 | blah_number | CommandInjection.rb:83:14:83:34 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:82:23:82:33 | blah_number | user-provided value |
| CommandInjection.rb:92:14:92:39 | "echo #{...}" | CommandInjection.rb:92:22:92:37 | ...[...] | CommandInjection.rb:92:14:92:39 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:92:22:92:37 | ...[...] | user-provided value |
| CommandInjection.rb:105:16:105:28 | "cat #{...}" | CommandInjection.rb:104:16:104:21 | call to params | CommandInjection.rb:105:16:105:28 | "cat #{...}" | This command depends on a $@. | CommandInjection.rb:104:16:104:21 | call to params | user-provided value |
| CommandInjection.rb:112:33:112:44 | ...[...] | CommandInjection.rb:112:33:112:38 | call to params | CommandInjection.rb:112:33:112:44 | ...[...] | This command depends on a $@. | CommandInjection.rb:112:33:112:38 | call to params | user-provided value |
| CommandInjection.rb:114:41:114:56 | "#{...}" | CommandInjection.rb:114:44:114:49 | call to params | CommandInjection.rb:114:41:114:56 | "#{...}" | This command depends on a $@. | CommandInjection.rb:114:44:114:49 | call to params | user-provided value |
edges
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:7:10:7:15 | #{...} | provenance | |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:8:16:8:18 | cmd | provenance | |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:10:14:10:16 | cmd | provenance | |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:11:17:11:22 | #{...} | provenance | |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:13:9:13:14 | #{...} | provenance | |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:29:19:29:24 | #{...} | provenance | |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:33:24:33:36 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:34:39:34:51 | "grep #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:30:19:30:24 | #{...} | provenance | |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:34:24:34:36 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:6:9:6:11 | cmd | CommandInjection.rb:35:39:35:51 | "grep #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:6:15:6:26 | ...[...] | provenance | |
| CommandInjection.rb:6:15:6:26 | ...[...] | CommandInjection.rb:6:9:6:11 | cmd | provenance | |
| CommandInjection.rb:46:9:46:11 | cmd | CommandInjection.rb:50:24:50:36 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:46:15:46:20 | call to params | CommandInjection.rb:46:15:46:26 | ...[...] | provenance | |
| CommandInjection.rb:46:15:46:26 | ...[...] | CommandInjection.rb:46:9:46:11 | cmd | provenance | |
| CommandInjection.rb:54:7:54:9 | cmd | CommandInjection.rb:59:14:59:16 | cmd | provenance | |
| CommandInjection.rb:54:13:54:18 | call to params | CommandInjection.rb:54:13:54:24 | ...[...] | provenance | |
| CommandInjection.rb:54:13:54:24 | ...[...] | CommandInjection.rb:54:7:54:9 | cmd | provenance | |
| CommandInjection.rb:73:18:73:23 | number | CommandInjection.rb:74:14:74:29 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:81:23:81:33 | blah_number | CommandInjection.rb:82:14:82:34 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:91:22:91:37 | ...[...] | CommandInjection.rb:91:14:91:39 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:103:9:103:12 | file | CommandInjection.rb:104:16:104:28 | "cat #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:103:16:103:21 | call to params | CommandInjection.rb:103:16:103:28 | ...[...] | provenance | |
| CommandInjection.rb:103:16:103:28 | ...[...] | CommandInjection.rb:103:9:103:12 | file | provenance | |
| CommandInjection.rb:111:33:111:38 | call to params | CommandInjection.rb:111:33:111:44 | ...[...] | provenance | Sink:MaD:1 |
| CommandInjection.rb:113:44:113:49 | call to params | CommandInjection.rb:113:44:113:54 | ...[...] | provenance | |
| CommandInjection.rb:113:44:113:54 | ...[...] | CommandInjection.rb:113:41:113:56 | "#{...}" | provenance | AdditionalTaintStep Sink:MaD:2 |
| CommandInjection.rb:47:9:47:11 | cmd | CommandInjection.rb:51:24:51:36 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:47:15:47:20 | call to params | CommandInjection.rb:47:15:47:26 | ...[...] | provenance | |
| CommandInjection.rb:47:15:47:26 | ...[...] | CommandInjection.rb:47:9:47:11 | cmd | provenance | |
| CommandInjection.rb:55:7:55:9 | cmd | CommandInjection.rb:60:14:60:16 | cmd | provenance | |
| CommandInjection.rb:55:13:55:18 | call to params | CommandInjection.rb:55:13:55:24 | ...[...] | provenance | |
| CommandInjection.rb:55:13:55:24 | ...[...] | CommandInjection.rb:55:7:55:9 | cmd | provenance | |
| CommandInjection.rb:74:18:74:23 | number | CommandInjection.rb:75:14:75:29 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:82:23:82:33 | blah_number | CommandInjection.rb:83:14:83:34 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:92:22:92:37 | ...[...] | CommandInjection.rb:92:14:92:39 | "echo #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:104:9:104:12 | file | CommandInjection.rb:105:16:105:28 | "cat #{...}" | provenance | AdditionalTaintStep |
| CommandInjection.rb:104:16:104:21 | call to params | CommandInjection.rb:104:16:104:28 | ...[...] | provenance | |
| CommandInjection.rb:104:16:104:28 | ...[...] | CommandInjection.rb:104:9:104:12 | file | provenance | |
| CommandInjection.rb:112:33:112:38 | call to params | CommandInjection.rb:112:33:112:44 | ...[...] | provenance | Sink:MaD:1 |
| CommandInjection.rb:114:44:114:49 | call to params | CommandInjection.rb:114:44:114:54 | ...[...] | provenance | |
| CommandInjection.rb:114:44:114:54 | ...[...] | CommandInjection.rb:114:41:114:56 | "#{...}" | provenance | AdditionalTaintStep Sink:MaD:2 |
models
| 1 | Sink: Terrapin::CommandLine!; Method[new].Argument[0]; command-injection |
| 2 | Sink: Terrapin::CommandLine!; Method[new].Argument[1]; command-injection |
nodes
| CommandInjection.rb:6:9:6:11 | cmd | semmle.label | cmd |
| CommandInjection.rb:6:15:6:20 | call to params | semmle.label | call to params |
@@ -36,47 +53,30 @@ nodes
| CommandInjection.rb:10:14:10:16 | cmd | semmle.label | cmd |
| CommandInjection.rb:11:17:11:22 | #{...} | semmle.label | #{...} |
| CommandInjection.rb:13:9:13:14 | #{...} | semmle.label | #{...} |
| CommandInjection.rb:29:19:29:24 | #{...} | semmle.label | #{...} |
| CommandInjection.rb:33:24:33:36 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:34:39:34:51 | "grep #{...}" | semmle.label | "grep #{...}" |
| CommandInjection.rb:46:9:46:11 | cmd | semmle.label | cmd |
| CommandInjection.rb:46:15:46:20 | call to params | semmle.label | call to params |
| CommandInjection.rb:46:15:46:26 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:50:24:50:36 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:54:7:54:9 | cmd | semmle.label | cmd |
| CommandInjection.rb:54:13:54:18 | call to params | semmle.label | call to params |
| CommandInjection.rb:54:13:54:24 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:59:14:59:16 | cmd | semmle.label | cmd |
| CommandInjection.rb:73:18:73:23 | number | semmle.label | number |
| CommandInjection.rb:74:14:74:29 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:81:23:81:33 | blah_number | semmle.label | blah_number |
| CommandInjection.rb:82:14:82:34 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:91:14:91:39 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:91:22:91:37 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:103:9:103:12 | file | semmle.label | file |
| CommandInjection.rb:103:16:103:21 | call to params | semmle.label | call to params |
| CommandInjection.rb:103:16:103:28 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:104:16:104:28 | "cat #{...}" | semmle.label | "cat #{...}" |
| CommandInjection.rb:111:33:111:38 | call to params | semmle.label | call to params |
| CommandInjection.rb:111:33:111:44 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:113:41:113:56 | "#{...}" | semmle.label | "#{...}" |
| CommandInjection.rb:113:44:113:49 | call to params | semmle.label | call to params |
| CommandInjection.rb:113:44:113:54 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:30:19:30:24 | #{...} | semmle.label | #{...} |
| CommandInjection.rb:34:24:34:36 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:35:39:35:51 | "grep #{...}" | semmle.label | "grep #{...}" |
| CommandInjection.rb:47:9:47:11 | cmd | semmle.label | cmd |
| CommandInjection.rb:47:15:47:20 | call to params | semmle.label | call to params |
| CommandInjection.rb:47:15:47:26 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:51:24:51:36 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:55:7:55:9 | cmd | semmle.label | cmd |
| CommandInjection.rb:55:13:55:18 | call to params | semmle.label | call to params |
| CommandInjection.rb:55:13:55:24 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:60:14:60:16 | cmd | semmle.label | cmd |
| CommandInjection.rb:74:18:74:23 | number | semmle.label | number |
| CommandInjection.rb:75:14:75:29 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:82:23:82:33 | blah_number | semmle.label | blah_number |
| CommandInjection.rb:83:14:83:34 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:92:14:92:39 | "echo #{...}" | semmle.label | "echo #{...}" |
| CommandInjection.rb:92:22:92:37 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:104:9:104:12 | file | semmle.label | file |
| CommandInjection.rb:104:16:104:21 | call to params | semmle.label | call to params |
| CommandInjection.rb:104:16:104:28 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:105:16:105:28 | "cat #{...}" | semmle.label | "cat #{...}" |
| CommandInjection.rb:112:33:112:38 | call to params | semmle.label | call to params |
| CommandInjection.rb:112:33:112:44 | ...[...] | semmle.label | ...[...] |
| CommandInjection.rb:114:41:114:56 | "#{...}" | semmle.label | "#{...}" |
| CommandInjection.rb:114:44:114:49 | call to params | semmle.label | call to params |
| CommandInjection.rb:114:44:114:54 | ...[...] | semmle.label | ...[...] |
subpaths
#select
| CommandInjection.rb:7:10:7:15 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:7:10:7:15 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:8:16:8:18 | cmd | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:8:16:8:18 | cmd | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:10:14:10:16 | cmd | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:10:14:10:16 | cmd | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:11:17:11:22 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:11:17:11:22 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:13:9:13:14 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:13:9:13:14 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:29:19:29:24 | #{...} | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:29:19:29:24 | #{...} | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:33:24:33:36 | "echo #{...}" | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:33:24:33:36 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:34:39:34:51 | "grep #{...}" | CommandInjection.rb:6:15:6:20 | call to params | CommandInjection.rb:34:39:34:51 | "grep #{...}" | This command depends on a $@. | CommandInjection.rb:6:15:6:20 | call to params | user-provided value |
| CommandInjection.rb:50:24:50:36 | "echo #{...}" | CommandInjection.rb:46:15:46:20 | call to params | CommandInjection.rb:50:24:50:36 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:46:15:46:20 | call to params | user-provided value |
| CommandInjection.rb:59:14:59:16 | cmd | CommandInjection.rb:54:13:54:18 | call to params | CommandInjection.rb:59:14:59:16 | cmd | This command depends on a $@. | CommandInjection.rb:54:13:54:18 | call to params | user-provided value |
| CommandInjection.rb:74:14:74:29 | "echo #{...}" | CommandInjection.rb:73:18:73:23 | number | CommandInjection.rb:74:14:74:29 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:73:18:73:23 | number | user-provided value |
| CommandInjection.rb:82:14:82:34 | "echo #{...}" | CommandInjection.rb:81:23:81:33 | blah_number | CommandInjection.rb:82:14:82:34 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:81:23:81:33 | blah_number | user-provided value |
| CommandInjection.rb:91:14:91:39 | "echo #{...}" | CommandInjection.rb:91:22:91:37 | ...[...] | CommandInjection.rb:91:14:91:39 | "echo #{...}" | This command depends on a $@. | CommandInjection.rb:91:22:91:37 | ...[...] | user-provided value |
| CommandInjection.rb:104:16:104:28 | "cat #{...}" | CommandInjection.rb:103:16:103:21 | call to params | CommandInjection.rb:104:16:104:28 | "cat #{...}" | This command depends on a $@. | CommandInjection.rb:103:16:103:21 | call to params | user-provided value |
| CommandInjection.rb:111:33:111:44 | ...[...] | CommandInjection.rb:111:33:111:38 | call to params | CommandInjection.rb:111:33:111:44 | ...[...] | This command depends on a $@. | CommandInjection.rb:111:33:111:38 | call to params | user-provided value |
| CommandInjection.rb:113:41:113:56 | "#{...}" | CommandInjection.rb:113:44:113:49 | call to params | CommandInjection.rb:113:41:113:56 | "#{...}" | This command depends on a $@. | CommandInjection.rb:113:44:113:49 | call to params | user-provided value |

View File

@@ -1,16 +0,0 @@
/**
* @kind path-problem
*/
import codeql.ruby.AST
import codeql.ruby.security.CommandInjectionQuery
import codeql.dataflow.test.ProvenancePathGraph
import codeql.ruby.frameworks.data.internal.ApiGraphModels
import ShowProvenance<interpretModelForTest/2, CommandInjectionFlow::PathNode, CommandInjectionFlow::PathGraph>
from CommandInjectionFlow::PathNode source, CommandInjectionFlow::PathNode sink, Source sourceNode
where
CommandInjectionFlow::flowPath(source, sink) and
sourceNode = source.getNode()
select sink.getNode(), source, sink, "This command depends on a $@.", sourceNode,
sourceNode.getSourceType()

View File

@@ -0,0 +1,4 @@
query: queries/security/cwe-078/CommandInjection.ql
postprocess:
- utils/test/PrettyPrintModels.ql
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -3,14 +3,15 @@ require "open3"
class UsersController < ActionController::Base
def create
cmd = params[:cmd]
`#{cmd}`
system(cmd)
cmd = params[:cmd] # $ Source
`#{cmd}` # $ Alert
system(cmd) # $ Alert
system("echo", cmd) # OK, because cmd is not shell interpreted
exec(cmd)
%x(echo #{cmd})
exec(cmd) # $ Alert
%x(echo #{cmd}) # $ Alert
result = <<`EOF`
#{cmd}
#{cmd} #{# $ Alert
}
EOF
safe_cmd_1 = Shellwords.escape(cmd)
@@ -26,12 +27,12 @@ EOF
if %w(foo bar).include? cmd
`echo #{cmd}`
else
`echo #{cmd}`
`echo #{cmd}` # $ Alert
end
# Open3 methods
Open3.capture2("echo #{cmd}")
Open3.pipeline("cat foo.txt", "grep #{cmd}")
Open3.capture2("echo #{cmd}") # $ Alert
Open3.pipeline("cat foo.txt", "grep #{cmd}") # $ Alert
Open3.pipeline(["echo", cmd], "tail") # OK, because cmd is not shell interpreted
end
@@ -43,20 +44,20 @@ EOF
end
def index
cmd = params[:key]
cmd = params[:key] # $ Source
if %w(foo bar).include? cmd
`echo #{cmd}`
end
Open3.capture2("echo #{cmd}")
Open3.capture2("echo #{cmd}") # $ Alert
end
def update
cmd = params[:key]
cmd = params[:key] # $ Source
case cmd
when "foo"
system(cmd)
end
system(cmd)
system(cmd) # $ Alert
end
end
@@ -70,16 +71,16 @@ module Types
field :with_arg, String, null: false, description: "A field with an argument" do
argument :number, Int, "A number", required: true
end
def with_arg(number:)
system("echo #{number}")
def with_arg(number:) # $ Source
system("echo #{number}") # $ Alert
number.to_s
end
field :with_method, String, null: false, description: "A field with a custom resolver method", resolver_method: :custom_method do
argument :blah_number, Int, "A number", required: true
end
def custom_method(blah_number:, number: nil)
system("echo #{blah_number}")
def custom_method(blah_number:, number: nil) # $ Source
system("echo #{blah_number}") # $ Alert
system("echo #{number}") # OK, number: is not an `argument` for this field
blah_number.to_s
end
@@ -88,7 +89,7 @@ module Types
argument :something, Int, "A number", required: true
end
def with_splat(**args)
system("echo #{args[:something]}")
system("echo #{args[:something]}") # $ Alert
args[:something].to_s
end
@@ -100,17 +101,17 @@ end
class Foo < ActionController::Base
def create
file = params[:file]
system("cat #{file}")
file = params[:file] # $ Source
system("cat #{file}") # $ Alert
# .shellescape
system("cat #{file.shellescape}") # OK, because file is shell escaped
end
def index
Terrapin::CommandLine.new(params[:foo], "bar") # BAD
Terrapin::CommandLine.new(params[:foo], "bar") # $ Alert
Terrapin::CommandLine.new("echo", "#{params[foo]}") # BAD
Terrapin::CommandLine.new("echo", "#{params[foo]}") # $ Alert
cmd = Terrapin::CommandLine.new("echo", ":msg")
cmd.run(msg: params[:foo]) # GOOD

View File

@@ -1,4 +1,14 @@
testFailures
#select
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ of sensitive file from $@. | insecure_download.rb:27:5:27:46 | call to get | Download | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | HTTP source |
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ of sensitive file from $@. | insecure_download.rb:27:5:27:46 | call to get | Download | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | HTTP source |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : String | insecure_download.rb:33:15:33:17 | url | $@ of sensitive file from $@. | insecure_download.rb:33:5:33:18 | call to get | Download | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" | HTTP source |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : String | insecure_download.rb:33:15:33:17 | url | $@ of sensitive file from $@. | insecure_download.rb:33:5:33:18 | call to get | Download | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" | HTTP source |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | $@ of sensitive file from $@. | insecure_download.rb:33:5:33:18 | call to get | Download | insecure_download.rb:33:15:33:17 | url | HTTP source |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | $@ of sensitive file from $@. | insecure_download.rb:33:5:33:18 | call to get | Download | insecure_download.rb:33:15:33:17 | url | HTTP source |
| insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | $@ of sensitive file from $@. | insecure_download.rb:37:32:37:69 | call to get | Download | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | HTTP source |
| insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | $@ of sensitive file from $@. | insecure_download.rb:41:27:41:64 | call to get | Download | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | HTTP source |
| insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | $@ of sensitive file from $@. | insecure_download.rb:43:12:43:57 | call to get | Download | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | HTTP source |
| insecure_download.rb:53:65:53:78 | "/myscript.sh" | insecure_download.rb:53:65:53:78 | "/myscript.sh" | insecure_download.rb:53:65:53:78 | "/myscript.sh" | $@ of sensitive file from $@. | insecure_download.rb:53:14:53:79 | call to get | Download | insecure_download.rb:53:65:53:78 | "/myscript.sh" | HTTP source |
edges
| insecure_download.rb:31:5:31:7 | url : String | insecure_download.rb:33:15:33:17 | url | provenance | |
| insecure_download.rb:31:5:31:7 | url : String | insecure_download.rb:33:15:33:17 | url | provenance | |
@@ -18,14 +28,3 @@ nodes
| insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | semmle.label | "http://example.org/unsafe.unk..." |
| insecure_download.rb:53:65:53:78 | "/myscript.sh" | semmle.label | "/myscript.sh" |
subpaths
#select
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" |
| insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | $@ | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | "http://example.org/unsafe.APK" |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : String | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : String | "http://example.org/unsafe.APK" : String |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : String | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : String | "http://example.org/unsafe.APK" : String |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:33:15:33:17 | url | url |
| insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | insecure_download.rb:33:15:33:17 | url | $@ | insecure_download.rb:33:15:33:17 | url | url |
| insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | $@ | insecure_download.rb:37:42:37:68 | "http://example.org/unsafe" | "http://example.org/unsafe" |
| insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | $@ | insecure_download.rb:41:37:41:63 | "http://example.org/unsafe" | "http://example.org/unsafe" |
| insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | $@ | insecure_download.rb:43:22:43:56 | "http://example.org/unsafe.unk..." | "http://example.org/unsafe.unk..." |
| insecure_download.rb:53:65:53:78 | "/myscript.sh" | insecure_download.rb:53:65:53:78 | "/myscript.sh" | insecure_download.rb:53:65:53:78 | "/myscript.sh" | $@ | insecure_download.rb:53:65:53:78 | "/myscript.sh" | "/myscript.sh" |

View File

@@ -1,23 +0,0 @@
import codeql.ruby.security.InsecureDownloadQuery
import InsecureDownloadFlow::PathGraph
import utils.test.InlineExpectationsTest
import utils.test.InlineFlowTestUtil
module FlowTest implements TestSig {
string getARelevantTag() { result = "BAD" }
predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "BAD" and
exists(DataFlow::Node src, DataFlow::Node sink | InsecureDownloadFlow::flow(src, sink) |
sink.getLocation() = location and
element = sink.toString() and
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
)
}
}
import MakeTest<FlowTest>
from InsecureDownloadFlow::PathNode source, InsecureDownloadFlow::PathNode sink
where InsecureDownloadFlow::flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -0,0 +1,4 @@
query: queries/security/cwe-829/InsecureDownload.ql
postprocess:
- utils/test/PrettyPrintModels.ql
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -2,7 +2,7 @@ require "excon"
def foo
def download_tools(installer)
Excon.get(installer[:url]) # $ MISSING: BAD= (requires hash flow)
Excon.get(installer[:url]) # $ MISSING: Alert (requires hash flow)
end
constants = {
@@ -24,23 +24,23 @@ def bar
Excon.get("https://download.microsoft.com/download/5/f/7/5f7acaeb-8363-451f-9425-68a90f98b238/visualcppbuildtools_full.exe") # GOOD
Excon.get("http://example.org/unsafe.APK") # $BAD=
Excon.get("http://example.org/unsafe.APK") # $ Alert
end
def baz
url = "http://example.org/unsafe.APK"
url = "http://example.org/unsafe.APK" # $ Source
Excon.get(url) # $BAD=
Excon.get(url) # $ Alert
end
def test
File.open("foo.exe").write(Excon.get("http://example.org/unsafe").body) # $BAD=
File.open("foo.exe").write(Excon.get("http://example.org/unsafe").body) # $ Alert
File.open("foo.safe").write(Excon.get("http://example.org/unsafe").body) # GOOD
File.write("foo.exe", Excon.get("http://example.org/unsafe").body) # $BAD=
File.write("foo.exe", Excon.get("http://example.org/unsafe").body) # $ Alert
resp = Excon.get("http://example.org/unsafe.unknown") # $BAD=
resp = Excon.get("http://example.org/unsafe.unknown") # $ Alert
file = File.open("unsafe.exe", "w")
file.write(resp.body)
@@ -50,6 +50,6 @@ def test
end
def sh
script = Net::HTTP.new("http://mydownload.example.org").get("/myscript.sh").body # $BAD=
script = Net::HTTP.new("http://mydownload.example.org").get("/myscript.sh").body # $ Alert
system(script)
end
end