Background
Historically, Android Custom permissions have been a mess and were install order dependent, which was known to expose vulnerabilities.
Prior
I think the problem in your example is that you explicitly require that both your applications are granted the custom permission.
This part requires, that the com.example.thirdparty app has the permission:
And this part requires, that the com.example.app application has the permission as well:
context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", ...
You mention that you don't have this problem when using a service. I don't know how exactly you use the service, but if you simply declare it like this:
and then bind it like this:
context.bindService(serviceIntent, mServiceConnection, ...
then it's enough if com.example.thirdparty has the permission granted, while com.example.app doesn't need to have it.
In other words, I think this behavior is by design, and the difference you see between the Broadcast and Service behavior is because in the Broadcast case you specifically request that the com.example.app has the custom permission, whereas in the Service case you don't.
I hope I didn't misunderstand your problem. If I did, please let me know and I'll delete this response.