Skip to content

Commit 364bc88

Browse files
committed
Ruby: add YAML.load_file as an unsafe deserialization sink
1 parent 140458b commit 364bc88

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added `YAML.load_file` as a potential sink for unsafe deserialization.

ruby/ql/lib/codeql/ruby/security/UnsafeDeserializationCustomizations.qll

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,15 @@ module UnsafeDeserialization {
4848
}
4949

5050
/**
51-
* An argument in a call to `YAML.load`, considered a sink for unsafe
52-
* deserialization.
51+
* An argument in a call to `YAML.load` or `YAML.load_file`, considered a sink
52+
* for unsafe deserialization. As the `YAML` module is an alias of `Psych` in
5353
*/
5454
class YamlLoadArgument extends Sink {
5555
YamlLoadArgument() {
56-
this = API::getTopLevelMember("YAML").getAMethodCall("load").getArgument(0)
56+
this =
57+
API::getTopLevelMember(["YAML", "Psych"])
58+
.getAMethodCall(["load", "load_file"])
59+
.getArgument(0)
5760
}
5861
}
5962

ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ edges
1616
| UnsafeDeserialization.rb:58:17:58:28 | ...[...] : | UnsafeDeserialization.rb:68:23:68:31 | json_data |
1717
| UnsafeDeserialization.rb:80:11:80:16 | call to params : | UnsafeDeserialization.rb:80:11:80:22 | ...[...] : |
1818
| UnsafeDeserialization.rb:80:11:80:22 | ...[...] : | UnsafeDeserialization.rb:81:34:81:36 | xml |
19+
| UnsafeDeserialization.rb:86:17:86:22 | call to params : | UnsafeDeserialization.rb:86:17:86:28 | ...[...] : |
20+
| UnsafeDeserialization.rb:86:17:86:28 | ...[...] : | UnsafeDeserialization.rb:87:29:87:37 | yaml_path |
21+
| UnsafeDeserialization.rb:92:17:92:22 | call to params : | UnsafeDeserialization.rb:92:17:92:28 | ...[...] : |
22+
| UnsafeDeserialization.rb:92:17:92:28 | ...[...] : | UnsafeDeserialization.rb:93:25:93:33 | yaml_data |
23+
| UnsafeDeserialization.rb:98:17:98:22 | call to params : | UnsafeDeserialization.rb:98:17:98:28 | ...[...] : |
24+
| UnsafeDeserialization.rb:98:17:98:28 | ...[...] : | UnsafeDeserialization.rb:99:30:99:38 | yaml_path |
1925
nodes
2026
| UnsafeDeserialization.rb:9:39:9:44 | call to params : | semmle.label | call to params : |
2127
| UnsafeDeserialization.rb:9:39:9:50 | ...[...] : | semmle.label | ...[...] : |
@@ -42,6 +48,15 @@ nodes
4248
| UnsafeDeserialization.rb:80:11:80:16 | call to params : | semmle.label | call to params : |
4349
| UnsafeDeserialization.rb:80:11:80:22 | ...[...] : | semmle.label | ...[...] : |
4450
| UnsafeDeserialization.rb:81:34:81:36 | xml | semmle.label | xml |
51+
| UnsafeDeserialization.rb:86:17:86:22 | call to params : | semmle.label | call to params : |
52+
| UnsafeDeserialization.rb:86:17:86:28 | ...[...] : | semmle.label | ...[...] : |
53+
| UnsafeDeserialization.rb:87:29:87:37 | yaml_path | semmle.label | yaml_path |
54+
| UnsafeDeserialization.rb:92:17:92:22 | call to params : | semmle.label | call to params : |
55+
| UnsafeDeserialization.rb:92:17:92:28 | ...[...] : | semmle.label | ...[...] : |
56+
| UnsafeDeserialization.rb:93:25:93:33 | yaml_data | semmle.label | yaml_data |
57+
| UnsafeDeserialization.rb:98:17:98:22 | call to params : | semmle.label | call to params : |
58+
| UnsafeDeserialization.rb:98:17:98:28 | ...[...] : | semmle.label | ...[...] : |
59+
| UnsafeDeserialization.rb:99:30:99:38 | yaml_path | semmle.label | yaml_path |
4560
subpaths
4661
#select
4762
| UnsafeDeserialization.rb:10:27:10:41 | serialized_data | UnsafeDeserialization.rb:9:39:9:44 | call to params : | UnsafeDeserialization.rb:10:27:10:41 | serialized_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:9:39:9:44 | call to params | user-provided value |
@@ -53,3 +68,6 @@ subpaths
5368
| UnsafeDeserialization.rb:53:22:53:30 | json_data | UnsafeDeserialization.rb:51:17:51:22 | call to params : | UnsafeDeserialization.rb:53:22:53:30 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:51:17:51:22 | call to params | user-provided value |
5469
| UnsafeDeserialization.rb:68:23:68:31 | json_data | UnsafeDeserialization.rb:58:17:58:22 | call to params : | UnsafeDeserialization.rb:68:23:68:31 | json_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:58:17:58:22 | call to params | user-provided value |
5570
| UnsafeDeserialization.rb:81:34:81:36 | xml | UnsafeDeserialization.rb:80:11:80:16 | call to params : | UnsafeDeserialization.rb:81:34:81:36 | xml | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:80:11:80:16 | call to params | user-provided value |
71+
| UnsafeDeserialization.rb:87:29:87:37 | yaml_path | UnsafeDeserialization.rb:86:17:86:22 | call to params : | UnsafeDeserialization.rb:87:29:87:37 | yaml_path | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:86:17:86:22 | call to params | user-provided value |
72+
| UnsafeDeserialization.rb:93:25:93:33 | yaml_data | UnsafeDeserialization.rb:92:17:92:22 | call to params : | UnsafeDeserialization.rb:93:25:93:33 | yaml_data | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:92:17:92:22 | call to params | user-provided value |
73+
| UnsafeDeserialization.rb:99:30:99:38 | yaml_path | UnsafeDeserialization.rb:98:17:98:22 | call to params : | UnsafeDeserialization.rb:99:30:99:38 | yaml_path | Unsafe deserialization depends on a $@. | UnsafeDeserialization.rb:98:17:98:22 | call to params | user-provided value |

ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,22 @@ def route10
8080
xml = params[:key]
8181
hash = Hash.from_trusted_xml(xml)
8282
end
83+
84+
# BAD
85+
def route11
86+
yaml_path = params[:key]
87+
object = YAML.load_file yaml_path
88+
end
89+
90+
# BAD
91+
def route12
92+
yaml_data = params[:key]
93+
object = Psych.load yaml_data
94+
end
95+
96+
# BAD
97+
def route13
98+
yaml_path = params[:key]
99+
object = Psych.load_file yaml_path
100+
end
83101
end

0 commit comments

Comments
 (0)