Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content Security Policy requires i. e. "script-src 'self' sub.domain.tld 'unsafe-eval'" #92

Open
syntaxys opened this issue Jun 11, 2024 · 11 comments

Comments

@syntaxys
Copy link

I am currently preparing a project for a penetration test that uses this extension for a form in Contao. However, the JavaScript requires the CSP setting 'unsafe-eval' to ensure functionality. What would be the best solution to get around this?

In the form, only 1 fieldset based on a checkbox is made visible. This could also be implemented with a jQuery one-liner. Is the JS of the extension always required in this form or can it be deactivated?

@fritzmg
Copy link
Contributor

fritzmg commented Jun 11, 2024

That's how the extension evaluates the condition you defined in your fieldset.

@syntaxys
Copy link
Author

I am aware of this, but is it possible to get it done without the JavaScript in the extension? Or is it necessary for the PHP part of the extension to be processed correctly? This is not obvious to me at the first glance.

The stupid thing is that with the CSP parameter 'unsafe-eval' you already give a potential attacker a hint to try out something and the extension actually does not work without this parameter. On the other hand, the CSP header should definitely be set for security reasons.

@fritzmg
Copy link
Contributor

fritzmg commented Jun 11, 2024

You could remove the JavaScript from $GLOBALS['TL_JAVASCRIPT'] and implement your own solution for hiding/showing the fieldset.

@Toflar
Copy link
Member

Toflar commented Jun 11, 2024

We would probably need to either rewrite the JS evaluation logic with some safe JS parser (no idea if such a thing exists) or ajaxify the logic and evaluate the expression on the server side. Whoever wants to work on this chooses the path we take :)

@syntaxys
Copy link
Author

It is somewhat difficult to think your way into a project when the documentation is quite sparse and the declaration of variables and functions is somewhat cryptic. 😉
If you knew why something was done this way or not differently, it would be easier to contribute with ideas.

I am currently wondering whether it is really necessary to evaluate anything at all with JavaScript. As I understand it, you could do without it completely.

The PHP part of the extension knows the condition for the switch to display the parts in the form from the conditionalFormFieldCondition column in tl_form_field table and could generate a jQuery snippet from this that specifically addresses the elements in the DOM, e.g.:

$( "#formID #elementID" ).click(function() {     
    if($('#another-elementID:visible').length)
        $('#another-element').hide("fade", 1000);
    else
        $('#another-elementID').show("fade", 1000);        
});

The respective IDs can be easily determined from the condition, these snippets would then have to be stored collectively in the JavaScript file that is integrated in the frontend. This can happen every time the PHP part of the extension is triggered.

This would allow you to completely dispense with client-side evaluation. Or am I wrong? What would argue against this concept?

@fritzmg
Copy link
Contributor

fritzmg commented Jun 12, 2024

I am currently wondering whether it is really necessary to evaluate anything at all with JavaScript. As I understand it, you could do without it completely.

The JavasScript shows or hides the fieldsets according to your condition.

What would argue against this concept?

Nothing if you find a way to generate pre-baked JavasScript out of arbitrary conditions :)

@syntaxys
Copy link
Author

Nothing if you find a way to generate pre-baked JavasScript out of arbitrary conditions :)

What is not possible with PHP in the backend that can be realized with JavaScript in the frontend in terms of the arbitrariness of conditions? :)

Anyway, if such a snippet will be enough to get the job done, I can live with it 😁

As soon as I find some time on a rainy day, I'll create a fork and see what I can do ...

@fritzmg
Copy link
Contributor

fritzmg commented Jun 12, 2024

What is not possible with PHP in the backend that can be realized with JavaScript in the frontend in terms of the arbitrariness of conditions? :)

I am not sure I understand what you mean. You need JavaScript to show/hide the fieldsets in the front end, according to the conditions you set.

@syntaxys
Copy link
Author

Again: I know that I need JavaScript to show/hide the fieldsets in the front end, according to the conditions I've set. But I'm sure that I don't need JavaScript to evaluate these conditions. To do that evaluation server-side and send pre-baked jQuery snippets to the frontend would be a great security improvement.

I don't want to avoid JavaScript per se, but the necessary evaluation of the conditions with it and the opening of a barn door associated with the eval() function. With evaluation functionality you basically allow everything being executed that is transmitted in the context of the function. This is the reason why the Content Security Policy restrictively prevents this.

Maybe this helps for a better understanding:
https://stackoverflow.com/questions/37155270/content-security-policy-csp-safe-usage-of-unsafe-eval

@fritzmg
Copy link
Contributor

fritzmg commented Jun 12, 2024

in terms of the arbitrariness of conditions?

Well I thought it won't be that easy to generate JavaScript that will apply conditions like

in_array('foobar', somefield) || someotherfield == 'lorem' && anotherfield != 'ipsum'

But I suppose it's possible.

pre-baked jQuery snippets

btw. it will need to be pure JavaScript, so that it is independent from any framework.

@aschempp
Copy link
Member

The only possible solution I can think of is generating the toggleFieldset (https://github.com/terminal42/contao-conditionalformfields/blob/main/public/conditionalformfields.js#L27-L42) code for each element inline in the template so that we can add CSP stuff. But not sure how the evaluation script would then use that code …

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants