From c6bc5471baecb03b870a0a18156d157e2421ab45 Mon Sep 17 00:00:00 2001 From: jamescaillenl Date: Wed, 24 Jun 2026 10:55:10 -0400 Subject: [PATCH 1/4] james caille 2026 elixir secure coding answers --- modules/2-owasp.livemd | 28 ++++++++++++++++------------ modules/3-ssdlc.livemd | 4 ++-- modules/5-elixir.livemd | 15 +++++++++------ modules/6-cookies.livemd | 10 ++++++++-- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/modules/2-owasp.livemd b/modules/2-owasp.livemd index 4b31bf5..8400588 100644 --- a/modules/2-owasp.livemd +++ b/modules/2-owasp.livemd @@ -101,25 +101,29 @@ Notable CWEs included are CWE-259: Use of Hard-coded Password, CWE-327: Broken o _Please uncomment the function call that you believe is correct._ - + ```elixir result = - defmodule PasswordCompare do - def option_one(password, md5_hash) do - case :crypto.hash(:md5, password) == md5_hash do - true -> :entry_granted_op1 - false -> :entry_denied_op1 + ( + defmodule PasswordCompare do + def option_one(password, md5_hash) do + case :crypto.hash(:md5, password) == md5_hash do + true -> :entry_granted_op1 + false -> :entry_denied_op1 + end end - end - def option_two(password, bcrypt_salted_hash) do - case Bcrypt.verify_pass(password, bcrypt_salted_hash) do - true -> :entry_granted_op2 - false -> :entry_denied_op2 + def option_two(password, bcrypt_salted_hash) do + case Bcrypt.verify_pass(password, bcrypt_salted_hash) do + true -> :entry_granted_op2 + false -> :entry_denied_op2 + end end end - end + + PasswordCompare.option_two("users_password", bcrypt_salted_hash) + ) case GradingClient.check_answer(OWASP, 1, result) do :correct -> diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index 276c1e2..b948c47 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -47,10 +47,10 @@ A very easy way to prevent secrets being added to files is to access them via En _Use `System.get_env/1` on line 2._ - + ```elixir -result = super_secret_password = "p@ssw0rd" +result = super_secret_password = System.get_env("envar_secret") case GradingClient.check_answer(SDLC, 1, result) do :correct -> diff --git a/modules/5-elixir.livemd b/modules/5-elixir.livemd index a3afc69..41eaa92 100644 --- a/modules/5-elixir.livemd +++ b/modules/5-elixir.livemd @@ -50,7 +50,7 @@ Beware of functions in applications/libraries that create atoms from input value _You should get a `true` result when you successfully fix the function._ - + ```elixir result = @@ -58,7 +58,7 @@ result = malicious_user_input = UUID.uuid4() try do - malicious_user_input |> String.to_atom() + malicious_user_input |> String.to_existing_atom() rescue e -> e end @@ -181,7 +181,7 @@ user_input = "HASH_OF_asdfasdf" Benchwarmer.benchmark(fn -> Susceptible.compare(user_input, password) end) Benchwarmer.benchmark(fn -> Constant.compare(user_input, password) end) -# IO.puts(:comparison_ran) +IO.puts(:comparison_ran) ``` ## Boolean Coercion @@ -213,7 +213,7 @@ The latter will raise a `BadBooleanError` when the function returns `:ok` or `{: _Uncomment the if statement that uses the correct boolean comparison._ - + ```elixir result = @@ -234,6 +234,9 @@ result = :ok try do + if SecurityCheck.validate(user_input, password) or raise(SecurityCheck) do + :you_let_a_baddie_in + end rescue e -> e end @@ -304,12 +307,12 @@ This prevents the table from being read by other processes, such as remote shell **We have decided that we do not want this ETS table to be read from other processes, so try making it private:** - + ```elixir result = ( - secret_table = :ets.new(:secret_table, [:public]) + secret_table = :ets.new(:secret_table, [:private]) :ets.info(secret_table)[:protection] ) diff --git a/modules/6-cookies.livemd b/modules/6-cookies.livemd index ec4f5a4..136675d 100644 --- a/modules/6-cookies.livemd +++ b/modules/6-cookies.livemd @@ -181,12 +181,18 @@ In the Phoenix Framework, you would use functionality found within the [Plug lib _Fill out the `put_resp_cookie/4` function arguments with the settings outlined in the previous section, no other code changes should be necessary._ - + ```elixir result = ( - cookie_name = "CHANGE_ME" + cookie_name = "__Host" + + conn = + Plug.Conn.put_resp_cookie( + conn, + cookie_name, + <<0::8, 42::8>>, path: "/", secure: true, http_only: true, same_site: "Strict") cookie = conn From 72c5a4bd485054df2d8235cf8c6945a9019c5d9d Mon Sep 17 00:00:00 2001 From: jamescaillenl Date: Fri, 26 Jun 2026 13:45:29 -0400 Subject: [PATCH 2/4] added comments for multiple choice answers --- modules/2-owasp.livemd | 2 +- modules/4-graphql.livemd | 4 ++-- modules/7-anti-patterns.livemd | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/2-owasp.livemd b/modules/2-owasp.livemd index 8400588..d57550a 100644 --- a/modules/2-owasp.livemd +++ b/modules/2-owasp.livemd @@ -261,7 +261,7 @@ _Please change the atom below to the name of the vulnerable package installed in _HINT: Check the changelogs for each dependency._ - + ```elixir result = diff --git a/modules/4-graphql.livemd b/modules/4-graphql.livemd index 19e716c..853b14e 100644 --- a/modules/4-graphql.livemd +++ b/modules/4-graphql.livemd @@ -59,7 +59,7 @@ It can also intercept responses to ensure no schema data is being leaked in any **Which of the OWASP API Security Top 10 2019 issues does disabling introspection queries address?** - + ```elixir result = @@ -106,7 +106,7 @@ OWASP recommends explicitly defining and enforcing all API response payload sche **Select the best example of a “good” error message, from the perspective of developer who is writing code that is intended to inform a user (who may or may not be a malicious actor) that the action they have attempted was unsuccessful:** - + ```elixir result = diff --git a/modules/7-anti-patterns.livemd b/modules/7-anti-patterns.livemd index 3904a6d..634de65 100644 --- a/modules/7-anti-patterns.livemd +++ b/modules/7-anti-patterns.livemd @@ -73,7 +73,7 @@ Penguin.slide([3, 4, 5, 2, 1]) **What sorting algorithm is the module above using?** - + ```elixir result = From 36b9fa78fcfdc9982aa0502b97187daaa3ce7c9a Mon Sep 17 00:00:00 2001 From: jamescaillenl Date: Fri, 26 Jun 2026 14:01:36 -0400 Subject: [PATCH 3/4] update plug --- modules/2-owasp.livemd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/2-owasp.livemd b/modules/2-owasp.livemd index d57550a..dd177c6 100644 --- a/modules/2-owasp.livemd +++ b/modules/2-owasp.livemd @@ -261,7 +261,7 @@ _Please change the atom below to the name of the vulnerable package installed in _HINT: Check the changelogs for each dependency._ - + ```elixir result = @@ -270,7 +270,7 @@ result = Kino.Input.select("Answer", ecto: "Ecto v2.2.2", nx: "Nx v0.5.0", - plug: "Plug v1.3.2" + plug: "Plug v1.4.0" ) Kino.render(answer) From 61f561630a7c576c1146685cb8443cd02ebc2fa5 Mon Sep 17 00:00:00 2001 From: jamescaillenl Date: Fri, 26 Jun 2026 14:06:57 -0400 Subject: [PATCH 4/4] save answers --- modules/2-owasp.livemd | 2 ++ modules/3-ssdlc.livemd | 2 ++ modules/4-graphql.livemd | 2 ++ modules/5-elixir.livemd | 2 ++ modules/6-cookies.livemd | 2 ++ modules/7-anti-patterns.livemd | 2 ++ modules/8-cicd.livemd | 2 ++ 7 files changed, 14 insertions(+) diff --git a/modules/2-owasp.livemd b/modules/2-owasp.livemd index dd177c6..c2a9926 100644 --- a/modules/2-owasp.livemd +++ b/modules/2-owasp.livemd @@ -1,3 +1,5 @@ + + # ESCT: Part 2 - OWASP ```elixir diff --git a/modules/3-ssdlc.livemd b/modules/3-ssdlc.livemd index b948c47..8e967a0 100644 --- a/modules/3-ssdlc.livemd +++ b/modules/3-ssdlc.livemd @@ -1,3 +1,5 @@ + + # ESCT: Part 3 - Secure SDLC Concepts ```elixir diff --git a/modules/4-graphql.livemd b/modules/4-graphql.livemd index 853b14e..5853198 100644 --- a/modules/4-graphql.livemd +++ b/modules/4-graphql.livemd @@ -1,3 +1,5 @@ + + # ESCT: Part 4 - GraphQL Security ```elixir diff --git a/modules/5-elixir.livemd b/modules/5-elixir.livemd index 41eaa92..ff3d126 100644 --- a/modules/5-elixir.livemd +++ b/modules/5-elixir.livemd @@ -1,3 +1,5 @@ + + # ESCT: Part 5 - Elixir Security ```elixir diff --git a/modules/6-cookies.livemd b/modules/6-cookies.livemd index 136675d..c2d2830 100644 --- a/modules/6-cookies.livemd +++ b/modules/6-cookies.livemd @@ -1,3 +1,5 @@ + + # ESCT: Part 6 - Cookie Security diff --git a/modules/7-anti-patterns.livemd b/modules/7-anti-patterns.livemd index 634de65..680867a 100644 --- a/modules/7-anti-patterns.livemd +++ b/modules/7-anti-patterns.livemd @@ -1,3 +1,5 @@ + + # ESCT: Part 7 - Security Anti-Patterns ```elixir diff --git a/modules/8-cicd.livemd b/modules/8-cicd.livemd index 729ce41..d59675a 100644 --- a/modules/8-cicd.livemd +++ b/modules/8-cicd.livemd @@ -1,3 +1,5 @@ + + # ESCT: Part 8 - CI/CD Tools ```elixir