MommaWatasu / OteraEngine.jl

This package is a template engine for Julia Lang.
https://mommawatasu.github.io/OteraEngine.jl/stable
MIT License
20 stars 4 forks source link

Pass arbitrary Julia values into template #21

Closed frankier closed 10 months ago

frankier commented 10 months ago

At the moment only strings and numbers can be passed into a template since they are interpolated into a string which is then run using "eval(...)". Would it be possible to pass in arbitrary values including, e.g. functions? The mechanism that tmp_init uses, where a function is generated and then arguments are passed to it seems suitable. Perhaps this could be used, and then the distinction between tmp_init and jl_init could be removed, i.e. all variables in a single namespace?

MommaWatasu commented 10 months ago

I agree on your idea. But, I want to not only remove the distinction between two init arguments, but also change the way to execute the codes. Like jinja2, OteraEngine should guarantees that codes will executed inside of sandbox which means that executed on the child process.

After this change is applied, the fatal bug about set statement and the distinction is also solved. Then, you’ll be able to pass the arbitrary Julia variables into template.

frankier commented 10 months ago

As far as I understand, Jinja does not use a child process -- and I cannot see a need to for Otera to either. In fact, depending on how stuff is passed to subprocesseses, this opens things up to shell injection attacks --- I think Otera's current HEAD may indeed have such a vulnerability here. In addition, spawning a bunch of subprocesses is not great for performance.

Jinja does two things that might be related to sandboxing:

  1. Jinja HTML escapes variables by default, so as to prevent various injections in the case the string has come from a user. Since interpolating user values into HTML is very common, this is commonly userful.
  2. Jinja provides SandboxedEnvironment which works by rejecting templates that don't keep to a safe subset of Jinja. This is for templates from an untrusted source. This scenario is very uncommon, and so this is a pretty niche feature.

I think, if eval(...) is used instead of exec, this might allow arbitrary Julia variables, and to have only tmp_init.

MommaWatasu commented 10 months ago

You are right. Now I understand the weak points of using child process. I'll try implementing the tmp code execution with eval(...).

MommaWatasu commented 10 months ago

Now, new version 0.4.0 is released, and you can pass arbitrary Julia values into init. Please check docs and release note for details.

frankier commented 10 months ago

Great thanks! I'll check it out!