Skip to content

Commit 93b66e0

Browse files
authored
Merge pull request #93 from polvalente/pv-feat/cleanup-smartcell-to-source
fix: smart cell to_source should not include string representation of the code
2 parents d851ce7 + 38cf33c commit 93b66e0

File tree

8 files changed

+63
-265
lines changed

8 files changed

+63
-265
lines changed

modules/2-owasp.livemd

+3-41
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Notable CWEs included are CWE-259: Use of Hard-coded Password, CWE-327: Broken o
101101

102102
_Please uncomment the function call that you believe is correct._
103103

104-
<!-- livebook:{"attrs":"eyJtb2R1bGVfaWQiOm51bGwsInF1ZXN0aW9uX2lkIjpudWxsLCJzb3VyY2UiOiIjT1dBU1A6MVxuZGVmbW9kdWxlIFBhc3N3b3JkQ29tcGFyZSBkb1xuICBkZWYgb3B0aW9uX29uZShwYXNzd29yZCwgbWQ1X2hhc2gpIGRvXG4gICAgY2FzZSA6Y3J5cHRvLmhhc2goOm1kNSwgcGFzc3dvcmQpID09IG1kNV9oYXNoIGRvXG4gICAgICB0cnVlIC0+IDplbnRyeV9ncmFudGVkX29wMVxuICAgICAgZmFsc2UgLT4gOmVudHJ5X2RlbmllZF9vcDFcbiAgICBlbmRcbiAgZW5kXG5cbiAgZGVmIG9wdGlvbl90d28ocGFzc3dvcmQsIGJjcnlwdF9zYWx0ZWRfaGFzaCkgZG9cbiAgICBjYXNlIEJjcnlwdC52ZXJpZnlfcGFzcyhwYXNzd29yZCwgYmNyeXB0X3NhbHRlZF9oYXNoKSBkb1xuICAgICAgdHJ1ZSAtPiA6ZW50cnlfZ3JhbnRlZF9vcDJcbiAgICAgIGZhbHNlIC0+IDplbnRyeV9kZW5pZWRfb3AyXG4gICAgZW5kXG4gIGVuZFxuZW5kXG5cbiMgRE8gTk9UIENIQU5HRSBDT0RFIEFCT1ZFIFRISVMgTElORSA9PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiMgUGFzc3dvcmRDb21wYXJlLm9wdGlvbl9vbmUoXCJ1c2Vyc19wYXNzd29yZFwiLCBtZDVfaGFzaClcbiMgUGFzc3dvcmRDb21wYXJlLm9wdGlvbl90d28oXCJ1c2Vyc19wYXNzd29yZFwiLCBiY3J5cHRfc2FsdGVkX2hhc2gpIn0","chunks":null,"kind":"Elixir.GradingClient.GradedCell","livebook_object":"smart_cell"} -->
104+
<!-- livebook:{"attrs":"eyJzb3VyY2UiOiIjT1dBU1A6MVxuZGVmbW9kdWxlIFBhc3N3b3JkQ29tcGFyZSBkb1xuICBkZWYgb3B0aW9uX29uZShwYXNzd29yZCwgbWQ1X2hhc2gpIGRvXG4gICAgY2FzZSA6Y3J5cHRvLmhhc2goOm1kNSwgcGFzc3dvcmQpID09IG1kNV9oYXNoIGRvXG4gICAgICB0cnVlIC0+IDplbnRyeV9ncmFudGVkX29wMVxuICAgICAgZmFsc2UgLT4gOmVudHJ5X2RlbmllZF9vcDFcbiAgICBlbmRcbiAgZW5kXG5cbiAgZGVmIG9wdGlvbl90d28ocGFzc3dvcmQsIGJjcnlwdF9zYWx0ZWRfaGFzaCkgZG9cbiAgICBjYXNlIEJjcnlwdC52ZXJpZnlfcGFzcyhwYXNzd29yZCwgYmNyeXB0X3NhbHRlZF9oYXNoKSBkb1xuICAgICAgdHJ1ZSAtPiA6ZW50cnlfZ3JhbnRlZF9vcDJcbiAgICAgIGZhbHNlIC0+IDplbnRyeV9kZW5pZWRfb3AyXG4gICAgZW5kXG4gIGVuZFxuZW5kXG5cbiMgRE8gTk9UIENIQU5HRSBDT0RFIEFCT1ZFIFRISVMgTElORSA9PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiMgUGFzc3dvcmRDb21wYXJlLm9wdGlvbl9vbmUoXCJ1c2Vyc19wYXNzd29yZFwiLCBtZDVfaGFzaClcbiMgUGFzc3dvcmRDb21wYXJlLm9wdGlvbl90d28oXCJ1c2Vyc19wYXNzd29yZFwiLCBiY3J5cHRfc2FsdGVkX2hhc2gpIn0","chunks":null,"kind":"Elixir.GradingClient.GradedCell","livebook_object":"smart_cell"} -->
105105

106106
```elixir
107107
result =
@@ -121,26 +121,7 @@ result =
121121
end
122122
end
123123

124-
[module_id, question_id] =
125-
"#OWASP:1\ndefmodule PasswordCompare do\n def option_one(password, md5_hash) do\n case :crypto.hash(:md5, password) == md5_hash do\n true -> :entry_granted_op1\n false -> :entry_denied_op1\n end\n end\n\n def option_two(password, bcrypt_salted_hash) do\n case Bcrypt.verify_pass(password, bcrypt_salted_hash) do\n true -> :entry_granted_op2\n false -> :entry_denied_op2\n end\n end\nend\n\n# DO NOT CHANGE CODE ABOVE THIS LINE =========================\n\n# PasswordCompare.option_one(\"users_password\", md5_hash)\n# PasswordCompare.option_two(\"users_password\", bcrypt_salted_hash)"
126-
|> String.split("\n", parts: 2)
127-
|> hd()
128-
|> String.trim_leading("#")
129-
|> String.split(":", parts: 2)
130-
131-
module_id =
132-
case %{"OWASP" => OWASP}[String.trim(module_id)] do
133-
nil -> raise "invalid module id: #{module_id}"
134-
module_id -> module_id
135-
end
136-
137-
question_id =
138-
case Integer.parse(String.trim(question_id)) do
139-
{id, ""} -> id
140-
_ -> raise "invalid question id: #{question_id}"
141-
end
142-
143-
case GradingClient.check_answer(module_id, question_id, result) do
124+
case GradingClient.check_answer(OWASP, 1, result) do
144125
:correct ->
145126
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
146127

@@ -292,26 +273,7 @@ result =
292273
Kino.Input.read(answer)
293274
)
294275

295-
[module_id, question_id] =
296-
"#OWASP:2\nanswer = \n Kino.Input.select(\"Answer\", [\n {:ecto, \"Ecto v2.2.2\"},\n {:nx, \"Nx v0.5.0\"},\n {:plug, \"Plug v1.3.2\"}\n ])\n\nKino.render(answer)\n\nKino.Input.read(answer)"
297-
|> String.split("\n", parts: 2)
298-
|> hd()
299-
|> String.trim_leading("#")
300-
|> String.split(":", parts: 2)
301-
302-
module_id =
303-
case %{"OWASP" => OWASP}[String.trim(module_id)] do
304-
nil -> raise "invalid module id: #{module_id}"
305-
module_id -> module_id
306-
end
307-
308-
question_id =
309-
case Integer.parse(String.trim(question_id)) do
310-
{id, ""} -> id
311-
_ -> raise "invalid question id: #{question_id}"
312-
end
313-
314-
case GradingClient.check_answer(module_id, question_id, result) do
276+
case GradingClient.check_answer(OWASP, 2, result) do
315277
:correct ->
316278
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
317279

modules/3-ssdlc.livemd

+1-20
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,7 @@ _Use `System.get_env/1` on line 2._
5252
```elixir
5353
result = super_secret_password = "p@ssw0rd"
5454

55-
[module_id, question_id] =
56-
"# SDLC:1\nsuper_secret_password = \"p@ssw0rd\""
57-
|> String.split("\n", parts: 2)
58-
|> hd()
59-
|> String.trim_leading("#")
60-
|> String.split(":", parts: 2)
61-
62-
module_id =
63-
case %{"ESCT" => ESCT, "OWASP" => OWASP}[String.trim(module_id)] do
64-
nil -> raise "invalid module id: #{module_id}"
65-
module_id -> module_id
66-
end
67-
68-
question_id =
69-
case Integer.parse(String.trim(question_id)) do
70-
{id, ""} -> id
71-
_ -> raise "invalid question id: #{question_id}"
72-
end
73-
74-
case GradingClient.check_answer(module_id, question_id, result) do
55+
case GradingClient.check_answer(SDLC, 1, result) do
7556
:correct ->
7657
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
7758

modules/4-graphql.livemd

+2-40
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,7 @@ result =
7676
Kino.Input.read(input)
7777
)
7878

79-
[module_id, question_id] =
80-
"# GRAPHQL:1\n\ninput = Kino.Input.select(\"Choose your answer\", [\n a: \"API6_2019_Mass_Assignment\", \n b: \"API10_2019_Insufficient_Logging_Monitoring\", \n c: \"API3_2019_Excessive_Data_Exposure\",\n d: \"API4_2019_Lack_of_Resources_Rate_Limiting\"\n])\n\nKino.render(input)\n\nKino.Input.read(input)"
81-
|> String.split("\n", parts: 2)
82-
|> hd()
83-
|> String.trim_leading("#")
84-
|> String.split(":", parts: 2)
85-
86-
module_id =
87-
case %{"ESCT" => ESCT, "GRAPHQL" => GRAPHQL, "OWASP" => OWASP}[String.trim(module_id)] do
88-
nil -> raise "invalid module id: #{module_id}"
89-
module_id -> module_id
90-
end
91-
92-
question_id =
93-
case Integer.parse(String.trim(question_id)) do
94-
{id, ""} -> id
95-
_ -> raise "invalid question id: #{question_id}"
96-
end
97-
98-
case GradingClient.check_answer(module_id, question_id, result) do
79+
case GradingClient.check_answer(GRAPHQL, 1, result) do
9980
:correct ->
10081
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
10182

@@ -141,26 +122,7 @@ result =
141122
Kino.Input.read(input)
142123
)
143124

144-
[module_id, question_id] =
145-
"# GRAPHQL:2\n\n# -------------------------------------------------------------\n# Option 1\n#\n# HTTP/2 401 Unauthorized\n# Date: Tues, 16 Aug 2022 21:06:42 GMT\n# …\n# {\n# \t“error”:”token expired”\n# {\n# -------------------------------------------------------------\n# Option 2\n#\n# HTTP/2 200 OK\n# Date: Tues, 16 Aug 2021 22:06:42 GMT\n# …\n# {\n# \t“errors”:[\n# \t\t{\n# \t\t\t“locations”:[\n# \t\t\t{\n# \t\t\t\t“column”:2,\n# \t\t\t\t:line”:2\n# \t\t\t}\n# \t\t\t],\n# \t\t\t“message”: “Parsing failed at\n# \t\t}\n# \t]\n# }\n# --------------------------------------------------------------\n# Option 3\n#\n# HTTP/2 200 OK\n# Date: Tues, 16 Aug 2022 21:06:42 GMT\n# …\n# {\n# \t“error”:”ID token for user 55e4cb07 at org 1234 expired”\n# {\n# ---------------------------------------------------------------\n# Option 4\n#\n# HTTP/2 404 File Not Found\n# Date: Tues, 16 Aug 2022 21:06:42 GMT\n# …\n# {\n# \t“error”:”/www/home/file.txt not found ”\n# {\n# ---------------------------------------------------------------\n\ninput = Kino.Input.select(\"Choose your answer\", [\n none: \"\",\n a: \"Option 1\", \n b: \"Option 2\", \n c: \"Option 3\",\n d: \"Option 4\"\n], default: :none)\n\nKino.render(input)\n\nKino.Input.read(input)"
146-
|> String.split("\n", parts: 2)
147-
|> hd()
148-
|> String.trim_leading("#")
149-
|> String.split(":", parts: 2)
150-
151-
module_id =
152-
case %{"ESCT" => ESCT, "GRAPHQL" => GRAPHQL, "OWASP" => OWASP}[String.trim(module_id)] do
153-
nil -> raise "invalid module id: #{module_id}"
154-
module_id -> module_id
155-
end
156-
157-
question_id =
158-
case Integer.parse(String.trim(question_id)) do
159-
{id, ""} -> id
160-
_ -> raise "invalid question id: #{question_id}"
161-
end
162-
163-
case GradingClient.check_answer(module_id, question_id, result) do
125+
case GradingClient.check_answer(GRAPHQL, 2, result) do
164126
:correct ->
165127
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
166128

modules/5-elixir.livemd

+3-75
Original file line numberDiff line numberDiff line change
@@ -64,31 +64,7 @@ result =
6464
end
6565
)
6666

67-
[module_id, question_id] =
68-
"# ELIXIR_SECURITY:1\nmalicious_user_input = UUID.uuid4()\n\ntry do\n malicious_user_input\n # ONLY CHANGE NEXT LINE\n |> String.to_atom()\nrescue\n e -> e\nend"
69-
|> String.split("\n", parts: 2)
70-
|> hd()
71-
|> String.trim_leading("#")
72-
|> String.split(":", parts: 2)
73-
74-
module_id =
75-
case %{
76-
"ELIXIR_SECURITY" => ELIXIR_SECURITY,
77-
"GRAPHQL" => GRAPHQL,
78-
"OWASP" => OWASP,
79-
"SDLC" => SDLC
80-
}[String.trim(module_id)] do
81-
nil -> raise "invalid module id: #{module_id}"
82-
module_id -> module_id
83-
end
84-
85-
question_id =
86-
case Integer.parse(String.trim(question_id)) do
87-
{id, ""} -> id
88-
_ -> raise "invalid question id: #{question_id}"
89-
end
90-
91-
case GradingClient.check_answer(module_id, question_id, result) do
67+
case GradingClient.check_answer(ELIXIR_SECURITY, 1, result) do
9268
:correct ->
9369
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
9470

@@ -263,31 +239,7 @@ result =
263239
end
264240
)
265241

266-
[module_id, question_id] =
267-
"# ELIXIR_SECURITY:2\n\ndefmodule SecurityCheck do\n def validate(input, password_hash) do\n case Plug.Crypto.secure_compare(input, password_hash) do\n true -> :ok\n false -> :access_denied\n end\n end\n\n defexception message: \"There was an issue\"\nend\n\npassword = \"some_secure_password_hash\"\nuser_input = \"some_string_which_obviously_isnt_the_same_as_the_password\"\n:ok\n# DO NOT EDIT ANY CODE ABOVE THIS LINE =====================\n\ntry do\n# if SecurityCheck.validate(user_input, password) or raise(SecurityCheck) do :you_let_a_baddie_in end\n# if SecurityCheck.validate(user_input, password) || raise(SecurityCheck) do :you_let_a_baddie_in end\nrescue\n e -> e\nend"
268-
|> String.split("\n", parts: 2)
269-
|> hd()
270-
|> String.trim_leading("#")
271-
|> String.split(":", parts: 2)
272-
273-
module_id =
274-
case %{
275-
"ELIXIR_SECURITY" => ELIXIR_SECURITY,
276-
"GRAPHQL" => GRAPHQL,
277-
"OWASP" => OWASP,
278-
"SDLC" => SDLC
279-
}[String.trim(module_id)] do
280-
nil -> raise "invalid module id: #{module_id}"
281-
module_id -> module_id
282-
end
283-
284-
question_id =
285-
case Integer.parse(String.trim(question_id)) do
286-
{id, ""} -> id
287-
_ -> raise "invalid question id: #{question_id}"
288-
end
289-
290-
case GradingClient.check_answer(module_id, question_id, result) do
242+
case GradingClient.check_answer(ELIXIR_SECURITY, 2, result) do
291243
:correct ->
292244
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
293245

@@ -361,31 +313,7 @@ result =
361313
:ets.info(secret_table)[:protection]
362314
)
363315

364-
[module_id, question_id] =
365-
"# ELIXIR_SECURITY:3\n\n# ONLY EDIT THIS LINE\nsecret_table = :ets.new(:secret_table, [:public])\n:ets.info(secret_table)[:protection]"
366-
|> String.split("\n", parts: 2)
367-
|> hd()
368-
|> String.trim_leading("#")
369-
|> String.split(":", parts: 2)
370-
371-
module_id =
372-
case %{
373-
"ELIXIR_SECURITY" => ELIXIR_SECURITY,
374-
"GRAPHQL" => GRAPHQL,
375-
"OWASP" => OWASP,
376-
"SDLC" => SDLC
377-
}[String.trim(module_id)] do
378-
nil -> raise "invalid module id: #{module_id}"
379-
module_id -> module_id
380-
end
381-
382-
question_id =
383-
case Integer.parse(String.trim(question_id)) do
384-
{id, ""} -> id
385-
_ -> raise "invalid question id: #{question_id}"
386-
end
387-
388-
case GradingClient.check_answer(module_id, question_id, result) do
316+
case GradingClient.check_answer(ELIXIR_SECURITY, 3, result) do
389317
:correct ->
390318
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
391319

modules/6-cookies.livemd

+1-26
Original file line numberDiff line numberDiff line change
@@ -197,32 +197,7 @@ result =
197197
{cookie, binary_part(cookie_name, 0, 6)}
198198
)
199199

200-
[module_id, question_id] =
201-
"# COOKIE_SECURITY:1 \n\ncookie_name = \"CHANGE_ME\"\n\n# Uncomment and change the put_resp_cookie call below\n# conn =\n# Plug.Conn.put_resp_cookie(\n# conn,\n# cookie_name,\n# <<0::8, 42::8>>,\n# domain: ...,\n# path: ...,\n# secure: ...,\n# http_only: ...,\n# same_site: ...\n# )\n\ncookie = \n conn\n |> Plug.Conn.fetch_cookies()\n |> Plug.Conn.get_resp_cookies()\n |> Map.fetch!(cookie_name)\n\n{cookie, binary_part(cookie_name, 0, 6)}"
202-
|> String.split("\n", parts: 2)
203-
|> hd()
204-
|> String.trim_leading("#")
205-
|> String.split(":", parts: 2)
206-
207-
module_id =
208-
case %{
209-
"COOKIE_SECURITY" => COOKIE_SECURITY,
210-
"ELIXIR_SECURITY" => ELIXIR_SECURITY,
211-
"GRAPHQL" => GRAPHQL,
212-
"OWASP" => OWASP,
213-
"SDLC" => SDLC
214-
}[String.trim(module_id)] do
215-
nil -> raise "invalid module id: #{module_id}"
216-
module_id -> module_id
217-
end
218-
219-
question_id =
220-
case Integer.parse(String.trim(question_id)) do
221-
{id, ""} -> id
222-
_ -> raise "invalid question id: #{question_id}"
223-
end
224-
225-
case GradingClient.check_answer(module_id, question_id, result) do
200+
case GradingClient.check_answer(COOKIE_SECURITY, 1, result) do
226201
:correct ->
227202
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
228203

modules/7-anti-patterns.livemd

+2-30
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,7 @@ Penguin.slide([3, 4, 5, 2, 1])
7171

7272
### <span style="color:red;">Quiz</span>
7373

74-
**What sort method is the module above using?**
75-
76-
_Uncomment the line with your answer._
74+
**What sorting algorithm is the module above using?**
7775

7876
<!-- livebook:{"attrs":"eyJzb3VyY2UiOiIjIEFOVElQQVRURVJOUzoxXG5cbmlucHV0ID0gS2luby5JbnB1dC5zZWxlY3QoXCJBbnN3ZXJcIiwgW1xuICBhOiBcIkJ1YmJsZSBTb3J0XCIsXG4gIGI6IFwiTWVyZ2UgU29ydFwiLFxuICBjOiBcIlF1aWNrIFNvcnRcIixcbiAgZDogXCJSYW5kb20gU29ydFwiXG5dKVxuXG5LaW5vLnJlbmRlcihpbnB1dClcblxuS2luby5JbnB1dC5yZWFkKGlucHV0KSJ9","chunks":null,"kind":"Elixir.GradingClient.GradedCell","livebook_object":"smart_cell"} -->
7977

@@ -92,33 +90,7 @@ result =
9290
Kino.Input.read(input)
9391
)
9492

95-
[module_id, question_id] =
96-
"# ANTIPATTERNS:1\n\ninput = Kino.Input.select(\"Answer\", [\n a: \"Bubble Sort\",\n b: \"Merge Sort\",\n c: \"Quick Sort\",\n d: \"Random Sort\"\n])\n\nKino.render(input)\n\nKino.Input.read(input)"
97-
|> String.split("\n", parts: 2)
98-
|> hd()
99-
|> String.trim_leading("#")
100-
|> String.split(":", parts: 2)
101-
102-
module_id =
103-
case %{
104-
"ANTIPATTERNS" => ANTIPATTERNS,
105-
"COOKIE_SECURITY" => COOKIE_SECURITY,
106-
"ELIXIR_SECURITY" => ELIXIR_SECURITY,
107-
"GRAPHQL" => GRAPHQL,
108-
"OWASP" => OWASP,
109-
"SDLC" => SDLC
110-
}[String.trim(module_id)] do
111-
nil -> raise "invalid module id: #{module_id}"
112-
module_id -> module_id
113-
end
114-
115-
question_id =
116-
case Integer.parse(String.trim(question_id)) do
117-
{id, ""} -> id
118-
_ -> raise "invalid question id: #{question_id}"
119-
end
120-
121-
case GradingClient.check_answer(module_id, question_id, result) do
93+
case GradingClient.check_answer(ANTIPATTERNS, 1, result) do
12294
:correct ->
12395
IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()])
12496

modules/8-cicd.livemd

+10-7
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,25 @@ This module will cover over some of the automated processes you may see in a CI/
3131

3232
Built in Elixir, for Elixir, by NCC Group - this tool will try to determine whether your codebase has a number of web vulnerabilities as well as the insecurites outlined in [Module 5 - Elixir Security](./5-elixir.livemd).
3333

34-
### <span style="color:blue;">Example</span>
34+
### <span style="color:blue;">Example</span>
35+
3536
Install [Sobelow](https://sobelow.io/) and add it to your application dependencies or install it by following the instructions https://hexdocs.pm/sobelow/readme.html
3637

3738
Scan your project by running the following at a terminal in your project's root directory
39+
3840
```
3941
$ mix sobelow
4042
```
41-
As a vulnerability scanner, there are multiple categories of vulnerabilities sobelow is capable of discovering and reporting on.
4243

43-
For instance, there are a number of security issues published on the Common Weakness Enumeration (CWE) site - [CWE's](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html) and on OWASP Top 10 [OWASP Top 10](https://owasp.org/www-project-top-ten/).
44+
As a vulnerability scanner, there are multiple categories of vulnerabilities sobelow is capable of discovering and reporting on.
45+
46+
For instance, there are a number of security issues published on the Common Weakness Enumeration (CWE) site - [CWE's](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html) and on OWASP Top 10 [OWASP Top 10](https://owasp.org/www-project-top-ten/).
4447

4548
Scanning tools like Sobelow identify code patterns that match these issues and report them back to developers/users.
4649

47-
### <span style="color:blue;">Example</span>
48-
49-
Let's say you are interested finding in places in your application that may be susceptible to injection attacks.
50+
### <span style="color:blue;">Example</span>
51+
52+
Let's say you are interested finding in places in your application that may be susceptible to injection attacks.
5053

5154
There are several types of injection. Referring to the CWE list, we see #17 CWE-77 for Command Injection, #25 CWE-94 is Code Injection, and #3 CWE-89 is SQL Injection. If we look at the OWASP Top 10 for 2021, A03:2021-Injection is third on the list. Sobelow has the capability to detect these types of security issues.
5255

@@ -59,7 +62,7 @@ Sobelow.CI
5962
Sobelow.CI.OS
6063
Sobelow.CI.System
6164
```
62-
65+
6366
Reference: https://docs.guardrails.io/docs/vulnerabilities/elixir/insecure_use_of_dangerous_function
6467

6568
### Usage

0 commit comments

Comments
 (0)