1
1

00:00:00,570  -->  00:00:02,010
<v Instructor>Secure Coding.</v>
2

2

00:00:02,010  -->  00:00:03,690
In this lesson, we are going to talk
3

3

00:00:03,690  -->  00:00:06,510
about some secure coding best practices,
4

4

00:00:06,510  -->  00:00:09,720
and in this lesson, we're going to talk about input validation,
5

5

00:00:09,720  -->  00:00:12,540
output encoding, and parameterized queries.
6

6

00:00:12,540  -->  00:00:14,610
First, let's talk about input validation.
7

7

00:00:14,610  -->  00:00:16,740
Now, I know I've mentioned how important it is
8

8

00:00:16,740  -->  00:00:20,580
when I talked about XML and SQL and directory traversals
9

9

00:00:20,580  -->  00:00:23,310
and we kept saying input validation was important,
10

10

00:00:23,310  -->  00:00:24,960
but we never really defined it.
11

11

00:00:24,960  -->  00:00:27,780
Well, input validation is any technique that you use
12

12

00:00:27,780  -->  00:00:30,570
to ensure the data entered into a field or a variable
13

13

00:00:30,570  -->  00:00:33,120
into an application is handled appropriately
14

14

00:00:33,120  -->  00:00:34,860
by that application.
15

15

00:00:34,860  -->  00:00:37,230
Now, essentially, when I take something from a user,
16

16

00:00:37,230  -->  00:00:39,510
I want to make sure it's actually accurate.
17

17

00:00:39,510  -->  00:00:41,100
If you go to my website and you try
18

18

00:00:41,100  -->  00:00:43,110
to enter in your username or your password,
19

19

00:00:43,110  -->  00:00:45,270
I want to make sure you're giving me valid data
20

20

00:00:45,270  -->  00:00:48,240
before I send it to my database to try and see if it works.
21

21

00:00:48,240  -->  00:00:50,100
So when we talk about input validation,
22

22

00:00:50,100  -->  00:00:52,320
this can be conducted in two ways.
23

23

00:00:52,320  -->  00:00:54,690
It can be conducted locally on your client
24

24

00:00:54,690  -->  00:00:57,630
or remotely on the server that you're trying to access.
25

25

00:00:57,630  -->  00:00:59,730
Now, this means that there's two different ways
26

26

00:00:59,730  -->  00:01:01,500
to think about this, but I want to give you
27

27

00:01:01,500  -->  00:01:04,650
a big warning here, while client side was used in the past
28

28

00:01:04,650  -->  00:01:07,380
a lot, you really should be careful using it.
29

29

00:01:07,380  -->  00:01:09,630
When you're using client side input validation,
30

30

00:01:09,630  -->  00:01:10,920
it is much more dangerous
31

31

00:01:10,920  -->  00:01:13,620
because it's vulnerable to malware interference.
32

32

00:01:13,620  -->  00:01:15,420
If I'm testing something on your computer
33

33

00:01:15,420  -->  00:01:18,000
before you send it to my server, I am now trusting
34

34

00:01:18,000  -->  00:01:20,220
that your computer is doing what I told it to do
35

35

00:01:20,220  -->  00:01:21,450
and that can't always be the case
36

36

00:01:21,450  -->  00:01:23,010
because attackers can modify that
37

37

00:01:23,010  -->  00:01:24,810
and malware can modify that.
38

38

00:01:24,810  -->  00:01:25,837
So you may be wondering,
39

39

00:01:25,837  -->  00:01:27,990
"Why don't we just do server-side for everything?"
40

40

00:01:27,990  -->  00:01:30,450
Well, server-side input validation can be time
41

41

00:01:30,450  -->  00:01:33,150
and resource intensive because every time I have
42

42

00:01:33,150  -->  00:01:35,760
to check something, that's process cycles on the server
43

43

00:01:35,760  -->  00:01:37,800
and while your computer's only serving you,
44

44

00:01:37,800  -->  00:01:40,380
my server is serving hundreds of thousands of people
45

45

00:01:40,380  -->  00:01:42,720
and so that can take up a lot of resources.
46

46

00:01:42,720  -->  00:01:43,950
Now, let me give you a good example of this.
47

47

00:01:43,950  -->  00:01:45,660
Let's say you went to my website and you're trying to buy
48

48

00:01:45,660  -->  00:01:48,390
your exam voucher for your CySA+ exam.
49

49

00:01:48,390  -->  00:01:50,670
You get to the checkout form and it ask for your email
50

50

00:01:50,670  -->  00:01:55,140
and you type in jason@notmydomain, but you didn't put .com.
51

51

00:01:55,140  -->  00:01:57,840
Notice here it says, "This is not a valid email."
52

52

00:01:57,840  -->  00:01:59,700
This isn't being checked by my server,
53

53

00:01:59,700  -->  00:02:01,650
this is being checked by your client.
54

54

00:02:01,650  -->  00:02:03,270
It knows that the format has
55

55

00:02:03,270  -->  00:02:06,450
to be something@something.something, right?
56

56

00:02:06,450  -->  00:02:07,740
It knows that's what an email looks like
57

57

00:02:07,740  -->  00:02:10,200
and since you didn't do that, it's not going to validate it
58

58

00:02:10,200  -->  00:02:11,880
and it won't let you enter this form.
59

59

00:02:11,880  -->  00:02:13,830
Now, if you just entered .com here,
60

60

00:02:13,830  -->  00:02:15,510
even though that's not a valid email,
61

61

00:02:15,510  -->  00:02:18,097
it would still accept it because the client side said,
62

62

00:02:18,097  -->  00:02:18,990
"That's good enough
63

63

00:02:18,990  -->  00:02:21,930
it just need to be something@something.com."
64

64

00:02:21,930  -->  00:02:24,330
Now, input, when you're validating it from the client,
65

65

00:02:24,330  -->  00:02:27,210
it still needs to go undergo a server-side validation
66

66

00:02:27,210  -->  00:02:29,310
after passing the client side validation.
67

67

00:02:29,310  -->  00:02:32,490
For example, a lot of websites will validate on your client
68

68

00:02:32,490  -->  00:02:35,100
that that looks like it's in a valid format of email,
69

69

00:02:35,100  -->  00:02:37,320
then you send it to the server and they're going to check
70

70

00:02:37,320  -->  00:02:39,120
that it's an actually a live email address
71

71

00:02:39,120  -->  00:02:40,920
before they process your order,
72

72

00:02:40,920  -->  00:02:42,690
that's a server-side validation as well.
73

73

00:02:42,690  -->  00:02:44,850
So you can do both and so it doesn't have to be
74

74

00:02:44,850  -->  00:02:47,010
either or you can use both.
75

75

00:02:47,010  -->  00:02:48,990
Now, let's talk about input here for a second.
76

76

00:02:48,990  -->  00:02:50,790
In addition to doing input validation,
77

77

00:02:50,790  -->  00:02:52,260
we also want to do what's called
78

78

00:02:52,260  -->  00:02:54,720
normalization or sanitization.
79

79

00:02:54,720  -->  00:02:55,950
Now, what is this?
80

80

00:02:55,950  -->  00:02:58,410
Well, normalization is when you take a string
81

81

00:02:58,410  -->  00:03:00,270
and it's stripped of all the illegal characters
82

82

00:03:00,270  -->  00:03:01,950
or substrings and it's converted
83

83

00:03:01,950  -->  00:03:03,570
to an accepted character set.
84

84

00:03:03,570  -->  00:03:05,100
For instance, when you go to my website
85

85

00:03:05,100  -->  00:03:06,270
and you enter your name,
86

86

00:03:06,270  -->  00:03:09,120
I expect it to be something that has the alphabet in it.
87

87

00:03:09,120  -->  00:03:10,620
You know, A, B, C, D, E.
88

88

00:03:10,620  -->  00:03:13,260
I don't expect a bunch of numbers or special characters,
89

89

00:03:13,260  -->  00:03:15,120
and so if you put in numbers or special characters,
90

90

00:03:15,120  -->  00:03:17,670
the system should do input validation either reject it
91

91

00:03:17,670  -->  00:03:20,130
or it should normalize it and remove those,
92

92

00:03:20,130  -->  00:03:21,870
that's the idea of normalization.
93

93

00:03:21,870  -->  00:03:23,610
Now, again, I've mentioned in the past
94

94

00:03:23,610  -->  00:03:25,650
the reason why we have to do input validation
95

95

00:03:25,650  -->  00:03:28,500
is because we want to prevent people from doing attacks on us
96

96

00:03:28,500  -->  00:03:29,670
and some of those attacks are things
97

97

00:03:29,670  -->  00:03:31,650
like directory traversals we mentioned.
98

98

00:03:31,650  -->  00:03:33,840
Well, one of the attacks that people can use against us
99

99

00:03:33,840  -->  00:03:36,360
is known as a canonicalization attack.
100

100

00:03:36,360  -->  00:03:38,550
Now, canonicalization is an attack method
101

101

00:03:38,550  -->  00:03:41,100
where input characters are encoded in such a way
102

102

00:03:41,100  -->  00:03:43,830
to evade vulnerable input validation measures.
103

103

00:03:43,830  -->  00:03:46,710
So I'll go back to the example of a directory traversal.
104

104

00:03:46,710  -->  00:03:48,840
I'm going to send something that looks like this,
105

105

00:03:48,840  -->  00:03:53,840
diontraining.com?user=../../../../etc/config.
106

106

00:03:57,570  -->  00:03:59,310
Now, if I don't want to fall victim
107

107

00:03:59,310  -->  00:04:01,530
of an attack like this, what can I do?
108

108

00:04:01,530  -->  00:04:03,907
I can normalize that data, I can sanitize it and say,
109

109

00:04:03,907  -->  00:04:06,210
"Oh, anytime you see ../, just ignore it,
110

110

00:04:06,210  -->  00:04:07,260
we're not going to take it,
111

111

00:04:07,260  -->  00:04:09,960
and we can either reject it or we can just remove that
112

112

00:04:09,960  -->  00:04:12,750
and just pass the etc/config part.
113

113

00:04:12,750  -->  00:04:14,820
Now, if somebody wants to try to send this
114

114

00:04:14,820  -->  00:04:16,680
as their username, we're not going to process it,
115

115

00:04:16,680  -->  00:04:18,600
or if we do, we're not going to fall victim
116

116

00:04:18,600  -->  00:04:21,122
of the attack because we've removed those ../.
117

117

00:04:21,122  -->  00:04:23,460
Now, what happens if they send me this instead?
118

118

00:04:23,460  -->  00:04:28,037
Well, they have diontraining.com?user=%2e%2e%2f,
119

119

00:04:29,430  -->  00:04:32,760
you get the idea /etc/config.
120

120

00:04:32,760  -->  00:04:33,840
What is this?
121

121

00:04:33,840  -->  00:04:35,550
Well, they encoded their input
122

122

00:04:35,550  -->  00:04:38,010
to try to get past my validation system.
123

123

00:04:38,010  -->  00:04:40,320
So I need to make sure that I'm aware of this type of attack
124

124

00:04:40,320  -->  00:04:42,840
because I would need to go and sanitize this input,
125

125

00:04:42,840  -->  00:04:46,050
not just for ../, but every variation of ../
126

126

00:04:46,050  -->  00:04:48,660
that may be used by different encoding mechanisms.
127

127

00:04:48,660  -->  00:04:50,190
So this is the idea of how you can prevent
128

128

00:04:50,190  -->  00:04:51,960
these canonicalization attack.
129

129

00:04:51,960  -->  00:04:54,390
Next, we want to talk about output encoding.
130

130

00:04:54,390  -->  00:04:56,610
Output encoding is any coding method that's used
131

131

00:04:56,610  -->  00:04:59,850
to sanitize the output by converting the untrusted input
132

132

00:04:59,850  -->  00:05:02,340
into a safe form where the input is now displayed
133

133

00:05:02,340  -->  00:05:04,380
as data to the user without executing
134

134

00:05:04,380  -->  00:05:05,820
the code in the browser.
135

135

00:05:05,820  -->  00:05:07,740
So let me give you a good example of this.
136

136

00:05:07,740  -->  00:05:09,450
Let's say you took that input from somebody
137

137

00:05:09,450  -->  00:05:12,810
with all those ../ and then you outputted it back
138

138

00:05:12,810  -->  00:05:15,780
to the user and said, "Error, username incorrect.
139

139

00:05:15,780  -->  00:05:19,493
Username cannot be ../../../."
140

140

00:05:19,493  -->  00:05:20,640
Well, what are you doing there?
141

141

00:05:20,640  -->  00:05:23,310
You're having a ability that somebody can actually put code
142

142

00:05:23,310  -->  00:05:25,770
into your webpage because if I went and put something
143

143

00:05:25,770  -->  00:05:28,410
like parenthesis script as my username
144

144

00:05:28,410  -->  00:05:30,667
and then you aired that out and gave it back to me and said,
145

145

00:05:30,667  -->  00:05:32,820
"Bracket script alert XSS.
146

146

00:05:32,820  -->  00:05:34,890
Bracket script is not a valid username."
147

147

00:05:34,890  -->  00:05:35,910
What did you just do?
148

148

00:05:35,910  -->  00:05:37,590
You put the script into your website
149

149

00:05:37,590  -->  00:05:41,100
and slate it back to me, output encoding prevents that.
150

150

00:05:41,100  -->  00:05:43,290
So for example, instead of taking an ampersand,
151

151

00:05:43,290  -->  00:05:45,117
you would convert that to &amp;amp;.
152

152

00:05:47,070  -->  00:05:48,900
If you take a less than sign,
153

153

00:05:48,900  -->  00:05:52,680
you would make that into &amp;lt;.
154

154

00:05:52,680  -->  00:05:55,320
Why, because the less than symbol is one of the things
155

155

00:05:55,320  -->  00:05:58,230
we used to make the word script insider brackets,
156

156

00:05:58,230  -->  00:06:00,450
less than symbol, script greater than symbol.
157

157

00:06:00,450  -->  00:06:04,347
So if we change that to &amp;lt; script &amp;gt;,
158

158

00:06:06,360  -->  00:06:08,910
that won't execute when you display it back to the user.
159

159

00:06:08,910  -->  00:06:10,860
That's the idea of output encoding.
160

160

00:06:10,860  -->  00:06:12,570
Output encoding is used to mitigate
161

161

00:06:12,570  -->  00:06:15,330
against the code injection and cross it scripting attacks
162

162

00:06:15,330  -->  00:06:17,880
that attempt to use input to run that script,
163

163

00:06:17,880  -->  00:06:19,410
that's what we're trying to prevent here.
164

164

00:06:19,410  -->  00:06:20,760
Now, the third area we want to talk
165

165

00:06:20,760  -->  00:06:22,440
about is parameterized queries,
166

166

00:06:22,440  -->  00:06:24,810
and this is a great technique that is used to defend
167

167

00:06:24,810  -->  00:06:28,350
against SQL injections and insecure object references
168

168

00:06:28,350  -->  00:06:31,680
by incorporating placeholders into an SQL query.
169

169

00:06:31,680  -->  00:06:33,420
Now, what does this look like?
170

170

00:06:33,420  -->  00:06:35,640
Well, when we take these parameterized queries,
171

171

00:06:35,640  -->  00:06:38,220
we're really doing a form of output encoding.
172

172

00:06:38,220  -->  00:06:40,170
So let me show you a small program that I wrote,
173

173

00:06:40,170  -->  00:06:43,260
it's just five lines long and this is a Java program.
174

174

00:06:43,260  -->  00:06:44,490
Now, I don't expect you to be able
175

175

00:06:44,490  -->  00:06:45,690
to write this code yourself,
176

176

00:06:45,690  -->  00:06:47,520
but you should be able to read it
177

177

00:06:47,520  -->  00:06:49,800
because Java is considered a high level language
178

178

00:06:49,800  -->  00:06:52,050
and it reads fairly much like English.
179

179

00:06:52,050  -->  00:06:54,060
So let's take this one line at a time.
180

180

00:06:54,060  -->  00:06:59,060
Now, string custname = request.getParameter("customerName")
181

181

00:07:00,180  -->  00:07:03,870
String query = "Select account_balance FROM user_data
182

182

00:07:03,870  -->  00:07:06,362
WHERE user_name = ?"
183

183

00:07:06,362  -->  00:07:11,362
PreparedStatement pstmt = connection.prepareStatement(query)
184

184

00:07:11,480  -->  00:07:15,293
pstmt.setString( 1, custname)
185

185

00:07:15,293  -->  00:07:18,093
ResultSet results = pstmt.executeQuery( ),
186

186

00:07:20,430  -->  00:07:21,420
what is this saying?
187

187

00:07:21,420  -->  00:07:25,080
Well, in the first line, this takes the string customer name
188

188

00:07:25,080  -->  00:07:27,570
and request you to get the parameter customer name,
189

189

00:07:27,570  -->  00:07:29,580
so we're getting input from our user.
190

190

00:07:29,580  -->  00:07:32,100
The second line, this is the query we're defining,
191

191

00:07:32,100  -->  00:07:34,770
we're defining that the query will always be in this format.
192

192

00:07:34,770  -->  00:07:37,620
Select account balance from user data
193

193

00:07:37,620  -->  00:07:40,260
where username equals question mark.
194

194

00:07:40,260  -->  00:07:42,480
The question mark is essentially what we're going to fill in,
195

195

00:07:42,480  -->  00:07:44,670
then we're going to use this prepared statement call,
196

196

00:07:44,670  -->  00:07:45,720
which is going to make a connection
197

197

00:07:45,720  -->  00:07:48,120
to the database using the query,
198

198

00:07:48,120  -->  00:07:50,910
then we're going to make that string get set
199

199

00:07:50,910  -->  00:07:53,610
inside the query using the first position,
200

200

00:07:53,610  -->  00:07:56,040
that first question mark we found, the only question mark,
201

201

00:07:56,040  -->  00:07:58,770
as customer name, and then we're going to get the results
202

202

00:07:58,770  -->  00:08:00,960
from executing that query, that's all it is saying.
203

203

00:08:00,960  -->  00:08:02,520
So when we're using a parameterized query,
204

204

00:08:02,520  -->  00:08:04,350
we're only going to use this format
205

205

00:08:04,350  -->  00:08:05,940
when sending it to the database.
206

206

00:08:05,940  -->  00:08:08,040
This way, we have different parameterized queries
207

207

00:08:08,040  -->  00:08:10,740
for different functions like writing to the database,
208

208

00:08:10,740  -->  00:08:13,140
reading from the database, updating from the database
209

209

00:08:13,140  -->  00:08:15,630
for certain fields, and we would use those queries
210

210

00:08:15,630  -->  00:08:17,850
that have already been defined by the programmers
211

211

00:08:17,850  -->  00:08:18,870
instead of trying to create them
212

212

00:08:18,870  -->  00:08:21,270
on the fly using customer data.
213

213

00:08:21,270  -->  00:08:22,920
That's what we're doing here and this is the idea
214

214

00:08:22,920  -->  00:08:24,150
of a prepared statement.
215

215

00:08:24,150  -->  00:08:27,150
Now, this is not a fully functional program.
216

216

00:08:27,150  -->  00:08:30,270
What am I missing here that can really cause me problems?
217

217

00:08:30,270  -->  00:08:32,400
We talked about it at the beginning of this lesson.
218

218

00:08:32,400  -->  00:08:34,650
That's right, input validation.
219

219

00:08:34,650  -->  00:08:37,020
Nothing here is validating that input.
220

220

00:08:37,020  -->  00:08:39,720
So when I'm getting the input from the customer,
221

221

00:08:39,720  -->  00:08:41,670
I didn't go through input validation.
222

222

00:08:41,670  -->  00:08:44,310
So when I get that input, I should run it through validation
223

223

00:08:44,310  -->  00:08:46,260
before I put it into my query
224

224

00:08:46,260  -->  00:08:47,640
and into my prepared statement,
225

225

00:08:47,640  -->  00:08:49,380
but this was an idea of showing you
226

226

00:08:49,380  -->  00:08:51,270
what a parameterized query looks like
227

227

00:08:51,270  -->  00:08:53,310
with these prepared statements, and that's what I wanted
228

228

00:08:53,310  -->  00:08:55,500
to focus on in this particular code snippet.
229

229

00:08:55,500  -->  00:08:58,680
Now, for the exam, you do need to be able to identify
230

230

00:08:58,680  -->  00:09:01,860
input validation, output encoding, and parameterized queries
231

231

00:09:01,860  -->  00:09:03,330
in a given scenario.
232

232

00:09:03,330  -->  00:09:06,030
Remember, anytime you take input from a user,
233

233

00:09:06,030  -->  00:09:07,860
you want to do input validation.
234

234

00:09:07,860  -->  00:09:10,410
Anytime you're outputting data that came from a user back
235

235

00:09:10,410  -->  00:09:13,350
to the screen, you want to use output encoding.
236

236

00:09:13,350  -->  00:09:15,570
Anytime you want to connect to an SQL database,
237

237

00:09:15,570  -->  00:09:17,730
you should really be using parametrized queries
238

238

00:09:17,730  -->  00:09:19,590
because this is a best practice.
239

239

00:09:19,590  -->  00:09:21,270
It'll make sure you're taking the minimum amount
240

240

00:09:21,270  -->  00:09:22,410
of information from a user
241

241

00:09:22,410  -->  00:09:24,420
and putting it into specific fields only
242

242

00:09:24,420  -->  00:09:27,513
inside that database by using those parameters queries.
