label-studio-frontend
label-studio-frontend copied to clipboard
Content Security Policy Error on Build Process for config.xml Files
Hello community I'm trying to use LSF in my single-spa project. To do so, I had to manage some changes on LSF and convert it to a microfrontend. The important ones are described here and here. The goal is to use in-browser import maps to import one microfrontend in another one similar to JS import specifiers. I have successfully managed the process and now I'm able to import LSF in my other microfrontend app and the UI renders. However now there is only one problem initializing the app state.
While initializing the state tree of mobx store, LSF uses treeToModel and runTemplate functions to generate the model using the config provided via params. The problem rises from the config param which is a XML like file (actually some JSX markups in a custom file with a .XML suffix). I manage to import these files in the Webpack build process using raw-loader. However I got these errors on the build process using the below config.xml:
<View>
<Image name="img" value="$image"></Image>
<RectangleLabels name="tag" toName="img" fillOpacity="0.5" strokeWidth="5">
<Label value="Planet"></Label>
<Label value="Moonwalker" background="blue"></Label>
</RectangleLabels>
</View>
'Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline' https: localhost:*".
' in
Code:
with(obj) { var r=[]; r.push(image); return r.join(""); }
And the same CSP error for these lines:
with(obj) { var r=[]; r.push("Planet"); return r.join(""); }
&
with(obj) { var r=[]; r.push("Moonwalker"); return r.join(""); }
I think the markup extraction process in the runTemplate function causes the situation:
function runTemplate(html, options) {
if (!options) options = {};
var re = /[$](.+)/g,
reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g,
code = "with(obj) { var r=[];\n",
cursor = 0,
result,
match;
var add = function(line, js) {
js
? (code += line.match(reExp) ? line + "\n" : "r.push(" + line + ");\n")
: (code += line !== "" ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : "");
return add;
};
while ((match = re.exec(html))) {
add(html.slice(cursor, match.index))(match[1], true);
cursor = match.index + match[0].length;
}
if (!html) return "";
add(html.substr(cursor, html.length - cursor));
code = (code + 'return r.join(""); }').replace(/[\r\t\n]/g, " ");
try {
result = new Function("obj", code).apply(options, [options]); // eslint-disable-line no-new-func
} catch (err) {
console.error("'" + err.message + "'", " in \n\nCode:\n", code, "\n");
}
return result;
}
It seems that new Function() call triggers the CSP error.
Do you have any suggestion for a start point to do so? Or any other idea about how to proceed?
Update:
I tried this approach without using single-spa. Again this CSP error occurs while trying to run the string code with new Function() in runTemplate() function.
Passing script-src: 'unsafe-inline' 'unsafe-eval' to Content-Security-Policy header, solves the problem. But I wonder wouldn't it be a security glitch?
Wow, that's a good catch, thank you!
This is legacy code and the only thing it is used for — var substitution in value property ("$img" -> data.imgvalue from task), so you can replace entire function runTemplate with some simple replace. And I'll fix this soon in next release.
Will it fix CSP error?