Open montlebalm opened 10 years ago
I think that F2's prototype can still be hijacked -- there's really no difference between hijacking F2.Events.emit
or F2.__proto__.emit
. As long as friendly and unfriendly apps share the same F2 singleton, there's no way to prevent hijacking. On the other hand, if the Apps don't share something, then they can't communicate.
For me, I would have the Apps trust the Container (maybe because I'm developing the TDA F2 Container :) ). The Container is responsible for instantiating instances of F2 or EventEmitter etc. to pass to the App's constructor function. That's how I'd do it. I don't see how to avoid having the App trust the Container, especially in the eventing because most events are between Container and App. It is possible to avoid trusting the Container in the event of App-to-App communication, but then you'd need to implement your own messaging and bypass the F2 singleton -- greatly reducing the usefulness of F2. That messaging would have to go through a shared channel -- either the DOM itself or through the shared backend. So I'm not sure that degree of paranoia is feasible in the majority of cases.
@ilinkuo:
As long as friendly and unfriendly apps share the same F2 singleton, there's no way to prevent hijacking.
In the example above, F2.spawn()
creates a new instance of F2. Overriding the emit
event of your instance wouldn't affect any F2 but your own.
@montlebalm
Please look at this fiddle http://jsfiddle.net/ilinkuo/LFzYW/ to see how to override the prototype's emit() method (not the instance) and also read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
@ilinkuo Is your contention with the idea of my example or simply the implementation of it? If it's the latter, trust that there will be plenty of time to take issue with the actual library code.
In the snippet below, do you think there's a way to modify "F2.emit" such that it would affect future instances?
var F2Class = function() {
return {
emit: function(name, data) {
console.log("Safe and sound");
}
};
};
var F2 = new F2Class();
@montlebalm, there's two points of contention which I have:
emit()
function is no longer hijackable. Alright, so the original point of contention (emit being hijacked) appears to have been solved. The second point of contention (apps trusting containers?) also seems like it is solved by the fact that there is a normal emit
for regular messages like there is today in addition to a secureEmit
for secure messages (app-to-app or who knows, maybe even secure app-to-container). The third point of contention (browser memory usage) could go away if we just trusted apps and containers (seems like in some of other threads we're not willing to trust apps, though...).
All-in-all @montlebalm, my main point of contention with what you wrote is that I didn't write secure messaging into the original v1 :smile:
I just wanted to post an update that we're working with a potential solution to this issue. We've created a new event method called emitTo
that takes an array of AppIds or InstanceIds. F2 will look through its collection of instantiated apps and restrict the recipients to apps that match the provided filters. Here's an example:
F2.Events.emitTo(['com_example_foo', '7975565d-f516-48c6-82d3-1ca715c5009a'], 'TESTING');
F2 will emit the TESTING
event to any app whose AppId is com_example_foo
or whose InstanceId is 7975565d-f516-48c6-82d3-1ca715c5009a
. You will be able to prevent your emitTo
being tampered with by creating a new instance of F2.
This is certainly more low-tech than we were discussing, but so far it seems to do the job easily and elegantly. There is still some discussion about allowing pattern matching through regex or wildcards.
How does an app know the instanceId of a given app? Are you thinking app-to-app would just be using AppId? And Container-to-App would be instanceId?
I've seen situations on projects where you might have two instances of the same app, but you only want to broadcast to one of them. In that case you could get a handle on the InstanceId (potentially via events as well) and target your messages to that specific app. Containers certainly have an easier time getting InstanceId, but anyone could do it.
How does an app know the instanceId of a given app?
See #163 for a way this could happen, using a registry.
alternate implementation #164
A private event instance was bandied about early on, but we removed it when we tabled the idea of implementing F2 as several small modules. To make a bad analogy, multiple event instances feels like having a different email client for each person in your contact list. In practice, I think the two approaches would be used similarly. You'd reference a saved "vendorEvents" object and I would save a "vendorAppIds" array.
I agree that someone who communicates in a single channel could have cleaner syntax using the approach in #164. However, one alternative would be to allow a param to new F2()
that would allow someone to specify an array of ids that would be treated as default filters. Ultimately, we're going to encourage anyone with security concerns to create their own instance of F2 anyway. This kills two birds with one stone.
Thanks for the proposal. We'll give it some thought.
Sounds good to me. I'm looking forward to seeing what comes out. Please let me know when it is available on a public branch.
As an F2 app, I'd like to specify who can receive the events I broadcast. This is required to prevent nefarious apps from spying on the data I'm sending.
My proposed API is below. It's targeted at F2 version 2, which is AMD compliant.
The results of the example are that
com_red_appid
will broadcast its secure events to any "red" or "blue" apps. The other app,com_blue_appid
, will only send its secure messages to "blue" apps.The
secureEmit
could be replaced with an additional parameter to the regularemit
event. The community can decide which is the better API.I believe this example fulfills the following goals of secure messaging: