DEV Community

Discussion on: Tuples are ok

 
cherrydt profile image
David Trapp • Edited

You mean the opposite, right? Like, breaking Elm using JavaScript? Since this is what we were talking about.

Here is an example: gist.github.com/CherryDT/7ced888d7...

You will never figure out why it starts falling apart after entering PWN3D into the field just looking at the Elm file.

But if you see the rogue script inside the HTML file which reaches into Elm's "protected" world and breaks assumptions (in this case the assumption that reading the property of an HTML element never throws an error), you can see why it behaves like that.

(And in the same way I can of course pass unexpected things from JavaScript into the TypeScript world that break assumptions there, as you said. The only protection against this sort of thing would be to rigorously check every detail at runtime and that would kill performance obviously.)

Thread Thread
 
aminnairi profile image
Amin • Edited

Interesting, thanks for your repro.

As I was suspecting, it takes a script written in JavaScript. So you example will work in the case of a malicious attacker having the ability to inject scripts. But I hope we don't do that to our own applications!

I think that we can agree that in the context of an application, one won't use the JavaScript DOM API and the Elm DOM API at the same time or it would be pointless to use Elm.

But I'm really grateful for your example because this kind of attack might be harmful if an attacker has access to a flaw that allows him to inject scripts as I said. I wonder if using the MutationObserver API in some way can prevent the outside from mutating some HTMLElements (but it would probably mean blocking the Elm runtime from mutating it too).

Thread Thread
 
cherrydt profile image
David Trapp

MutationObserver won't help here, especially since my attack is against the JavaScript object representing that DOM element and not even the DOM element itself.

But one point I'm getting confused about right now is this: The reason I even chimed in in the first place was this statement of yours:

My point was to say that you can have interfaces, tuples, and everything you want, this won't prevent me from using your library, compile it to javascript and use the wrong types because in the runtime, it is JavaScript.

...which I read as "things outside of your bubble can interfere with your code at runtime in unexpected ways, rendering your compile-time protections useless", which in my opinion is true for pretty much every language, hence the example with Elm now.

If we are talking about staying inside the bubble anyway, then for me that point is moot, because in your own TypeScript code you also won't add scripts that hurt yourself...

And if you are just talking about the defined interfaces between the languages, then it's true that JSON data in ports won't be able to trip up Elm that easily but that's just because Elm does (expensive) runtime validation there for you. TypeScript leaves this task up to you. (But there are tools out there to help with that, such as the validator io-ts github.com/gcanti/io-ts/ which does runtime validation with given constraints and automatically also creates the correct TS types from it based on your constraints.) Just like in my C++ example: C++ also won't do runtime type checking (in fact it cannot because unlike JavaScript as "base language", machine code doesn't have types, just raw bytes in memory whose meaning is up to you to know).

And if that is actually the point here, then again I don't see how "doesn't do runtime type checking" makes TypeScript any less of a language than Elm. :-)

(Oh and, "in Elm you have to use Elm" isn't true either, because there are (hacky) ways to synchronously invoke your Elm function from JS without implicit type marshalling, and then you can pass arbitrary data to it including data with traps like properties that throw and so on. And since you are talking about other people using your code, you can't force them not to do that either, if they think they need it. See lazamar.github.io/calling-elm-func... for example. Just like only providing a .ts file won't prevent people from compiling it to .js and circumventing your types, providing only an .elm file won't prevent people from compiling it to .js and messing with it either. Or, as mentioned, providing only a .cpp file in C++ won't prevent people from compiling to an .a file and statically linking to it from a language that doesn't care about the original function signatures your C++ functions had.)