1
00:00:01,040 --> 00:00:02,370
The next set of attacks we will take a

2
00:00:02,370 --> 00:00:04,990
look at are Deserialization attacks, and

3
00:00:04,990 --> 00:00:07,210
this family of attacks come in at number 8

4
00:00:07,210 --> 00:00:09,810
on the OWASP Top 10 List. What these

5
00:00:09,810 --> 00:00:11,750
attacks are trying to do is to inject

6
00:00:11,750 --> 00:00:14,000
malicious code provided by the attacker

7
00:00:14,000 --> 00:00:16,640
into your application by misappropriating

8
00:00:16,640 --> 00:00:18,580
and abusing some of the features of the

9
00:00:18,580 --> 00:00:21,460
deserialization process. These types of

10
00:00:21,460 --> 00:00:23,300
attacks can be mounted against any type of

11
00:00:23,300 --> 00:00:25,970
data you're deserializing, whether JSON,

12
00:00:25,970 --> 00:00:28,770
XML, or binary data. But we'll take a look

13
00:00:28,770 --> 00:00:31,140
at deserializing JSON data first with the

14
00:00:31,140 --> 00:00:35,130
popular Newtonsoft Json.NET library. There

15
00:00:35,130 --> 00:00:36,950
are two conditions that have to exist for

16
00:00:36,950 --> 00:00:39,460
this attack to succeed. First, in one of

17
00:00:39,460 --> 00:00:41,070
your view models, you need to have a

18
00:00:41,070 --> 00:00:43,660
property that is of the type dynamic, as

19
00:00:43,660 --> 00:00:46,560
you see here. Sometimes developers do this

20
00:00:46,560 --> 00:00:48,600
to allow a client to pass any arbitrary

21
00:00:48,600 --> 00:00:50,750
data to the controller, and then the

22
00:00:50,750 --> 00:00:52,830
controller will either save this data or

23
00:00:52,830 --> 00:00:55,910
decode it into an object. The second

24
00:00:55,910 --> 00:00:57,780
condition that has to exist is that the

25
00:00:57,780 --> 00:01:00,240
TypeNameHandling property of the JSON

26
00:01:00,240 --> 00:01:02,450
SerializerSettings needs to be set to

27
00:01:02,450 --> 00:01:04,440
something other than its default value,

28
00:01:04,440 --> 00:01:07,270
which is none. What this property does is

29
00:01:07,270 --> 00:01:09,980
tell the Json.NET serializer to write type

30
00:01:09,980 --> 00:01:11,520
information with the data that it

31
00:01:11,520 --> 00:01:14,700
serializes. But more importantly for us,

32
00:01:14,700 --> 00:01:16,920
it allows incoming JSON to specify the

33
00:01:16,920 --> 00:01:19,380
type that it should be deserialized to.

34
00:01:19,380 --> 00:01:21,540
And this is a feature that can be abused

35
00:01:21,540 --> 00:01:24,820
and result in a vulnerability. In fact, if

36
00:01:24,820 --> 00:01:27,110
you look at the Json.NET documentation

37
00:01:27,110 --> 00:01:29,950
page for the TypeNameHandling enumeration,

38
00:01:29,950 --> 00:01:32,440
it warns you of just such a case,

39
00:01:32,440 --> 00:01:34,130
indicating that if you set this value to

40
00:01:34,130 --> 00:01:36,120
anything other than the default value of

41
00:01:36,120 --> 00:01:38,370
none, then you also need to use a

42
00:01:38,370 --> 00:01:41,140
SerializationBinder class to specify what

43
00:01:41,140 --> 00:01:44,110
types are allowed to be deserialized. If

44
00:01:44,110 --> 00:01:45,930
you don't do this, then the attacker can

45
00:01:45,930 --> 00:01:48,340
specify any arbitrary type. And the

46
00:01:48,340 --> 00:01:51,070
problem is that in .NET, there are types

47
00:01:51,070 --> 00:01:52,770
that will run code automatically when

48
00:01:52,770 --> 00:01:54,770
they're deserialized or at some other

49
00:01:54,770 --> 00:01:57,030
point in their lifetime. For example,

50
00:01:57,030 --> 00:01:59,220
running a constructor or a finalizer for a

51
00:01:59,220 --> 00:02:02,170
class. Most classes are safe as all they

52
00:02:02,170 --> 00:02:04,370
do in their constructor is set some

53
00:02:04,370 --> 00:02:05,810
properties. But there are a few classes

54
00:02:05,810 --> 00:02:07,490
that can be manipulated to do something

55
00:02:07,490 --> 00:02:09,280
malicious. So let's take a look at an

56
00:02:09,280 --> 00:02:12,345
example of one of these. On your screen,

57
00:02:12,345 --> 00:02:14,810
you see a view model class, and you can

58
00:02:14,810 --> 00:02:16,730
see that for this last property I have

59
00:02:16,730 --> 00:02:19,220
specified the type to be dynamic, so I can

60
00:02:19,220 --> 00:02:21,090
pass in whatever data I want, and then

61
00:02:21,090 --> 00:02:23,360
it's up to my API to inspect the data that

62
00:02:23,360 --> 00:02:25,120
comes in and figure out the right thing to

63
00:02:25,120 --> 00:02:27,580
do with it. Switching over to the sample

64
00:02:27,580 --> 00:02:29,400
JSON though, you will start to see how

65
00:02:29,400 --> 00:02:32,030
this design can be abused. You will notice

66
00:02:32,030 --> 00:02:34,250
that for the deliveryOptions property, I

67
00:02:34,250 --> 00:02:36,260
have specified the type. In this case, the

68
00:02:36,260 --> 00:02:39,200
FileInfo class. The second line is the

69
00:02:39,200 --> 00:02:40,920
parameter passed to the constructor, so

70
00:02:40,920 --> 00:02:43,430
the name of a file. And the third line is

71
00:02:43,430 --> 00:02:46,190
a property to be set on this type. When

72
00:02:46,190 --> 00:02:48,260
this gets deserialized, what this is going

73
00:02:48,260 --> 00:02:50,630
to do is to create a new FileInfo object

74
00:02:50,630 --> 00:02:53,040
for this file, and then set that file to

75
00:02:53,040 --> 00:02:56,270
be ReadOnly. As you might imagine, this

76
00:02:56,270 --> 00:02:58,780
can be a serious problem. If an attacker

77
00:02:58,780 --> 00:03:00,370
is able to guess the name of an important

78
00:03:00,370 --> 00:03:02,730
file and set it to ReadOnly, that could

79
00:03:02,730 --> 00:03:04,830
cause a process on the server to start

80
00:03:04,830 --> 00:03:06,980
throwing errors or to crash when it next

81
00:03:06,980 --> 00:03:09,750
tries to write to that file. So let's

82
00:03:09,750 --> 00:03:12,610
prove that this actually works. I have

83
00:03:12,610 --> 00:03:14,070
this test file that I'm going to use to

84
00:03:14,070 --> 00:03:16,020
demonstrate the attack, and if you look at

85
00:03:16,020 --> 00:03:18,230
the properties, you can see the Read‑only

86
00:03:18,230 --> 00:03:20,870
box is unchecked. So currently I can read

87
00:03:20,870 --> 00:03:23,920
or write to this file. So I'll get the

88
00:03:23,920 --> 00:03:27,750
application running here. And at this

89
00:03:27,750 --> 00:03:29,820
point, you could use Postman to post that

90
00:03:29,820 --> 00:03:32,220
JSON to the endpoint, but I actually have

91
00:03:32,220 --> 00:03:33,980
a test page here to make this a little bit

92
00:03:33,980 --> 00:03:36,050
easier to demonstrate. And if you look at

93
00:03:36,050 --> 00:03:37,950
this page, all that's happening here is

94
00:03:37,950 --> 00:03:40,110
the page is using some jQuery to post this

95
00:03:40,110 --> 00:03:42,970
JSON back to the endpoint. So I'll do

96
00:03:42,970 --> 00:03:45,630
that, and you can see in the response now

97
00:03:45,630 --> 00:03:46,830
it's telling us that that file is

98
00:03:46,830 --> 00:03:49,800
ReadOnly. So let's verify that statement

99
00:03:49,800 --> 00:03:52,810
by going back to Windows Explorer. And

100
00:03:52,810 --> 00:03:54,640
indeed, you'll see that that file is

101
00:03:54,640 --> 00:03:58,540
ReadOnly, and that is obviously a problem.

102
00:03:58,540 --> 00:04:00,400
This is a very simple yet very serious

103
00:04:00,400 --> 00:04:02,300
example, but it demonstrates a larger

104
00:04:02,300 --> 00:04:05,140
issue. If an attacker can find types like

105
00:04:05,140 --> 00:04:07,760
this that run code automatically, either

106
00:04:07,760 --> 00:04:10,340
in .NET itself, in popular libraries, or

107
00:04:10,340 --> 00:04:12,620
in your code, they can use it to attack

108
00:04:12,620 --> 00:04:14,510
your application if those conditions we

109
00:04:14,510 --> 00:04:16,880
laid out in the beginning are true. That

110
00:04:16,880 --> 00:04:19,210
is, somewhere you accept a dynamic type as

111
00:04:19,210 --> 00:04:21,550
input and TypeNameHandling is set to

112
00:04:21,550 --> 00:04:24,090
something other than none. So that is what

113
00:04:24,090 --> 00:04:26,570
attackers do, they scan the code bases of

114
00:04:26,570 --> 00:04:28,870
.NET in popular libraries to see if there

115
00:04:28,870 --> 00:04:30,665
are any classes that will potentially run

116
00:04:30,665 --> 00:04:32,470
damaging code as part of the constructor

117
00:04:32,470 --> 00:04:34,660
or another automatically run method, and

118
00:04:34,660 --> 00:04:36,260
they see how they can take advantage of

119
00:04:36,260 --> 00:04:39,430
it. The name for these is a gadget, and

120
00:04:39,430 --> 00:04:42,060
this post by Alphabot Security lists four

121
00:04:42,060 --> 00:04:44,050
such gadgets that can be used to execute

122
00:04:44,050 --> 00:04:47,030
malicious code. Now these might be classes

123
00:04:47,030 --> 00:04:49,530
that are infrequently used in a web or API

124
00:04:49,530 --> 00:04:51,640
type application, but they give you an

125
00:04:51,640 --> 00:04:54,640
idea of how creative these threats can be.

126
00:04:54,640 --> 00:04:57,660
So what can we do about this? First is

127
00:04:57,660 --> 00:04:58,960
that you always want to leave the

128
00:04:58,960 --> 00:05:01,500
TypeNameHandling property set to none, its

129
00:05:01,500 --> 00:05:04,170
default. There's no reason to let a client

130
00:05:04,170 --> 00:05:06,310
define what type should be deserialized,

131
00:05:06,310 --> 00:05:08,260
so leaving this value to none protects

132
00:05:08,260 --> 00:05:11,370
you. Second is to stay away from allowing

133
00:05:11,370 --> 00:05:13,170
dynamic types to be posted to your

134
00:05:13,170 --> 00:05:16,070
application or API. It is much better to

135
00:05:16,070 --> 00:05:18,100
have a defined type because then you know

136
00:05:18,100 --> 00:05:19,490
exactly what you're getting from the

137
00:05:19,490 --> 00:05:22,500
client and any extraneous or over posted

138
00:05:22,500 --> 00:05:25,650
data just gets thrown away. If for some

139
00:05:25,650 --> 00:05:27,790
reason you have to accept dynamic types,

140
00:05:27,790 --> 00:05:30,440
and you have to turn TypeNameHandling on,

141
00:05:30,440 --> 00:05:32,220
then you want to implement a custom

142
00:05:32,220 --> 00:05:35,030
SerializationBinder class that limits what

143
00:05:35,030 --> 00:05:36,600
types can be created as part of the

144
00:05:36,600 --> 00:05:39,080
serialization process. And you can see an

145
00:05:39,080 --> 00:05:40,750
example of how to do this in the

146
00:05:40,750 --> 00:05:43,880
Newtonsoft documentation. By limiting the

147
00:05:43,880 --> 00:05:45,850
types that can be deserialized to known

148
00:05:45,850 --> 00:05:47,960
safe types, you've once again protected

149
00:05:47,960 --> 00:05:49,960
your application against an attack like

150
00:05:49,960 --> 00:05:53,660
this using JSON. It is not just JSON data

151
00:05:53,660 --> 00:05:55,640
that can be attacked via deserialization,

152
00:05:55,640 --> 00:05:57,970
but any type of serialized data, including

153
00:05:57,970 --> 00:06:00,880
binary and XML serialized data. If you

154
00:06:00,880 --> 00:06:02,640
want to dive deep into how these attacks

155
00:06:02,640 --> 00:06:04,750
work, I'll direct you to this paper on the

156
00:06:04,750 --> 00:06:07,720
Black Hat website. All these attacks work

157
00:06:07,720 --> 00:06:09,620
the same way though, they try to

158
00:06:09,620 --> 00:06:11,630
deserialize an arbitrary class that will

159
00:06:11,630 --> 00:06:13,820
automatically execute some code, whether

160
00:06:13,820 --> 00:06:15,860
in the constructor, an onDeserializing

161
00:06:15,860 --> 00:06:17,750
method, or in the finalization process.

162
00:06:17,750 --> 00:06:21,040
.NET's binary serializer is particularly

163
00:06:21,040 --> 00:06:23,650
vulnerable because by default it does not

164
00:06:23,650 --> 00:06:25,740
do any type checking on the incoming class

165
00:06:25,740 --> 00:06:28,530
before it deserializes that class. So any

166
00:06:28,530 --> 00:06:29,910
class marked with a serializable

167
00:06:29,910 --> 00:06:32,940
attribute, it will happily be serialized.

168
00:06:32,940 --> 00:06:34,410
The solution to this problem is to create

169
00:06:34,410 --> 00:06:36,760
a custom SerializationBinder class that

170
00:06:36,760 --> 00:06:38,440
specifies the classes that are allowed to

171
00:06:38,440 --> 00:06:40,780
be instantiated. And then you attach this

172
00:06:40,780 --> 00:06:43,530
custom binder to the binaryFormatter class

173
00:06:43,530 --> 00:06:46,010
that is doing the deserialization. The

174
00:06:46,010 --> 00:06:47,470
theme here in preventing these types of

175
00:06:47,470 --> 00:06:49,300
attacks is to restrict the classes that

176
00:06:49,300 --> 00:06:52,740
can be deserialized to known safe types.

177
00:06:52,740 --> 00:06:53,811
If you know the classes that you are

178
00:06:53,811 --> 00:06:56,000
instantiating through the deserialization

179
00:06:56,000 --> 00:06:58,230
process, and make sure those classes are

180
00:06:58,230 --> 00:07:00,940
simple DTOs, or data transfer objects,

181
00:07:00,940 --> 00:07:02,690
solely designed to hold the deserialized

182
00:07:02,690 --> 00:07:04,790
data and get it into your system, then

183
00:07:04,790 --> 00:07:06,710
your application will not be vulnerable to

184
00:07:06,710 --> 00:07:12,000
these attacks. Let's go ahead and wrap up the course next.

