{"id":13399191,"url":"https://github.com/asterisk/asterisk","last_synced_at":"2026-04-09T18:18:48.608Z","repository":{"id":30233389,"uuid":"33784533","full_name":"asterisk/asterisk","owner":"asterisk","description":"The official Asterisk Project repository.","archived":false,"fork":false,"pushed_at":"2026-01-22T22:28:53.000Z","size":379230,"stargazers_count":3017,"open_issues_count":190,"forks_count":1178,"subscribers_count":127,"default_branch":"master","last_synced_at":"2026-01-23T10:07:24.855Z","etag":null,"topics":["asterisk","c","pbx","sip","voip"],"latest_commit_sha":null,"homepage":"https://www.asterisk.org","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asterisk.png","metadata":{"files":{"readme":"README-SERIOUSLY.bestpractices.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2015-04-11T17:07:55.000Z","updated_at":"2026-01-22T21:00:45.000Z","dependencies_parsed_at":"2023-01-14T16:45:14.874Z","dependency_job_id":"282de0d9-8e20-43ba-ae9d-24a1995848b5","html_url":"https://github.com/asterisk/asterisk","commit_stats":null,"previous_names":[],"tags_count":1624,"template":false,"template_full_name":null,"purl":"pkg:github/asterisk/asterisk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Fasterisk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Fasterisk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Fasterisk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Fasterisk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asterisk","download_url":"https://codeload.github.com/asterisk/asterisk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asterisk%2Fasterisk/sbom","scorecard":{"id":213318,"data":{"date":"2025-08-11","repo":{"name":"github.com/asterisk/asterisk","commit":"b0421fc87c6f9c900635c701036e607d6402857d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":6,"checks":[{"name":"Code-Review","score":9,"reason":"Found 27/30 approved changesets -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/CreateDocs.yml:1","Warn: no topLevel permission defined: .github/workflows/IssueOpened.yml:1","Warn: no topLevel permission defined: .github/workflows/NightlyAdmin.yml:1","Warn: no topLevel permission defined: .github/workflows/NightlyTests.yml:1","Warn: no topLevel permission defined: .github/workflows/OnPRCPCheck.yml:1","Warn: no topLevel permission defined: .github/workflows/OnPRCheck.yml:1","Warn: no topLevel permission defined: .github/workflows/OnPRMergeApproved.yml:1","Warn: no topLevel permission defined: .github/workflows/Releaser.yml:1","Warn: no topLevel permission defined: .github/workflows/WeeklyTests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":8,"reason":"5 out of the last 5 releases have a total of 5 signed artifacts.","details":["Info: signed release artifact: asterisk-22.5.1-patch.tar.gz.asc: https://github.com/asterisk/asterisk/releases/tag/22.5.1","Info: signed release artifact: asterisk-21.10.1-patch.tar.gz.asc: https://github.com/asterisk/asterisk/releases/tag/21.10.1","Info: signed release artifact: asterisk-20.15.1-patch.tar.gz.asc: https://github.com/asterisk/asterisk/releases/tag/20.15.1","Info: signed release artifact: asterisk-18.26.3-patch.tar.gz.asc: https://github.com/asterisk/asterisk/releases/tag/18.26.3","Info: signed release artifact: asterisk-certified-20.7-cert7-patch.tar.gz.asc: https://github.com/asterisk/asterisk/releases/tag/certified-20.7-cert7","Warn: release artifact 22.5.1 does not have provenance: https://api.github.com/repos/asterisk/asterisk/releases/236639602","Warn: release artifact 21.10.1 does not have provenance: https://api.github.com/repos/asterisk/asterisk/releases/236637320","Warn: release artifact 20.15.1 does not have provenance: https://api.github.com/repos/asterisk/asterisk/releases/236636572","Warn: release artifact 18.26.3 does not have provenance: https://api.github.com/repos/asterisk/asterisk/releases/236635990","Warn: release artifact certified-20.7-cert7 does not have provenance: https://api.github.com/repos/asterisk/asterisk/releases/236637436"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Info: Possibly incomplete results: error parsing shell code: a command can only contain words and redirects; encountered (: contrib/scripts/ast_coredumper:0","Info: Possibly incomplete results: error parsing shell code: a command can only contain words and redirects; encountered (: contrib/scripts/ast_loggrabber:0","Warn: third-party GitHubAction not pinned by hash: .github/workflows/CreateDocs.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/CreateDocs.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/IssueOpened.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/IssueOpened.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/NightlyAdmin.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/NightlyAdmin.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/NightlyTests.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/NightlyTests.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/OnPRCPCheck.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/OnPRCPCheck.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/OnPRCheck.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/OnPRCheck.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/OnPRMergeApproved.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/OnPRMergeApproved.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/Releaser.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/Releaser.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/WeeklyTests.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/asterisk/asterisk/WeeklyTests.yml/master?enable=pin","Warn: containerImage not pinned by hash: contrib/docker/Dockerfile.asterisk:2: pin your Docker image by updating centos:7 to centos:7@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4","Warn: containerImage not pinned by hash: contrib/docker/Dockerfile.packager:1: pin your Docker image by updating alanfranz/fwd-centos-7:latest to alanfranz/fwd-centos-7:latest@sha256:8ea8fa06db4db04fae817c4a8e761793a891de9be54864ec50b51f82ef71dad9","Info:   0 out of   9 third-party GitHubAction dependencies pinned","Info:   0 out of   2 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'releases/22'","Warn: branch protection not enabled for branch 'releases/21'","Warn: branch protection not enabled for branch 'releases/20'","Warn: branch protection not enabled for branch 'releases/18'","Warn: branch protection not enabled for branch 'releases/certified-20.7'","Warn: branch protection not enabled for branch 'releases/certified-18.9'","Info: 'allow deletion' disabled on branch 'master'","Info: 'force pushes' disabled on branch 'master'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'master'","Warn: could not determine whether codeowners review is allowed","Warn: no status checks found to merge onto branch 'master'","Warn: PRs are not required to make changes on branch 'master'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T01:09:13.493Z","repository_id":30233389,"created_at":"2025-08-17T01:09:13.493Z","updated_at":"2025-08-17T01:09:13.493Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28880841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T10:31:27.438Z","status":"ssl_error","status_checked_at":"2026-01-29T10:31:01.017Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asterisk","c","pbx","sip","voip"],"created_at":"2024-07-30T19:00:35.044Z","updated_at":"2026-01-29T16:01:36.463Z","avatar_url":"https://github.com/asterisk.png","language":"C","readme":"# Best Practices\n\nThe purpose of this document is to define best practices when working with\nAsterisk in order to minimize possible security breaches and to provide tried\nexamples in field deployments. This is a living document and is subject to\nchange over time as best practices are defined.\n\n* [Filtering Data]:\n        How to protect yourself from redial attacks\n* [Proper Device Naming]:\n        Why to not use numbered extensions for devices\n* [Secure Passwords]:\n        Secure passwords limit your risk to brute force attacks\n* [Reducing Pattern Match Typos]:\n        Using the 'same' prefix, or using Goto()\n* [Manager Class Authorizations]:\n        Recognizing potential issues with certain classes of authorization\n* [Avoid Privilege Escalations]:\n        Disable the ability to execute functions that may escalate privileges\n* [Important Security Considerations]:\n        More information on the Asterisk Wiki\n\n## Additional Links\n\nAdditional links that contain useful information about best practices or\nsecurity are listed below.\n\n* [Seven Steps to Better SIP Security][blog-sip-security]\n* [Asterisk VoIP Security (webinar)][voip-security-webinar]\n\n\n## Filtering Data\n\nIn the Asterisk dialplan, several channel variables contain data potentially\nsupplied by outside sources. This could lead to a potential security concern\nwhere those outside sources may send cleverly crafted strings of data which\ncould be utilized, e.g. to place calls to unexpected locations.\n\nAn example of this can be found in the use of pattern matching and the ${EXTEN}\nchannel variable. Note that ${EXTEN} is not the only system created channel\nvariable, so it is important to be aware of where the data you're using is\ncoming from.\n\nFor example, this common dialplan takes 2 or more characters of data, starting\nwith a number 0-9, and then accepts any additional information supplied by the\nrequest.\n\n**NOTE**:\n\u003e We use SIP in this example, but is not limited to SIP only; protocols such as\n\u003e Jabber/XMPP or IAX2 are also susceptible to the same sort of injection problem.\n\n```INI\n[incoming]\nexten =\u003e _X.,1,Verbose(2,Incoming call to extension ${EXTEN})\nexten =\u003e _X.,n,Dial(PJSIP/${EXTEN})\nexten =\u003e _X.,n,Hangup()\n```\n\nThis dialplan may be utilized to accept calls to extensions, which then dial a\nnumbered device name configured in one of the channel configuration files (such\nas pjsip.conf, iax.conf, etc...) (see [Proper Device Naming] for more information\non why this approach is flawed).\n\nThe example we've given above looks harmless enough until you take into\nconsideration that several channel technologies accept characters that could\nbe utilized in a clever attack. For example, instead of just sending a request\nto dial extension 500 (which in our example above would create the string\nPJSIP/500 and is then used by the Dial() application to place a call), someone\ncould potentially send a string like \"500\u0026PJSIP/itsp/14165551212\".\n\nThe string \"500\u0026PJSIP/itsp/14165551212\" would then be contained within the\n${EXTEN} channel variable, which is then utilized by the Dial() application in\nour example, thereby giving you the dialplan line of:\n\n```INI\nexten =\u003e _X.,n,Dial(PJSIP/500\u0026PJSIP/itsp/14165551212)\n```\n\nOur example above has now provided someone with a method to place calls out of\nyour ITSP in a place where you didn't expect to allow it. There are a couple of\nways in which you can mitigate this impact: stricter pattern matching, or using\nthe FILTER() dialplan function.\n\nThe CALLERID(num) and CALLERID(name) values are other commonly used values that\nare sources of data potentially supplied by outside sources.  If you use these\nvalues as parameters to the System() or MixMonitor() applications or the SHELL()\ndialplan function, you can allow injection of arbitrary operating system command\nexecution.  The FILTER() dialplan function is available to remove dangerous\ncharacters from untrusted strings to block the command injection.\n\n\n### Strict Pattern Matching\n\nThe simple way to mitigate this problem is with a strict pattern match that does\nnot utilize the period (.) or bang (!) characters to match on one-or-more\ncharacters or zero-or-more characters (respectively). To fine tune our example\nto only accept three digit extensions, we could change our pattern match to\nbe:\n\n```INI\nexten =\u003e _XXX,n,Dial(PJSIP/${EXTEN})\n```\n\nIn this way, we have minimized our impact because we're not allowing anything\nother than the numbers zero through nine. But in some cases we really do need to\nhandle variable pattern matches, such as when dialing international numbers\nor when we want to handle something like a SIP URI. In this case, we'll need to\nutilize the FILTER() dialplan function.\n\n\n### Using FILTER()\n\nThe FILTER() dialplan function is used to filter strings by only allowing\ncharacters that you have specified. This is a perfect candidate for controlling\nwhich characters you want to pass to the Dial() application, or any other\napplication which will contain dynamic information passed to Asterisk from an\nexternal source. Lets take a look at how we can use FILTER() to control what\ndata we allow.\n\nUsing our previous example to accept any string length of 2 or more characters,\nstarting with a number of zero through nine, we can use FILTER() to limit what\nwe will accept to just numbers. Our example would then change to something like:\n\n```INI\n[incoming]\nexten =\u003e _X.,1,Verbose(2,Incoming call to extension ${EXTEN})\nexten =\u003e _X.,n,Dial(PJSIP/${FILTER(0-9,${EXTEN})})\nexten =\u003e _X.,n,Hangup()\n```\n\nNote how we've wrapped the ${EXTEN} channel variable with the FILTER() function\nwhich will then only pass back characters that fit into the numerical range that\nwe've defined.\n\nAlternatively, if we didn't want to utilize the FILTER() function within the\nDial() application directly, we could save the value to a channel variable,\nwhich has a side effect of being usable in other locations of your dialplan if\nnecessary, and to handle error checking in a separate location.\n\n```INI\n[incoming]\nexten =\u003e _X.,1,Verbose(2,Incoming call to extension ${EXTEN})\nexten =\u003e _X.,n,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN})})\nexten =\u003e _X.,n,Dial(PJSIP/${SAFE_EXTEN})\nexten =\u003e _X.,n,Hangup()\n```\n\nNow we can use the ${SAFE_EXTEN} channel variable anywhere throughout the rest\nof our dialplan, knowing we've already filtered it. We could also perform an\nerror check to verify that what we've received in ${EXTEN} also matches the data\npassed back by FILTER(), and to fail the call if things do not match.\n\n```INI\n[incoming]\nexten =\u003e _X.,1,Verbose(2,Incoming call to extension ${EXTEN})\nexten =\u003e _X.,n,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN})})\nexten =\u003e _X.,n,GotoIf($[${EXTEN} != ${SAFE_EXTEN}]?error,1)\nexten =\u003e _X.,n,Dial(PJSIP/${SAFE_EXTEN})\nexten =\u003e _X.,n,Hangup()\n\nexten =\u003e error,1,Verbose(2,Values of EXTEN and SAFE_EXTEN did not match.)\nexten =\u003e error,n,Verbose(2,EXTEN: \"${EXTEN}\" -- SAFE_EXTEN: \"${SAFE_EXTEN}\")\nexten =\u003e error,n,Playback(silence/1\u0026invalid)\nexten =\u003e error,n,Hangup()\n```\n\nAnother example would be using FILTER() to control the characters we accept when\nwe're expecting to get a SIP URI for dialing.\n\n```INI\n[incoming]\nexten =\u003e _[0-9a-zA-Z].,1,Verbose(2,Incoming call to extension ${EXTEN})\nexten =\u003e _[0-9a-zA-Z].,n,Dial(PJSIP/${FILTER(.@0-9a-zA-Z,${EXTEN})\nexten =\u003e _[0-9a-zA-Z].,n,Hangup()\n```\n\nOf course the FILTER() function doesn't check the formatting of the incoming\nrequest. There is also the REGEX() dialplan function which can be used to\ndetermine if the string passed to it matches the regular expression you've\ncreated, and to take proper action on whether it matches or not. The creation of\nregular expressions is left as an exercise for the reader.\n\nMore information about the FILTER() and REGEX() dialplan functions can be found\nby typing \"core show function FILTER\" and \"core show function REGEX\" from your\nAsterisk console.\n\n\n## Proper Device Naming\n\nIn Asterisk, the concept of an extension number being tied to a specific device\ndoes not exist. Asterisk is aware of devices it can call or receive calls from,\nand how you define in your dialplan how to reach those devices is up to you.\n\nBecause it has become common practice to think of a specific device as having an\nextension number associated with it, it only becomes natural to think about\nnaming your devices the same as the extension number you're providing it. But\nby doing this, you're limiting the powerful concept of separating user from\nextensions, and extensions from devices.\n\nIt can also be a security hazard to name your devices with a number, as this can\nopen you up to brute force attacks. Many of the current exploits deal with\ndevice configurations which utilize a number, and even worse, a password that\nmatches the devices name. For example, take a look at this poorly created device\nin pjsip.conf:\n\n```INI\n[1000]\ntype=auth\nauth_type=userpass\npassword=1000\nusername=1000\n```\n\nAs implied by the context, we've permitted a device named 1000 with a password\nof 1000 to place calls internationally. If your PBX system is accessible via\nthe internet, then your system will be vulnerable to expensive international\ncalls. Even if your system is not accessible via the internet, people within\nyour organization could get access to dialing rules you'd prefer to reserve only\nfor certain people.\n\nA more secure example for the device would be to use something like the MAC\naddress of the device, along with a strong password (see the section Secure\nPasswords). The following example would be more secure:\n\n```INI\n[0004f2040001]\ntype=auth\nauth_type=userpass\npassword=aE3%B8*$jk^G\nusername=0004f2040001\n```\n\nThen in your dialplan, you would reference the device via the MAC address of the\ndevice (or if using the softphone, a MAC address of a network interface on the\ncomputer).\n\nAlso note that you should NOT use this password, as it will likely be one of the\nfirst ones added to the dictionary for brute force attacks.\n\n\n## Secure Passwords\n\nSecure passwords are necessary in many (if not all) environments, and Asterisk\nis certainly no exception, especially when it comes to expensive long distance\ncalls that could potentially cost your company hundreds or thousands of dollars\non an expensive monthly phone bill, with little to no recourse to fight the\ncharges.\n\nWhenever you are positioned to add a password to your system, whether that is\nfor a device configuration, a database connection, or any other secure\nconnection, be sure to use a secure password. A good example of a secure\npassword would be something like:\n\n```\naE3%B8*$jk^G\n```\n\nOur password also contains 12 characters with a mixture of upper and\nlower case characters, numbers, and symbols. Because these passwords are likely\nto only be entered once, or loaded via a configuration file, there is\nno need to create simple passwords, even in testing. Some of the holes found in\nproduction systems used for exploitations involve finding the one test extension\nthat contains a weak password that was forgotten prior to putting a system into\nproduction.\n\nUsing a web search you can find several online password generators such as\n[Strong Password Generator] or there are several scripts that can be\nused to generate a strong password.\n\n\n## Reducing Pattern Match Typos\n\nAs of Asterisk 1.6.2, a new method for reducing the number of complex pattern\nmatches you need to enter, which can reduce typos in your dialplan, has been\nimplemented. Traditionally, a dialplan with a complex pattern match would look\nsomething like:\n\n```INI\nexten =\u003e _[3-5]XXX,1,Verbose(Incoming call to ${EXTEN})\nexten =\u003e _[3-5]XXX,n,Set(DEVICE=${DB(device/mac_address/${EXTEN})})\nexten =\u003e _[3-5]XXX,n,Set(TECHNOLOGY=${DB(device/technology/${EXTEN})})\nexten =\u003e _[3-5]XXX,n,GotoIf($[${ISNULL(${TECHNOLOGY})} | ${ISNULL(${DEVICE})}]?error,1)\nexten =\u003e _[3-5]XXX,n,Dial(${TECHNOLOGY}/${DEVICE},${GLOBAL(TIMEOUT)})\nexten =\u003e _[3-5]XXX,n,Set(vmFlag=${IF($[${DIALSTATUS} = BUSY]?b:u)})\nexten =\u003e _[3-5]XXX,n,Voicemail(${EXTEN}@${GLOBAL(VOICEMAIL_CONTEXT)},${vmFlag})\nexten =\u003e _[3-5]XXX,n,Hangup()\n\nexten =\u003e error,1,Verbose(2,Unable to lookup technology or device for extension)\nexten =\u003e error,n,Playback(silence/1\u0026num-not-in-db)\nexten =\u003e error,n,Hangup()\n```\n\nOf course there exists the possibility for a typo when retyping the pattern\nmatch _\\[3-5\\]XXX which will match on extensions 3000 through 5999. We can\nminimize this error by utilizing the same =\u003e prefix on all lines beyond the\nfirst one. Our same dialplan with using same =\u003e would look like the following:\n\n```INI\nexten =\u003e _[3-5]XXX,1,Verbose(Incoming call to ${EXTEN})\nsame =\u003e n,Set(DEVICE=${DB(device/mac_address/${EXTEN})})\nsame =\u003e n,Set(TECHNOLOGY=${DB(device/technology/${EXTEN})})\nsame =\u003e n,GotoIf($[${ISNULL(${TECHNOLOGY})} | ${ISNULL(${DEVICE})}]?error,1)\nsame =\u003e n,Dial(${TECHNOLOGY}/${DEVICE},${GLOBAL(TIMEOUT)})\nsame =\u003e n,Set(vmFlag=${IF($[${DIALSTATUS} = BUSY]?b:u)})\nsame =\u003e n,Voicemail(${EXTEN}@${GLOBAL(VOICEMAIL_CONTEXT)},${vmFlag})\nsame =\u003e n,Hangup()\n\nexten =\u003e error,1,Verbose(2,Unable to lookup technology or device for extension)\nsame =\u003e n,Playback(silence/1\u0026num-not-in-db)\nsame =\u003e n,Hangup()\n```\n\n\n## Manager Class Authorizations\n\nManager accounts have associated class authorizations that define what actions\nand events that account can execute/receive.  In order to run Asterisk commands\nor dialplan applications that affect the system Asterisk executes on, the\n\"system\" class authorization should be set on the account.\n\nHowever, Manager commands that originate new calls into the Asterisk dialplan\nhave the potential to alter or affect the system as well, even though the\nclass authorization for origination commands is \"originate\".  Take, for example,\nthe Originate manager command:\n\n```\nAction: Originate\nChannel: PJSIP/foo\nExten: s\nContext: default\nPriority: 1\nApplication: System\nData: echo hello world!\n```\n\nThis manager command will attempt to execute an Asterisk application, System,\nwhich is normally associated with the \"system\" class authorization.  While some\nchecks have been put into Asterisk to take this into account, certain dialplan\nconfigurations and/or clever manipulation of the Originate manager action can\ncircumvent these checks.  For example, take the following dialplan:\n\n```INI\nexten =\u003e s,1,Verbose(Incoming call)\nsame =\u003e n,MixMonitor(foo.wav,,${EXEC_COMMAND})\nsame =\u003e n,Dial(PJSIP/bar)\nsame =\u003e n,Hangup()\n```\n\nWhatever has been defined in the variable EXEC_COMMAND will be executed after\nMixMonitor has finished recording the call.  The dialplan writer may have\nintended that this variable to be set by some other location in the dialplan;\nhowever, the Manager action Originate allows for channel variables to be set by\nthe account initiating the new call.  This could allow the Originate action to\nexecute some command on the system by setting the EXEC_COMMAND dialplan variable\nin the Variable: header.\n\nIn general, you should treat the Manager class authorization \"originate\" the\nsame as the class authorization \"system\".  Good system configuration, such as\nnot running Asterisk as root, can prevent serious problems from arising when\nallowing external connections to originate calls into Asterisk.\n\n\n## Avoid Privilege Escalations\n\nExternal control protocols, such as Manager, often have the ability to get and\nset channel variables; which allows the execution of dialplan functions.\n\nDialplan functions within Asterisk are incredibly powerful, which is wonderful\nfor building applications using Asterisk. But during the read or write\nexecution, certain dialplan functions do much more. For example, reading the\nSHELL() function can execute arbitrary commands on the system Asterisk is\nrunning on. Writing to the FILE() function can change any file that Asterisk has\nwrite access to.\n\nWhen these functions are executed from an external protocol, that execution\ncould result in a privilege escalation. Asterisk can inhibit the execution of\nthese functions, if live_dangerously in the \\[options\\] section of asterisk.conf\nis set to no.\n\nIn Asterisk 12 and later, live_dangerously defaults to no.\n\n[voip-security-webinar]: https://docs.asterisk.org/Deployment/Important-Security-Considerations/Asterisk-Security-Webinars/\n[blog-sip-security]: https://web.archive.org/web/20171030134647/http://blogs.digium.com/2009/03/28/sip-security/\n[Strong Password Generator]: https://www.strongpasswordgenerator.com\n[Filtering Data]: #filtering-data\n[Proper Device Naming]: #proper-device-naming\n[Secure Passwords]: #secure-passwords\n[Reducing Pattern Match Typos]: #reducing-pattern-match-typos\n[Manager Class Authorizations]: #manager-class-authorizations\n[Avoid Privilege Escalations]: #avoid-privilege-escalations\n[Important Security Considerations]: https://docs.asterisk.org/Deployment/Important-Security-Considerations/\n","funding_links":[],"categories":["C","Interconnect","PBX Servers","Apps"],"sub_categories":["SBC, IMS","Communication"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasterisk%2Fasterisk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasterisk%2Fasterisk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasterisk%2Fasterisk/lists"}