|
1 | 1 | # ESCT: Part 2 - OWASP
|
2 | 2 |
|
3 | 3 | ```elixir
|
4 |
| -Mix.install([ |
5 |
| - {:grading_client, path: "#{__DIR__}/grading_client"}, |
6 |
| - :bcrypt_elixir, |
7 |
| - :httpoison, |
8 |
| - {:absinthe, "~> 1.7.0"}, |
9 |
| - {:phoenix, "~> 1.0"}, |
10 |
| - {:plug, "~> 1.3.2"} |
11 |
| -]) |
| 4 | +Mix.install( |
| 5 | + [ |
| 6 | + {:grading_client, path: "#{__DIR__}/grading_client"} |
| 7 | + ], |
| 8 | + config_path: "#{__DIR__}/grading_client/config/config.exs" |
| 9 | +) |
12 | 10 |
|
13 | 11 | md5_hash = :crypto.hash(:md5, "users_password")
|
14 | 12 | bcrypt_salted_hash = Bcrypt.hash_pwd_salt("users_password")
|
@@ -103,27 +101,55 @@ Notable CWEs included are CWE-259: Use of Hard-coded Password, CWE-327: Broken o
|
103 | 101 |
|
104 | 102 | _Please uncomment the function call that you believe is correct._
|
105 | 103 |
|
| 104 | +<!-- livebook:{"attrs":"eyJtb2R1bGVfaWQiOm51bGwsInF1ZXN0aW9uX2lkIjpudWxsLCJzb3VyY2UiOiIjT1dBU1A6MVxuZGVmbW9kdWxlIFBhc3N3b3JkQ29tcGFyZSBkb1xuICBkZWYgb3B0aW9uX29uZShwYXNzd29yZCwgbWQ1X2hhc2gpIGRvXG4gICAgY2FzZSA6Y3J5cHRvLmhhc2goOm1kNSwgcGFzc3dvcmQpID09IG1kNV9oYXNoIGRvXG4gICAgICB0cnVlIC0+IDplbnRyeV9ncmFudGVkX29wMVxuICAgICAgZmFsc2UgLT4gOmVudHJ5X2RlbmllZF9vcDFcbiAgICBlbmRcbiAgZW5kXG5cbiAgZGVmIG9wdGlvbl90d28ocGFzc3dvcmQsIGJjcnlwdF9zYWx0ZWRfaGFzaCkgZG9cbiAgICBjYXNlIEJjcnlwdC52ZXJpZnlfcGFzcyhwYXNzd29yZCwgYmNyeXB0X3NhbHRlZF9oYXNoKSBkb1xuICAgICAgdHJ1ZSAtPiA6ZW50cnlfZ3JhbnRlZF9vcDJcbiAgICAgIGZhbHNlIC0+IDplbnRyeV9kZW5pZWRfb3AyXG4gICAgZW5kXG4gIGVuZFxuZW5kXG5cbiMgRE8gTk9UIENIQU5HRSBDT0RFIEFCT1ZFIFRISVMgTElORSA9PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiMgUGFzc3dvcmRDb21wYXJlLm9wdGlvbl9vbmUoXCJ1c2Vyc19wYXNzd29yZFwiLCBtZDVfaGFzaClcbiMgUGFzc3dvcmRDb21wYXJlLm9wdGlvbl90d28oXCJ1c2Vyc19wYXNzd29yZFwiLCBiY3J5cHRfc2FsdGVkX2hhc2gpIn0","chunks":null,"kind":"Elixir.GradingClient.GradedCell","livebook_object":"smart_cell"} --> |
| 105 | + |
106 | 106 | ```elixir
|
107 |
| -defmodule PasswordCompare do |
108 |
| - def option_one(password, md5_hash) do |
109 |
| - case :crypto.hash(:md5, password) == md5_hash do |
110 |
| - true -> :entry_granted_op1 |
111 |
| - false -> :entry_denied_op1 |
| 107 | +result = |
| 108 | + defmodule PasswordCompare do |
| 109 | + def option_one(password, md5_hash) do |
| 110 | + case :crypto.hash(:md5, password) == md5_hash do |
| 111 | + true -> :entry_granted_op1 |
| 112 | + false -> :entry_denied_op1 |
| 113 | + end |
112 | 114 | end
|
113 |
| - end |
114 | 115 |
|
115 |
| - def option_two(password, bcrypt_salted_hash) do |
116 |
| - case Bcrypt.verify_pass(password, bcrypt_salted_hash) do |
117 |
| - true -> :entry_granted_op2 |
118 |
| - false -> :entry_denied_op2 |
| 116 | + def option_two(password, bcrypt_salted_hash) do |
| 117 | + case Bcrypt.verify_pass(password, bcrypt_salted_hash) do |
| 118 | + true -> :entry_granted_op2 |
| 119 | + false -> :entry_denied_op2 |
| 120 | + end |
119 | 121 | end
|
120 | 122 | end
|
121 |
| -end |
122 | 123 |
|
123 |
| -# DO NOT CHANGE CODE ABOVE THIS LINE ========================= |
| 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 |
| 144 | + :correct -> |
| 145 | + IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()]) |
| 146 | + |
| 147 | + {:incorrect, help_text} when is_binary(help_text) -> |
| 148 | + IO.puts([IO.ANSI.red(), "Incorrect: ", IO.ANSI.reset(), help_text]) |
124 | 149 |
|
125 |
| -# PasswordCompare.option_one("users_password", md5_hash) |
126 |
| -# PasswordCompare.option_two("users_password", bcrypt_salted_hash) |
| 150 | + _ -> |
| 151 | + IO.puts([IO.ANSI.red(), "Incorrect.", IO.ANSI.reset()]) |
| 152 | +end |
127 | 153 | ```
|
128 | 154 |
|
129 | 155 | <!-- livebook:{"branch_parent_index":3} -->
|
@@ -244,19 +270,57 @@ Notable CWE included is CWE-1104: Use of Unmaintained Third-Party Components
|
244 | 270 |
|
245 | 271 | ### <span style="color:red">QUIZ</span>
|
246 | 272 |
|
247 |
| -**Which of the outdated components currently installed is vulnerable?** |
| 273 | +**Which of the outdated components listed below is vulnerable?** |
248 | 274 |
|
249 | 275 | _Please change the atom below to the name of the vulnerable package installed in this Livebook AND update the afflicted package._
|
250 | 276 |
|
251 |
| -_HINT: Installed dependencies can be found at the very top, it was the very first cell you ran._ |
| 277 | +_HINT: Check the changelogs for each dependency._ |
| 278 | + |
| 279 | +<!-- livebook:{"attrs":"eyJtb2R1bGVfaWQiOm51bGwsInF1ZXN0aW9uX2lkIjpudWxsLCJzb3VyY2UiOiIjT1dBU1A6MlxuYW5zd2VyID0gXG4gIEtpbm8uSW5wdXQuc2VsZWN0KFwiQW5zd2VyXCIsIFtcbiAgICB7OmVjdG8sIFwiRWN0byB2Mi4yLjJcIn0sXG4gICAgezpueCwgXCJOeCB2MC41LjBcIn0sXG4gICAgezpwbHVnLCBcIlBsdWcgdjEuMy4yXCJ9XG4gIF0pXG5cbktpbm8ucmVuZGVyKGFuc3dlcilcblxuS2luby5JbnB1dC5yZWFkKGFuc3dlcikifQ","chunks":null,"kind":"Elixir.GradingClient.GradedCell","livebook_object":"smart_cell"} --> |
252 | 280 |
|
253 | 281 | ```elixir
|
254 |
| -# CHANGE ME |
255 |
| -vulnerable_dependency = :vulnerable_dependency |
| 282 | +result = |
| 283 | + ( |
| 284 | + answer = |
| 285 | + Kino.Input.select("Answer", |
| 286 | + ecto: "Ecto v2.2.2", |
| 287 | + nx: "Nx v0.5.0", |
| 288 | + plug: "Plug v1.3.2" |
| 289 | + ) |
| 290 | + |
| 291 | + Kino.render(answer) |
| 292 | + Kino.Input.read(answer) |
| 293 | + ) |
| 294 | + |
| 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 |
| 315 | + :correct -> |
| 316 | + IO.puts([IO.ANSI.green(), "Correct!", IO.ANSI.reset()]) |
256 | 317 |
|
257 |
| -# DO NOT CHANGE CODE BELOW THIS LINE ============================ |
258 |
| -Application.spec(vulnerable_dependency)[:vsn] |> List.to_string() |> IO.puts() |
259 |
| -IO.puts(vulnerable_dependency) |
| 318 | + {:incorrect, help_text} when is_binary(help_text) -> |
| 319 | + IO.puts([IO.ANSI.red(), "Incorrect: ", IO.ANSI.reset(), help_text]) |
| 320 | + |
| 321 | + _ -> |
| 322 | + IO.puts([IO.ANSI.red(), "Incorrect.", IO.ANSI.reset()]) |
| 323 | +end |
260 | 324 | ```
|
261 | 325 |
|
262 | 326 | <!-- livebook:{"branch_parent_index":3} -->
|
|
0 commit comments