7 ms·
Probably important to mention that at the moment, TypeScript as a configuration format means anyone who writes a configuration blob for you has arbitrary code e
by fay59 5y ago
Probably important to mention that at the moment, TypeScript as a configuration format means anyone who writes a configuration blob for you has arbitrary code execution. This is rarely an issue in practice, though.
- cphoover 5y agoIt also means your configuration must be transpiled into JS first before execution unless run through a typescript runtime interpreter.
- mejutoco 5y agoThis could be solved by having some kind of sandbox (https://github.com/patriksimek/vm2 https://github.com/patriksimek/vm2), but I agree it complicates it. It would be cool if tsc had a flag —sandboxed or similar that does not allow any sideeffects (fs access, output, forking, net requests, etc)
- realrocker 5y agoOne of such sandboxes is Deno.
- cormacrelf 5y agoNot even Deno can solve the halting problem, unfortunately.
- Zababa 5y agoNo need to solve the halting problem, just put a timeout.
- cormacrelf 5y agoIf you use it by running a V8 isolate that transforms the exported config into JSON, then sure. But TS-based config is largely for people using TS elsewhere. And in that case: // this returns in 0 ms export const config: any = { get value() { while (true) {} } } as const; // accessing config.value runs forever console.log(config.value); For a less unrealistic perspective, if you write enough configuration in a Turing-complete language, you will eventually be tempted to use the full power of the language. You may find yourself having to write tests for the config, which might be e.g. parsing other files, making HTTP requests, querying the filesystem/OS and more. If you're doing that, you are no longer really writing configuration. The point of having a config file in the first place was so that it could be replaced, at start time or better yet at runtime, without touching the rest of the code, such that the same code can be parametrized and instantiated as you wish. When you use a fully-powered language, this becomes a matter of discipline instead of something guaranteed by the format. ALL of the other competing config file formats are attempts to walk this line between too little expressive power and too much expressive power, such that people naturally separate their code and config. Typescript-as-config just abandons this goal; it's not a new idea, just one that has been rejected over and over again by each new format because everyone else saw the benefit of limiting expressive power.
- mejutoco 5y agoVery clear example, thank you. I would like to see an option to whitelist syntax/types/keywords in Typescript. Allowing only const, dicts, arrays, assignments (but not while). It could just abort if something other than the whitelisted appears. It could get rid of most of this problems, and not allow network or infinite looping (or file access, and others). Of course it would not be perfect, but could be good enough.
- cormacrelf 5y agoRhai can do this, obviously not for Js but for its own very customizable Lua-competitive language. https://rhai.rs/ https://rhai.rs/
- realrocker 5y agoAgreed. It's a matter of discipline. It is a a balancing act between: 1. A constrained specification where its difficult(but not impossible) to shoot yourself in the foot. 2. Devops: as in equitable participation of operators and developers in maintaining configuration on a build it, run it basis. Languages like skylark/starlark, dhall, cuelang, jsonnet promise a constrained spec(for operators) while being expressive enough(for developers). But after using skylark, jsonnet and dhall in production, personally I haven't seen enough adoption in terms of developer contribution so the promise of expressiveness which is attractive enough for developers hasn't been true for me. At my current workplace, we have taken a middle approach. We use typescript to generate/emit yaml/json and use "official" validators to validate this configuration. The developers get a familiar and "blessed" frontend to the configuration while the operators can still enforce schema validation, resources and security policy on the generated config. But yes, if one could import this base typescript package directly in their application, and generate the configuration which can be then picked up by the operator pipeline and isapplied to the infrastructure. That would be bad. Really bad.
- rkeene2 5y agoTcl's safe interpreters [0] have various limits like instruction count, command count, time, and memory [1]. [0] https://www.tcl.tk/man/tcl8.6/TclCmd/safe.html https://www.tcl.tk/man/tcl8.6/TclCmd/safe.html [1] https://www.tcl.tk/man/tcl8.6/TclCmd/interp.html#M48 https://www.tcl.tk/man/tcl8.6/TclCmd/interp.html#M48
- the_duke 5y agoDeno is sandboxed by default and doesn't allow disk or network access, which is ideal for configuration. It also runs Typescript directly.
- crabmusket 5y agoBe careful with terms like "directly" as people seem to get very confused when talking about Deno. "Transparently" may be more accurate. My understanding of the situation right now is that by default, Deno runs TS files by transpiling using SWC, which strips types without checking them, and then sends the result to V8. Optionally you can enable type checking which invokes TSC (with no emission) before SWC. All this is done "magically" from the user's point of view.