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