bundled pjproject: Fix DNS write to freed memory.
[asterisk/asterisk.git] / README-SERIOUSLY.bestpractices.txt
1 ==================
2 | Best Practices |
3 ==================
4
5 The purpose of this document is to define best practices when working with
6 Asterisk in order to minimize possible security breaches and to provide tried
7 examples in field deployments. This is a living document and is subject to
8 change over time as best practices are defined.
9
10 --------
11 Sections
12 --------
13
14 * Filtering Data:
15         How to protect yourself from redial attacks
16
17 * Proper Device Naming:
18         Why to not use numbered extensions for devices
19
20 * Secure Passwords:
21         Secure passwords limit your risk to brute force attacks
22
23 * Reducing Pattern Match Typos:
24         Using the 'same' prefix, or using Goto()
25
26 * Manager Class Authorizations:
27         Recognizing potential issues with certain classes of authorization
28
29 * Avoid Privilege Escalations:
30         Disable the ability to execute functions that may escalate privileges
31
32 ----------------
33 Additional Links
34 ----------------
35
36 Additional links that contain useful information about best practices or
37 security are listed below.
38
39 * Seven Steps to Better SIP Security:
40         http://blogs.digium.com/2009/03/28/sip-security/
41
42 * Asterisk VoIP Security (webinar):
43         http://www.asterisk.org/security/webinar/
44
45
46 ==============
47 Filtering Data
48 ==============
49
50 In the Asterisk dialplan, several channel variables contain data potentially
51 supplied by outside sources. This could lead to a potential security concern
52 where those outside sources may send cleverly crafted strings of data which
53 could be utilized, e.g. to place calls to unexpected locations.
54
55 An example of this can be found in the use of pattern matching and the ${EXTEN}
56 channel variable. Note that ${EXTEN} is not the only system created channel
57 variable, so it is important to be aware of where the data you're using is
58 coming from.
59
60 For example, this common dialplan takes 2 or more characters of data, starting
61 with a number 0-9, and then accepts any additional information supplied by the
62 request.
63
64 [NOTE: We use SIP in this example, but is not limited to SIP only; protocols
65        such as Jabber/XMPP or IAX2 are also susceptible to the same sort of
66        injection problem.]
67
68
69 [incoming]
70 exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN})
71 exten => _X.,n,Dial(SIP/${EXTEN})
72 exten => _X.,n,Hangup()
73
74 This dialplan may be utilized to accept calls to extensions, which then dial a
75 numbered device name configured in one of the channel configuration files (such
76 as sip.conf, iax.conf, etc...) (see the section Proper Device Naming for more
77 information on why this approach is flawed).
78
79 The example we've given above looks harmless enough until you take into
80 consideration that several channel technologies accept characters that could
81 be utilized in a clever attack. For example, instead of just sending a request
82 to dial extension 500 (which in our example above would create the string
83 SIP/500 and is then used by the Dial() application to place a call), someone
84 could potentially send a string like "500&SIP/itsp/14165551212".
85
86 The string "500&SIP/itsp/14165551212" would then be contained within the
87 ${EXTEN} channel variable, which is then utilized by the Dial() application in
88 our example, thereby giving you the dialplan line of:
89
90 exten => _X.,n,Dial(SIP/500&SIP/itsp/14165551212)
91
92 Our example above has now provided someone with a method to place calls out of
93 your ITSP in a place where you didn't expect to allow it. There are a couple of
94 ways in which you can mitigate this impact: stricter pattern matching, or using
95 the FILTER() dialplan function.
96
97 Strict Pattern Matching
98 -----------------------
99
100 The simple way to mitigate this problem is with a strict pattern match that does
101 not utilize the period (.) or bang (!) characters to match on one-or-more
102 characters or zero-or-more characters (respectively). To fine tune our example
103 to only accept three digit extensions, we could change our pattern match to
104 be:
105
106 exten => _XXX,n,Dial(SIP/${EXTEN})
107
108 In this way, we have minimized our impact because we're not allowing anything
109 other than the numbers zero through nine. But in some cases we really do need to
110 handle variable pattern matches, such as when dialing international numbers
111 or when we want to handle something like a SIP URI. In this case, we'll need to
112 utilize the FILTER() dialplan function.
113
114 Using FILTER()
115 --------------
116
117 The FILTER() dialplan function is used to filter strings by only allowing
118 characters that you have specified. This is a perfect candidate for controlling
119 which characters you want to pass to the Dial() application, or any other
120 application which will contain dynamic information passed to Asterisk from an
121 external source. Lets take a look at how we can use FILTER() to control what
122 data we allow.
123
124 Using our previous example to accept any string length of 2 or more characters,
125 starting with a number of zero through nine, we can use FILTER() to limit what
126 we will accept to just numbers. Our example would then change to something like:
127
128 [incoming]
129 exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN})
130 exten => _X.,n,Dial(SIP/${FILTER(0-9,${EXTEN})})
131 exten => _X.,n,Hangup()
132
133 Note how we've wrapped the ${EXTEN} channel variable with the FILTER() function
134 which will then only pass back characters that fit into the numerical range that
135 we've defined.
136
137 Alternatively, if we didn't want to utilize the FILTER() function within the
138 Dial() application directly, we could save the value to a channel variable,
139 which has a side effect of being usable in other locations of your dialplan if
140 necessary, and to handle error checking in a separate location.
141
142 [incoming]
143 exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN})
144 exten => _X.,n,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN})})
145 exten => _X.,n,Dial(SIP/${SAFE_EXTEN})
146 exten => _X.,n,Hangup()
147
148 Now we can use the ${SAFE_EXTEN} channel variable anywhere throughout the rest
149 of our dialplan, knowing we've already filtered it. We could also perform an
150 error check to verify that what we've received in ${EXTEN} also matches the data
151 passed back by FILTER(), and to fail the call if things do not match.
152
153 [incoming]
154 exten => _X.,1,Verbose(2,Incoming call to extension ${EXTEN})
155 exten => _X.,n,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN})})
156 exten => _X.,n,GotoIf($[${EXTEN} != ${SAFE_EXTEN}]?error,1)
157 exten => _X.,n,Dial(SIP/${SAFE_EXTEN})
158 exten => _X.,n,Hangup()
159
160 exten => error,1,Verbose(2,Values of EXTEN and SAFE_EXTEN did not match.)
161 exten => error,n,Verbose(2,EXTEN: "${EXTEN}" -- SAFE_EXTEN: "${SAFE_EXTEN}")
162 exten => error,n,Playback(silence/1&invalid)
163 exten => error,n,Hangup()
164
165 Another example would be using FILTER() to control the characters we accept when
166 we're expecting to get a SIP URI for dialing.
167
168 [incoming]
169 exten => _[0-9a-zA-Z].,1,Verbose(2,Incoming call to extension ${EXTEN})
170 exten => _[0-9a-zA-Z].,n,Dial(SIP/${FILTER(.@0-9a-zA-Z,${EXTEN})
171 exten => _[0-9a-zA-Z].,n,Hangup()
172
173 Of course the FILTER() function doesn't check the formatting of the incoming
174 request. There is also the REGEX() dialplan function which can be used to
175 determine if the string passed to it matches the regular expression you've
176 created, and to take proper action on whether it matches or not. The creation of
177 regular expressions is left as an exercise for the reader.
178
179 More information about the FILTER() and REGEX() dialplan functions can be found
180 by typing "core show function FILTER" and "core show function REGEX" from your
181 Asterisk console.
182
183
184 ====================
185 Proper Device Naming
186 ====================
187
188 In Asterisk, the concept of an extension number being tied to a specific device
189 does not exist. Asterisk is aware of devices it can call or receive calls from,
190 and how you define in your dialplan how to reach those devices is up to you.
191
192 Because it has become common practice to think of a specific device as having an
193 extension number associated with it, it only becomes natural to think about
194 naming your devices the same as the extension number you're providing it. But
195 by doing this, you're limiting the powerful concept of separating user from
196 extensions, and extensions from devices.
197
198 It can also be a security hazard to name your devices with a number, as this can
199 open you up to brute force attacks. Many of the current exploits deal with
200 device configurations which utilize a number, and even worse, a password that
201 matches the devices name. For example, take a look at this poorly created device
202 in sip.conf:
203
204 [1000]
205 type=friend
206 context=international_dialing
207 secret=1000
208
209 As implied by the context, we've permitted a device named 1000 with a password
210 of 1000 to place calls internationally. If your PBX system is accessible via
211 the internet, then your system will be vulnerable to expensive international
212 calls. Even if your system is not accessible via the internet, people within
213 your organization could get access to dialing rules you'd prefer to reserve only
214 for certain people.
215
216 A more secure example for the device would be to use something like the MAC
217 address of the device, along with a strong password (see the section Secure
218 Passwords). The following example would be more secure:
219
220 [0004f2040001]
221 type=friend
222 context=international_dialing
223 secret=aE3%B8*$jk^G
224
225 Then in your dialplan, you would reference the device via the MAC address of the
226 device (or if using the softphone, a MAC address of a network interface on the
227 computer).
228
229 Also note that you should NOT use this password, as it will likely be one of the
230 first ones added to the dictionary for brute force attacks.
231
232
233 ================
234 Secure Passwords
235 ================
236
237 Secure passwords are necessary in many (if not all) environments, and Asterisk
238 is certainly no exception, especially when it comes to expensive long distance
239 calls that could potentially cost your company hundreds or thousands of dollars
240 on an expensive monthly phone bill, with little to no recourse to fight the
241 charges.
242
243 Whenever you are positioned to add a password to your system, whether that is
244 for a device configuration, a database connection, or any other secure
245 connection, be sure to use a secure password. A good example of a secure
246 password would be something like:
247
248 aE3%B8*$jk^G
249
250 Our password also contains 12 characters with a mixture of upper and
251 lower case characters, numbers, and symbols. Because these passwords are likely
252 to only be entered once, or loaded via a configuration file, there is
253 no need to create simple passwords, even in testing. Some of the holes found in
254 production systems used for exploitations involve finding the one test extension
255 that contains a weak password that was forgotten prior to putting a system into
256 production.
257
258 Using a web search you can find several online password generators such as
259 http://www.strongpasswordgenerator.com or there are several scripts that can be
260 used to generate a strong password.
261
262
263 ============================
264 Reducing Pattern Match Typos
265 ============================
266
267 As of Asterisk 1.6.2, a new method for reducing the number of complex pattern
268 matches you need to enter, which can reduce typos in your dialplan, has been
269 implemented. Traditionally, a dialplan with a complex pattern match would look
270 something like:
271
272 exten => _[3-5]XXX,1,Verbose(Incoming call to ${EXTEN})
273 exten => _[3-5]XXX,n,Set(DEVICE=${DB(device/mac_address/${EXTEN})})
274 exten => _[3-5]XXX,n,Set(TECHNOLOGY=${DB(device/technology/${EXTEN})})
275 exten => _[3-5]XXX,n,GotoIf($[${ISNULL(${TECHNOLOGY})} | ${ISNULL(${DEVICE})}]?error,1)
276 exten => _[3-5]XXX,n,Dial(${TECHNOLOGY}/${DEVICE},${GLOBAL(TIMEOUT)})
277 exten => _[3-5]XXX,n,Set(vmFlag=${IF($[${DIALSTATUS} = BUSY]?b:u)})
278 exten => _[3-5]XXX,n,Voicemail(${EXTEN}@${GLOBAL(VOICEMAIL_CONTEXT)},${vmFlag})
279 exten => _[3-5]XXX,n,Hangup()
280
281 exten => error,1,Verbose(2,Unable to lookup technology or device for extension)
282 exten => error,n,Playback(silence/1&num-not-in-db)
283 exten => error,n,Hangup()
284
285 Of course there exists the possibility for a typo when retyping the pattern
286 match _[3-5]XXX which will match on extensions 3000 through 5999. We can
287 minimize this error by utilizing the same => prefix on all lines beyond the
288 first one. Our same dialplan with using same => would look like the following:
289
290 exten => _[3-5]XXX,1,Verbose(Incoming call to ${EXTEN})
291 same => n,Set(DEVICE=${DB(device/mac_address/${EXTEN})})
292 same => n,Set(TECHNOLOGY=${DB(device/technology/${EXTEN})})
293 same => n,GotoIf($[${ISNULL(${TECHNOLOGY})} | ${ISNULL(${DEVICE})}]?error,1)
294 same => n,Dial(${TECHNOLOGY}/${DEVICE},${GLOBAL(TIMEOUT)})
295 same => n,Set(vmFlag=${IF($[${DIALSTATUS} = BUSY]?b:u)})
296 same => n,Voicemail(${EXTEN}@${GLOBAL(VOICEMAIL_CONTEXT)},${vmFlag})
297 same => n,Hangup()
298
299 exten => error,1,Verbose(2,Unable to lookup technology or device for extension)
300 same => n,Playback(silence/1&num-not-in-db)
301 same => n,Hangup()
302
303
304 ============================
305 Manager Class Authorizations
306 ============================
307
308 Manager accounts have associated class authorizations that define what actions
309 and events that account can execute/receive.  In order to run Asterisk commands
310 or dialplan applications that affect the system Asterisk executes on, the
311 "system" class authorization should be set on the account.
312
313 However, Manager commands that originate new calls into the Asterisk dialplan
314 have the potential to alter or affect the system as well, even though the
315 class authorization for origination commands is "originate".  Take, for example,
316 the Originate manager command:
317
318 Action: Originate
319 Channel: SIP/foo
320 Exten: s
321 Context: default
322 Priority: 1
323 Application: System
324 Data: echo hello world!
325
326 This manager command will attempt to execute an Asterisk application, System,
327 which is normally associated with the "system" class authorication.  While some
328 checks have been put into Asterisk to take this into account, certain dialplan
329 configurations and/or clever manipulation of the Originate manager action can
330 circumvent these checks.  For example, take the following dialplan:
331
332 exten => s,1,Verbose(Incoming call)
333 same => n,MixMonitor(foo.wav,,${EXEC_COMMAND})
334 same => n,Dial(SIP/bar)
335 same => n,Hangup()
336
337 Whatever has been defined in the variable EXEC_COMMAND will be executed after
338 MixMonitor has finished recording the call.  The dialplan writer may have
339 intended that this variable to be set by some other location in the dialplan;
340 however, the Manager action Originate allows for channel variables to be set by
341 the account initiating the new call.  This could allow the Originate action to
342 execute some command on the system by setting the EXEC_COMMAND dialplan variable
343 in the Variable: header.
344
345 In general, you should treat the Manager class authorization "originate" the
346 same as the class authorization "system".  Good system configuration, such as
347 not running Asterisk as root, can prevent serious problems from arising when
348 allowing external connections to originate calls into Asterisk.
349
350 ===========================
351 Avoid Privilege Escalations
352 ===========================
353
354 External control protocols, such as Manager, often have the ability to get and
355 set channel variables; which allows the execution of dialplan functions.
356
357 Dialplan functions within Asterisk are incredibly powerful, which is wonderful
358 for building applications using Asterisk. But during the read or write
359 execution, certain diaplan functions do much more. For example, reading the
360 SHELL() function can execute arbitrary commands on the system Asterisk is
361 running on. Writing to the FILE() function can change any file that Asterisk has
362 write access to.
363
364 When these functions are executed from an external protocol, that execution
365 could result in a privilege escalation. Asterisk can inhibit the execution of
366 these functions, if live_dangerously in the [options] section of asterisk.conf
367 is set to no.
368
369 In Asterisk 12 and later, live_dangerously defaults to no.