Skip to content

Commit 80566d7

Browse files
committed
Updating for Joi episode
1 parent b7fd5cd commit 80566d7

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#+OPTIONS: num:nil toc:nil
2+
#+OPTIONS: tags:nil
3+
#+OPTIONS: reveal_center:nil reveal_control:nil width:100% height:100% prop:nil
4+
#+OPTIONS: reveal_history:t reveal_keyboard:t reveal_overview:t
5+
#+OPTIONS: reveal_slide_number:nil
6+
#+OPTIONS: reveal_title_slide:"<h2>%t</h2><h3>%d<h3>"
7+
#+OPTIONS: reveal_progress:t reveal_rolling_links:nil reveal_single_file:nil
8+
#+OPTIONS: auto-id:t ^:nil
9+
#+TITLE: Joi.js Input Validation (Part 1)
10+
#+DATE: Input Validation Defenses/Attacks
11+
#+AUTHOR: Zach Roof
12+
#+REVEAL_HLEVEL: 1
13+
#+REVEAL_MARGIN: 0
14+
#+REVEAL_MIN_SCALE: 1
15+
#+REVEAL_MAX_SCALE: 1
16+
#+REVEAL_ROOT: .
17+
#+REVEAL_TRANS: default
18+
#+REVEAL_SPEED: slow
19+
#+REVEAL_THEME: sts
20+
#+REVEAL_EXTRA_CSS: css/local.css
21+
#+REVEAL_INIT_SCRIPT: previewLinks: false
22+
#+REVEAL_PLUGINS: (classList highlight)
23+
#+REVEAL_HIGHLIGHT_CSS: %r/lib/highlight.js/src/styles/monokai-sublime.css
24+
#+REVEAL_HLEVEL: 2
25+
#+NAME: CURRENT_TUTORIAL
26+
* Joi.js Input Validation (Part 1)
27+
** Table Of Contents
28+
- [[#joijs-input-validation-part-1][Joi.js Input Validation (Part 1)]]
29+
- [[#scope][Scope]]
30+
- [[#what-is-joi][What is Joi?]]
31+
- [[#why-leverage-joi][Why Leverage Joi?]]
32+
- [[#types-of-input-validation-question][Types Of Input Validation (Question)]]
33+
- [[#types-of-input-validation-answer][Types Of Input Validation (Answer)]]
34+
- [[#joi-advantages][Joi Advantages]]
35+
- [[#joi-advantages-cont][Joi Advantages (CONT.)]]
36+
- [[#joi-schemas][Joi Schemas]]
37+
- [[#joi-schemas-cont][Joi Schemas (CONT.)]]
38+
- [[#additional-joi-types][Additional Joi Types]]
39+
- [[#ex-joi-bypass-question][Ex: Joi Bypass (Question)]]
40+
- [[#ex-joi-schemapayload][Ex: Joi Schema/Payload]]
41+
- [[#ex-joi-schemapayload-result][Ex: Joi Schema/Payload (Result)]]
42+
43+
** Scope
44+
1. Understand how to approach input validation (useful for any input validation library)
45+
2. Learn how to create json validation schemas within Joi.js
46+
47+
** What is Joi?
48+
- Javascript input validation library
49+
- Create JSON schemas that validate JSON payloads entering an API (or leaving
50+
a browser)
51+
** Why Leverage Joi?
52+
- Very granular whitelisting functionality
53+
- Define what you will accept from the user
54+
- Everything else is denied by default
55+
** Types Of Input Validation (Question)
56+
- In general, when user input is sent to the api, what /types/ of input
57+
validation should we preform?
58+
- HINT
59+
- Think about the different types of coding errors
60+
- There are two primary types
61+
** Types Of Input Validation (Answer)
62+
- 2 primary checks need to occur when untrusted input (user input) comes to
63+
the API
64+
- If these checks aren't completed, the server might act in unintended ways
65+
- Types of input validation checks
66+
1. "Syntactic" Checks (Checking the /form/ of the input)
67+
- Ex: Is the input a string with length ~X~?
68+
- Regular Express Denial Of Service (ReDoS) mitigation
69+
- Usecase for Joi
70+
2. "Semantic" Checks (Logic Checks)
71+
- Ex: Does the user have appropriate permissions to do action ~X~?
72+
- Not what Joi is intended for
73+
** Joi Advantages
74+
- If you aren't leveraging Javascript/Node.js, look for these features in a framework
75+
- Share JSON schema between frontend/backend
76+
- Frontend
77+
- https://github.com/jeffbski/joi-browser
78+
- Backend
79+
- https://github.com/hapijs/joi
80+
- Installation instructions
81+
- Validated at entrypoint
82+
- Much safer than validating through database library
83+
** Joi Advantages (CONT.)
84+
- [[https://github.com/arb/celebrate][Celebrate]]
85+
- A Joi validation middleware for Express.js
86+
** Joi Schemas
87+
- Joi leverages schemas to define validations
88+
- Within a schema, you define ~types~ and ~constraints~
89+
- ~username: Joi.string().alphanum().min(3).max(30).required()~
90+
1. Type Ex: ~Joi.string()~
91+
- ~Joi.string()~ generates a schema object that matches a string data type
92+
- Inherits from ~Joi.any()~
93+
- Generates a schema object that matches any data type
94+
2. Constraint Ex: ~.min(3)~
95+
- Each constraint returns a new schema object
96+
- Method chaining is available
97+
** Joi Schemas (CONT.)
98+
- ~username: Joi.string().alphanum().min(3).max(30).required()~
99+
- Values (or keys in case of objects) are optional by default
100+
101+
** Additional Joi Types
102+
- Ex: ~username: Joi.string().alphanum().min(3).max(30).required()~
103+
- Besides ~string()~, what other types can we validate?
104+
- Joi Types
105+
- [[https://github.com/hapijs/joi/blob/v13.6.0/api.md#array---inherits-from-any][Array]]
106+
- [[https://github.com/hapijs/joi/blob/v13.6.0/API.md#boolean---inherits-from-any][Boolean]]
107+
- [[https://github.com/hapijs/joi/blob/v13.6.0/API.md#binary---inherits-from-any][Binary]]
108+
- [[https://github.com/hapijs/joi/blob/v13.6.0/API.md#date---inherits-from-any][Date]]
109+
- [[https://github.com/hapijs/joi/blob/v13.6.0/API.md#func---inherits-from-any][Func]]
110+
- [[https://github.com/hapijs/joi/blob/v13.6.0/API.md#number---inherits-from-any][Number]]
111+
- [[https://github.com/hapijs/joi/blob/v13.6.0/API.md#object---inherits-from-any][Object]]
112+
113+
** Ex: Joi Bypass (Question)
114+
- While viewing the following schema object (and payload) on the next slide,
115+
think about how it could be exploited/bypassed
116+
- Further assumptions
117+
1. JSON payload is submitted to the API
118+
2. Joi doesn't throw a validation error
119+
3. The JSON is directly saved to the database
120+
- Payload key/value pairs are directly mapped to database fields/values
121+
- Try to figure out how the following schema could be exploited
122+
- https://sts.tools/joi-schema
123+
124+
** Ex: Joi Schema/Payload
125+
#+BEGIN_SRC js
126+
const Joi = require('joi');
127+
128+
const schema = Joi.object()
129+
.keys({
130+
// Requires a given string value
131+
username: Joi.string()
132+
.alphanum()
133+
.min(3)
134+
.max(30)
135+
.required(),
136+
// Define password complexity requirements through regex (consider more complex regex)
137+
password: Joi.string()
138+
.regex(/^[a-zA-Z0-9]{3,30}$/)
139+
.required(),
140+
// Force passwords to match
141+
password_confirmation: Joi.any()
142+
.equal(Joi.ref('password'))
143+
.required(),
144+
// Accept different Joi types. Optional, unconstrained string or number
145+
access_token: [Joi.string(), Joi.number()],
146+
// Required birthyear to be an int between range
147+
birthyear: Joi.number()
148+
.integer()
149+
.min(1900)
150+
.max(2013)
151+
.required(),
152+
// Validate email address from example.com (remember spoofing considerations)
153+
email: Joi.string()
154+
.email()
155+
.regex(/example\.com$/),
156+
marketing_opt_out: Joi.boolean(),
157+
csrf_token: Joi.string()
158+
.guid({
159+
version: 'uuidv4',
160+
})
161+
.required(),
162+
sex: Joi.string()
163+
.equal(['M', 'F', 'MALE', 'FEMALE', 'DECLINE'])
164+
.required(),
165+
time: Joi.date()
166+
.timestamp('javascript'),
167+
roles: Joi.object()
168+
.keys(),
169+
})
170+
// email must be accompanied by marketing_opt_out
171+
.with('email', 'marketing_opt_out');
172+
173+
const result = Joi.validate({
174+
username: 'Ronald',
175+
password: 'McDonald',
176+
password_confirmation: 'McDonald',
177+
birthyear: 2010,
178+
179+
marketing_opt_out: true,
180+
csrf_token: '6d4d8c14-ef12-45d9-ab3c-5dddf941fb76',
181+
sex: 'F',
182+
time: 1534942475121,
183+
roles: {},
184+
}, schema);
185+
186+
// If result.error === null, payload is valid
187+
console.log(`The validation error is: ${result.error}`);
188+
#+END_SRC
189+
190+
** Ex: Joi Schema/Payload (Result)
191+
#+BEGIN_SRC text
192+
The validation error is: null
193+
#+END_SRC

0 commit comments

Comments
 (0)