From ca36d10121b52c9c35ba1135d54963b40d5543b4 Mon Sep 17 00:00:00 2001 From: agree <37550360+greenbea@users.noreply.github.com> Date: Thu, 30 Mar 2023 01:24:04 -0400 Subject: [PATCH] [security] prevent xml injection and executing switch api cmds (#6594) --- app/call_centers/call_center_agent_edit.php | 3 + app/call_centers/call_center_queue_edit.php | 20 +- .../resources/scripts/directory/directory.lua | 198 +++++++++--------- .../scripts/resources/functions/xml.lua | 29 +++ resources/classes/xml.php | 16 ++ 5 files changed, 158 insertions(+), 108 deletions(-) create mode 100644 app/scripts/resources/scripts/resources/functions/xml.lua create mode 100644 resources/classes/xml.php diff --git a/app/call_centers/call_center_agent_edit.php b/app/call_centers/call_center_agent_edit.php index 008355574a..98182429cb 100644 --- a/app/call_centers/call_center_agent_edit.php +++ b/app/call_centers/call_center_agent_edit.php @@ -162,6 +162,9 @@ $agent_contact = str_replace("@", "/", $agent_contact); } + //freeswitch expands the the contact string, so we need to sanitize it. + $agent_contact = str_replace('$', '', $agent_contact); + //prepare the array $array['call_center_agents'][0]['domain_uuid'] = $_SESSION['domain_uuid']; $array['call_center_agents'][0]['call_center_agent_uuid'] = $call_center_agent_uuid; diff --git a/app/call_centers/call_center_queue_edit.php b/app/call_centers/call_center_queue_edit.php index 5f4be19ee9..eda032d59a 100644 --- a/app/call_centers/call_center_queue_edit.php +++ b/app/call_centers/call_center_queue_edit.php @@ -336,42 +336,42 @@ } //build the xml dialplan - $dialplan_xml = "\n"; + $dialplan_xml = "\n"; $dialplan_xml .= " \n"; $dialplan_xml .= " \n"; $dialplan_xml .= " \n"; - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; $dialplan_xml .= " \n"; if (is_uuid($call_center_queue_uuid)) { - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; } if (is_numeric($queue_extension)) { - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; } $dialplan_xml .= " \n"; $dialplan_xml .= " \n"; if ($queue_time_base_score_sec != '') { - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; } if ($queue_greeting_path != '') { $dialplan_xml .= " \n"; $greeting_array = explode(':', $queue_greeting_path); if (count($greeting_array) == 1) { - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; } else { if ($greeting_array[0] == 'say' || $greeting_array[0] == 'tone_stream' || $greeting_array[0] == 'phrase') { - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; } } } if (strlen($queue_cid_prefix) > 0) { - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; } if (strlen($queue_cc_exit_keys) > 0) { - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; } - $dialplan_xml .= " \n"; + $dialplan_xml .= " \n"; if ($destination->valid($queue_timeout_app.':'.$queue_timeout_data)) { $dialplan_xml .= " \n"; } diff --git a/app/scripts/resources/scripts/app/xml_handler/resources/scripts/directory/directory.lua b/app/scripts/resources/scripts/app/xml_handler/resources/scripts/directory/directory.lua index 94028683bc..224b0de430 100644 --- a/app/scripts/resources/scripts/app/xml_handler/resources/scripts/directory/directory.lua +++ b/app/scripts/resources/scripts/app/xml_handler/resources/scripts/directory/directory.lua @@ -29,7 +29,7 @@ -- Luis Daniel Lucio Quiroz --set the default - continue = true; +continue = true; --get the action action = params:getHeader("action"); @@ -52,6 +52,8 @@ json = require "resources.functions.lunajson" end + local Xml = require "resources.functions.xml"; + --include cache library local cache = require "resources.functions.cache" @@ -490,207 +492,207 @@ end --build the xml - local xml = {} - table.insert(xml, [[]]); - table.insert(xml, [[]]); - table.insert(xml, [[
]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); + local xml = Xml:new(); + xml:append([[]]); + xml:append([[]]); + xml:append([[
]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); if (number_alias) then if (cidr) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); else - table.insert(xml, [[ ]]); + xml:append([[ ]]); end else if (cidr) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); else - table.insert(xml, [[ ]]); + xml:append([[ ]]); end end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); if (string.len(vm_mailto) > 0) then - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); end if (string.len(mwi_account) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (string.len(auth_acl) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); for key,row in pairs(extension_settings) do if (row.extension_setting_type == 'param') then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); if (user_uuid ~= nil) and (string.len(user_uuid) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (contact_uuid ~= nil) and (string.len(contact_uuid) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); if (call_group ~= nil) and (string.len(call_group) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (call_screen_enabled ~= nil) and (string.len(call_screen_enabled) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (user_record ~= nil) and (string.len(user_record) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (hold_music ~= nil) and (string.len(hold_music) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (toll_allow ~= nil) and (string.len(toll_allow) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (accountcode ~= nil) and (string.len(accountcode) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end - table.insert(xml, [[ ]]); + xml:append([[ ]]); if (effective_caller_id_name ~= nil) and (string.len(effective_caller_id_name) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (effective_caller_id_number ~= nil) and (string.len(effective_caller_id_number) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (outbound_caller_id_name ~= nil) and (string.len(outbound_caller_id_name) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (outbound_caller_id_number ~= nil) and (string.len(outbound_caller_id_number) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (emergency_caller_id_name ~= nil) and (string.len(emergency_caller_id_name) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (emergency_caller_id_number ~= nil) and (string.len(emergency_caller_id_number) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (missed_call_app ~= nil) and (string.len(missed_call_app) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (missed_call_data ~= nil) and (string.len(missed_call_data) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (directory_full_name ~= nil) and (string.len(directory_full_name) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (directory_visible ~= nil) and (string.len(directory_visible) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (directory_exten_visible ~= nil) and (string.len(directory_exten_visible) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (limit_max ~= nil) and (string.len(limit_max) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); else - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (limit_destination ~= nil) and (string.len(limit_destination) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (sip_force_contact ~= nil) and (string.len(sip_force_contact) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (sip_force_expires ~= nil) and (string.len(sip_force_expires) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (nibble_account ~= nil) and (string.len(nibble_account) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (absolute_codec_string ~= nil) and (string.len(absolute_codec_string) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (force_ping ~= nil) and (string.len(force_ping) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (sip_bypass_media ~= nil) and (sip_bypass_media == "bypass-media") then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (sip_bypass_media ~= nil) and (sip_bypass_media == "bypass-media-after-bridge") then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (sip_bypass_media ~= nil) and (sip_bypass_media == "proxy-media") then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_all_enabled ~= nil) and (string.len(forward_all_enabled) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_all_destination ~= nil) and (string.len(forward_all_destination) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_busy_enabled ~= nil) and (string.len(forward_busy_enabled) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_busy_destination ~= nil) and (string.len(forward_busy_destination) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_no_answer_enabled ~= nil) and (string.len(forward_no_answer_enabled) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_no_answer_destination ~= nil) and (string.len(forward_no_answer_destination) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_user_not_registered_enabled ~= nil) and (string.len(forward_user_not_registered_enabled) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (forward_user_not_registered_destination ~= nil) and (string.len(forward_user_not_registered_destination) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end if (follow_me_enabled ~= nil) and (string.len(follow_me_enabled) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end --if (follow_me_destinations ~= nil) and (string.len(follow_me_destinations) > 0) then - -- table.insert(xml, [[ ]]); + -- xml:append([[ ]]); --end if (do_not_disturb ~= nil) and (string.len(do_not_disturb) > 0) then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[ ]]); for key,row in pairs(extension_settings) do if (row.extension_setting_type == 'variable') then - table.insert(xml, [[ ]]); + xml:append([[ ]]); end end - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[ ]]); - table.insert(xml, [[
]]); - table.insert(xml, [[
]]); - XML_STRING = table.concat(xml, "\n"); + xml:append([[ ]]); + xml:append([[ ]]); + xml:append([[
]]); + xml:append([[
]]); + xml:append([[
]]); + xml:append([[
]]); + xml:append([[
]]); + xml:append([[
]]); + XML_STRING = xml:build(); --close the database connection dbh:release(); diff --git a/app/scripts/resources/scripts/resources/functions/xml.lua b/app/scripts/resources/scripts/resources/functions/xml.lua new file mode 100644 index 0000000000..ec315c2e46 --- /dev/null +++ b/app/scripts/resources/scripts/resources/functions/xml.lua @@ -0,0 +1,29 @@ +local xml = {} + +function xml:new(o) + o = o or {} + setmetatable(o, self); + self.__index = self; + self.xml = {}; + return o; +end + +function xml:append(data) + table.insert(self.xml, data); +end + +function xml:build() + return table.concat(self.xml, "\n"); +end + +function xml.sanitize(s) + return (string.gsub(s, "[\"><'$]", { + ["<"] = "<", + [">"] = ">", + ['"'] = """, + ["'"] = "'", + ["$"] = "" + })) +end + +return xml; \ No newline at end of file diff --git a/resources/classes/xml.php b/resources/classes/xml.php new file mode 100644 index 0000000000..15c992533a --- /dev/null +++ b/resources/classes/xml.php @@ -0,0 +1,16 @@ + \ No newline at end of file