Proposal to disable in-call transfer features by default

I might be out of touch on how this is used so please weigh in. In-call transfer features (## and *2) seem to be legacies of analog and are uncommonly used in modern VoIP systems other than to be exploited for fraud. Pretty much any SIP phone can do blind or attended transfers using SIP methods, so these inband functions are not needed.

My proposal is to disable the in-call transfer functions by default on new installations of FreePBX. Disable these settings:

and get the T and t out of all the dial strings by default. If someone really wants them, they can enable them.

(Also disable the disconnect code because that’s just annoying. Sometimes I want to press * twice without getting disconnected - thanks Asterisk.)


I would support such a petition. I suspect the vast majority of users are not using these features, so the incremental improvement in security will probably outweigh the inconvenience to those who don’t realize they need to be enabled before using.

I recommend filing a feature request once discussion here dies (if it even starts).


I use them from time to time, but the default being the more secure choice is something I can support. As long as we can turn them back on, I’m all for it.


While InCall transfers are more for analog or those using feature codes as their main way to do things because of a crappy phone or not wanting to learn new things. They can be used for macros on phones to help with one-touch or shortcut type soft/line keys to do transfers, etc.

That said, the only way the InCall transfers can work is if the T or t options are set in the Dial() string. That only happens with internal facing Dial()'s. Now since an external call can be bounced around and still be sent out the trunks for any reason (FM, etc) there is this setting that is on by default:

At that point as long as the call has all the proper flags/variables set on it the system will strip/remove the ability to have the T option (called party can transfer) since the called party is external and at that point the calling party is either an extension or local channel.

Honestly, I’ve never seen an incident where InCall transfers have caused fraud. I’ve seen people opening up themselves to allow external callers to set CF and others things (DISA) so that’s happened. Plus I’ve seen it where a device gets compromised or the account is and they setup Call Forward on the account to send the calls somewhere.

But as it stands unless someone really screws with settings, adds custom stuff without consideration or turns off this protection the system already has mitigation for stopping what you are referring to.

Follow up:

External call comes into the PBX that is Channel A, now in order for InCall transfers to work there must be a answered and bridged call. So now the caller needs to be sent somewhere that answers the call. Where would that be? An IVR? Queue? Extension?

Even then they’ll hit *2 or ## which will now put the called channel (Channel B) on hold and then dial Channel C. So if that call passes all the routes and goes out to the PSTN when it’s all said and done the caller has to complete the transfer and then Channel B is transferred to Channel C.

How is that fraud call going to happen? What is Channel B active on? At this point the Channel C has zero ability to do any type of transfers themselves and I guess Channel B could if it was an actual person. However, at that point you have bigger issues to deal with.

Let’s been clear, I’m not questioning/arguing for/against disabling or leaving InCall transfers enabled by default. I’m rather indifferent on it. The reasoning behind it though, that is what I’m questioning.

Recently posted on the forum: FreePBX hacked via dialplan

Related ticket:

There are not enough details to say for sure that this was an inband transfer exploit, but it’s plausible. Anyway, it’s what the user claims, and should be tested thoroughly.

I would hope that “Disallow transfer features for inbound callers” is water-tight, but I can be absolutely certain of it if inband transfer features are disabled globally.

I would classify this as belt and suspenders. Should the belt fail at some future date for any of a dozen unknown possible reasons, the suspenders pick up the slack. Shouldn’t be necessary, but nice to have in case it is.


Yes and there is this:

Set original setup of the inbound route that has been used was:

InboundRoute -> Misc Destination -> Call to a number

Misc. Destinations will dial something as if they are an internal caller which, right there, makes all that stuff for “inbound callers” moot. I got back to my previous statements about the users doing stuff to allow things to happen from external callers.

Which means the ticket opened against this issue is also under that.

The tool tip seems pretty absolute:

Disallow transfer features (Normally ## and *2) for callers who passthrough inbound routes (Such as external callers)

Here’s the tool tip for Misc Destinations:

Enter the number this destination will simulate dialing, exactly as you would dial it from an internal phone. When you route a call to this destination, it will be as if the caller dialed this number from an internal phone.

Pretty subtle; I would call it a booby trap. More compelling reason to disable internal transfer features globally by default.

There was also this in that post:

asterisk -rx ‘database show ampuser’ | grep speeddials
/AMPUSER//speeddials/ :
/AMPUSER//speeddials/** :
/AMPUSER//speeddials/0000 : 900442085350050
/AMPUSER//speeddials/1 : 900442085350050
/AMPUSER//speeddials/105 : 900442070871900

That means something wrote to the AstDB either wrong or on purpose like that because when the checks are made against the DB and external calls have the AMPUSER variable not set, it will pull those and use those if called upon.

This is something else that needs to be looked at. I’m unaware of a way an external caller can write things to the AstDB.

I think what he is saying happened is this…

Caller called in and initiated a transfer by doing ## or *2. Then the caller dialed *75 (default feature code for adding a speed dial) followed by numbers to set up each of the speed dials that got written to astdb.

In the ticket he put a comment saying that he can also do transfers when the inbound route is sent to a queue and not to Misc Dest. I have not tested that myself, but if so, that’s clearly a bug and not a user mistake.

Here is my theory on this: It’s a Queue. When the caller is put into the Queue, that is where the caller is. When the Queue is calling the agents the call is via Local channels from the Queue to the Agents.

Now when that Local channel calls the external number it’s from the Queue so all the variables that hold this is an external call are not there. So now when the Queue then merges those calls together they are now bridged and the ONLY WAY this call can be use InCall Transfers is if the Dial() to the external agent allows it.

Since this is an external agent one can theorize that this agent, like their internal counter parts, will need to be able to transfer calls they made or received. This would require calls out the trunk to that external agent to actually have the Tt options on it to facilitate this.

So far this is not sounding like a bug but a poorly setup method of handling external agents.


I am the one created the ticket and the post. I have updated the ticket with a trace but I am starting to believe that for some reason channels are swappped. For now on all of our installations we have disabled unneeded feature codes (including ## and *2)


Is it possible that you could make a list and post here of the other unneeded feature codes you disable by default (in particular, those that are exploited by unsavory characters)?



Only you can decide if a feature is needed or not.

What @lgaetz said. Its different for each of our clients. For some I disabled all features code, for some only the call forward codes.

If you ask what are the feature codes that could be exploited most, these are, in my opinion, the call forward, speed dial and in call tranfer codes. But as I said, it depends on the client.

1 Like

In our daily usage, this is a mandatory feature in this case:

  • an external inbound call received at help desk
  • internal call to staff member and ends up to the voice mail
  • *2 only way to cancel this internal call and go back to the initial external caller

So keep it ! at least as an option.

On most systems, you can press Transfer, dial extension, hear voicemail, press Cancel and be back with original caller. What kind of phone is help desk using? What goes wrong using normal Transfer key?

More details:

  • Inbound call arrived in a queue
  • call pick-up by one of the help-desk phone

Canceling the internal call ==> external call endless waiting in the queue

Phones are Snom.

Running Freepbx for more than 10 years now, and never had that security flaw.
“Disallow transfer features for inbound callers” is enabled.

Can you put a call (picked up from the queue) on hold (with the Hold key), then resume that call? If not, then there is a bug in the queue logic. Otherwise, something must be wrong with the Transfer logic, because an uncompleted transfer should appear to Asterisk as nothing more than a call placed on hold and later resumed.

In your failing case, what does the help desk user see after the cancel? Does he have an option to resume the original call? If so, what does he hear and see when he presses it?