@@ -59,15 +59,52 @@ It can also intercept responses to ensure no schema data is being leaked in any
59
59
60
60
** Which of the OWASP API Security Top 10 2019 issues does disabling introspection queries address?**
61
61
62
- _ Uncomment the line with your answer. _
62
+ <!-- livebook:{"attrs":"eyJzb3VyY2UiOiIjIEdSQVBIUUw6MVxuXG5pbnB1dCA9IEtpbm8uSW5wdXQuc2VsZWN0KFwiQ2hvb3NlIHlvdXIgYW5zd2VyXCIsIFtcbiAgYTogXCJBUEk2XzIwMTlfTWFzc19Bc3NpZ25tZW50XCIsIFxuICBiOiBcIkFQSTEwXzIwMTlfSW5zdWZmaWNpZW50X0xvZ2dpbmdfTW9uaXRvcmluZ1wiLCBcbiAgYzogXCJBUEkzXzIwMTlfRXhjZXNzaXZlX0RhdGFfRXhwb3N1cmVcIixcbiAgZDogXCJBUEk0XzIwMTlfTGFja19vZl9SZXNvdXJjZXNfUmF0ZV9MaW1pdGluZ1wiXG5dKVxuXG5LaW5vLnJlbmRlcihpbnB1dClcblxuS2luby5JbnB1dC5yZWFkKGlucHV0KSJ9","chunks":null,"kind":"Elixir.GradingClient.GradedCell","livebook_object":"smart_cell"} -->
63
63
64
64
``` elixir
65
- # answer = :API6_2019_Mass_Assignment
66
- # answer = :API10_2019_Insufficient_Logging_Monitoring
67
- # answer = :API3_2019_Excessive_Data_Exposure
68
- # answer = :API4_2019_Lack_of_Resources_Rate_Limiting
69
-
70
- IO .puts (answer)
65
+ result =
66
+ (
67
+ input =
68
+ Kino .Input .select (" Choose your answer" ,
69
+ a: " API6_2019_Mass_Assignment" ,
70
+ b: " API10_2019_Insufficient_Logging_Monitoring" ,
71
+ c: " API3_2019_Excessive_Data_Exposure" ,
72
+ d: " API4_2019_Lack_of_Resources_Rate_Limiting"
73
+ )
74
+
75
+ Kino .render (input)
76
+ Kino .Input .read (input)
77
+ )
78
+
79
+ [module_id, question_id] =
80
+ " # GRAPHQL:1\n\n input = 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\n Kino.render(input)\n\n Kino.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
99
+ :correct ->
100
+ IO .puts ([IO .ANSI .green (), " Correct!" , IO .ANSI .reset ()])
101
+
102
+ {:incorrect , help_text} when is_binary (help_text) - >
103
+ IO .puts ([IO .ANSI .red (), " Incorrect: " , IO .ANSI .reset (), help_text])
104
+
105
+ _ ->
106
+ IO .puts ([IO .ANSI .red (), " Incorrect." , IO .ANSI .reset ()])
107
+ end
71
108
```
72
109
73
110
## Error Disclosure
@@ -88,58 +125,51 @@ OWASP recommends explicitly defining and enforcing all API response payload sche
88
125
89
126
** 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:**
90
127
91
- _ Uncomment the item number (1-4) with your answer_
128
+ <!-- livebook:{"attrs":"eyJzb3VyY2UiOiIjIEdSQVBIUUw6MlxuXG4jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiMgT3B0aW9uIDFcbiNcbiMgSFRUUC8yIDQwMSBVbmF1dGhvcml6ZWRcbiMgRGF0ZTogVHVlcywgMTYgQXVnIDIwMjIgMjE6MDY6NDIgR01UXG4jIOKAplxuIyB7XG4jIFx04oCcZXJyb3LigJ064oCddG9rZW4gZXhwaXJlZOKAnVxuIyB7XG4jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiMgT3B0aW9uIDJcbiNcbiMgSFRUUC8yIDIwMCBPS1xuIyBEYXRlOiBUdWVzLCAxNiBBdWcgMjAyMSAyMjowNjo0MiBHTVRcbiMg4oCmXG4jIHtcbiMgXHTigJxlcnJvcnPigJ06W1xuIyBcdFx0e1xuIyBcdFx0XHTigJxsb2NhdGlvbnPigJ06W1xuIyBcdFx0XHR7XG4jIFx0XHRcdFx04oCcY29sdW1u4oCdOjIsXG4jIFx0XHRcdFx0OmxpbmXigJ06MlxuIyBcdFx0XHR9XG4jIFx0XHRcdF0sXG4jIFx0XHRcdOKAnG1lc3NhZ2XigJ06IOKAnFBhcnNpbmcgZmFpbGVkIGF0XG4jIFx0XHR9XG4jIFx0XVxuIyB9XG4jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4jIE9wdGlvbiAzXG4jXG4jIEhUVFAvMiAyMDAgT0tcbiMgRGF0ZTogVHVlcywgMTYgQXVnIDIwMjIgMjE6MDY6NDIgR01UXG4jIOKAplxuIyB7XG4jIFx04oCcZXJyb3LigJ064oCdSUQgdG9rZW4gZm9yIHVzZXIgNTVlNGNiMDcgYXQgb3JnIDEyMzQgZXhwaXJlZOKAnVxuIyB7XG4jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIyBPcHRpb24gNFxuI1xuIyBIVFRQLzIgNDA0IEZpbGUgTm90IEZvdW5kXG4jIERhdGU6IFR1ZXMsIDE2IEF1ZyAyMDIyIDIxOjA2OjQyIEdNVFxuIyDigKZcbiMge1xuIyBcdOKAnGVycm9y4oCdOuKAnS93d3cvaG9tZS9maWxlLnR4dCBub3QgZm91bmQg4oCdXG4jIHtcbiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmlucHV0ID0gS2luby5JbnB1dC5zZWxlY3QoXCJDaG9vc2UgeW91ciBhbnN3ZXJcIiwgW1xuICBub25lOiBcIlwiLFxuICBhOiBcIk9wdGlvbiAxXCIsIFxuICBiOiBcIk9wdGlvbiAyXCIsIFxuICBjOiBcIk9wdGlvbiAzXCIsXG4gIGQ6IFwiT3B0aW9uIDRcIlxuXSwgZGVmYXVsdDogOm5vbmUpXG5cbktpbm8ucmVuZGVyKGlucHV0KVxuXG5LaW5vLklucHV0LnJlYWQoaW5wdXQpIn0","chunks":null,"kind":"Elixir.GradingClient.GradedCell","livebook_object":"smart_cell"} -->
92
129
93
130
``` elixir
94
- # -------------------------------------------------------------
95
- # answer = 1
96
- #
97
- # HTTP/2 401 Unauthorized
98
- # Date: Tues, 16 Aug 2022 21:06:42 GMT
99
- # …
100
- # {
101
- # “error”:”token expired”
102
- # {
103
- # -------------------------------------------------------------
104
- # answer = 2
105
- #
106
- # HTTP/2 200 OK
107
- # Date: Tues, 16 Aug 2021 22:06:42 GMT
108
- # …
109
- # {
110
- # “errors”:[
111
- # {
112
- # “locations”:[
113
- # {
114
- # “column”:2,
115
- # :line”:2
116
- # }
117
- # ],
118
- # “message”: “Parsing failed at
119
- # }
120
- # ]
121
- # }
122
- # --------------------------------------------------------------
123
- # answer = 3
124
- #
125
- # HTTP/2 200 OK
126
- # Date: Tues, 16 Aug 2022 21:06:42 GMT
127
- # …
128
- # {
129
- # “error”:”ID token for user 55e4cb07 at org 1234 expired”
130
- # {
131
- # ---------------------------------------------------------------
132
- # answer = 4
133
- #
134
- # HTTP/2 404 File Not Found
135
- # Date: Tues, 16 Aug 2022 21:06:42 GMT
136
- # …
137
- # {
138
- # “error”:”/www/home/file.txt not found ”
139
- # {
140
- # ---------------------------------------------------------------
141
-
142
- IO .puts (answer)
131
+ result =
132
+ (
133
+ input =
134
+ Kino .Input .select (
135
+ " Choose your answer" ,
136
+ [none: " " , a: " Option 1" , b: " Option 2" , c: " Option 3" , d: " Option 4" ],
137
+ default: :none
138
+ )
139
+
140
+ Kino .render (input)
141
+ Kino .Input .read (input)
142
+ )
143
+
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
164
+ :correct ->
165
+ IO .puts ([IO .ANSI .green (), " Correct!" , IO .ANSI .reset ()])
166
+
167
+ {:incorrect , help_text} when is_binary (help_text) - >
168
+ IO .puts ([IO .ANSI .red (), " Incorrect: " , IO .ANSI .reset (), help_text])
169
+
170
+ _ ->
171
+ IO .puts ([IO .ANSI .red (), " Incorrect." , IO .ANSI .reset ()])
172
+ end
143
173
```
144
174
145
175
### Resources
0 commit comments