Hello Ruby Developers,
I love Ruby, its simplicity, its compactness, and the power of its native functions.
That’s why it seemed obvious to me that, to add a scripted formula system to OpenCutList, I would opt directly for Ruby rather than reinvent a home made script language.
Except that to use Ruby code in a SketchUp extension, you have to use the eval
command. That runs in global context. However, Trimble’s security policy has changed, and calling eval
is no longer allowed without securing the transmitted code. I know they’re right.
Not wanting to part with the Ruby scripts that the user can insert into the extension, I chose to try to block dangerous functions. But it’s not easy to be sure of bypassing them all.
Currently I extend Ripper to parse the input Ruby code and detect unwanted Const or methods use.
You can check the source code of my parser here:
As you can see there’s back listed keyword and methods and white listed Const.
Examples of prohibited codes here.
How to use it ?
begin
Ladb::OpenCutList::FormulaParser.new('[unsafe ruby code]', nil).parse
rescue Ladb::OpenCutList::ForbiddenFormulaError => e
puts e.messge
end
Question ?
- What do you think of this method?
- Do you have any other ideas for things to ban?
Hi Boris,
For context, could you provide an example of how the formulas would be used?
Is it basic mathematical operators like 4 + 5, does it reference variables such as material thickness, length, width etc, is it using sin, cosine etc? When does the user use it? Where does the formula output go? To dynamically size something in the model, to generate text for a report or anything else?
Where are the formulas saved? Along with the SKP file and potentially executed at someone else’s machine if you send them the file or confined to the local system where they were entered?
Hello Christina,
Formulas are used to customize / format / compute text output only. It does not generate anything in the model.
Some examples :
does it reference variables such as material thickness, length, width
Yes, but I do it through Wrapper object passed as instance variables to the eval.
is it using sin, cosine etc?
It has to be possible, yes. That’s why I add Math
package in whitelist.
Where are the formulas saved?
In model attributes.
Along with the SKP file and potentially executed at someone else’s machine if you send them the file or confined to the local system where they were entered?
Formulas can (and must) be transmitted with SKP file. I know that’s what’s causing the problem.
1 Like
Thanks for clarifications!
This usage seems safe and reasonable to me. At this point we don’t have an exact established policy about eval but it is raising security concerns.
I would advice a code comment next to eval explaining what it’s for and why it’s needed, maybe even linking this conversation. It helps future reviews.
1 Like
The eval
method accepts a Binding
to another context (a module, or class instance, etc.,) within which it can do the evaluation.
In addition, you could also use Moduel#module_eval
which only evaluates within the module instance. So you could (for example) create a “dummy” submodule within your namespace & extension modules, to wrap up evaluation.
But yes I see that you may wish to restrict access to certain Ruby classes and modules. File
, Dir
, Kernel
… etc.
Parsing as you’ve done seems the best way if you are going to use Ruby.
I wonder if there is a way to spin-off a smaller protected subprocess? A “mini-API” so to speak.
The only other thing I could think of is perhaps Strings with replacement parameters.
See format specifications
.
1 Like
Thank you both for your answers.
Still in ruby you mean?
Yes it would have to be in order to access SketchUp model objects. I would think it would need to be coded in C and compiled. Ie, it’s own interpreter that restricts access to model objects and some of the core Ruby classes (String, Numerics, Array, Math, Comarable, Enumerable, etc.) It is beyond my abilities.
Okay, but this can produce the same result as checking for the use of prohibited Classes, with more work, no?