[Libwebsockets] Content-Security-Policy

Andy Green andy at warmcat.com
Thu Jan 31 04:38:59 CET 2019



On 31/01/2019 11:24, Alexander Zvyagin wrote:
> Thanks Andy,
> 
> in fact, I did not realize that on the top of my "index.html" file,
> the policy implied by
> LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE is
> added extra. So all my attempts to modify the "index.html" file were
> in vain.
> 
> This is what I have done.
> 1. In the server source code, comment out the line:
>      // info.options =
> LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;

...

> 2. In the "index.html" add the line:
>      <meta http-equiv="Content-Security-Policy" content="script-src
> 'self' 'unsafe-eval';">
>      (it is also OK just to remove it completely, but I wanted to have
> something like that.)

If the server delivers the CSP headers independent of the payload, your 
CSP policy becomes mandatory vhost-wide without having to maintain it in 
individual files.

> ...and the browser is happy!

If the goal is just make the browser stop complaining, you can simply 
remove any attempt at CSP and it will remain completely happy even as 
scripts are injected, eval is abused etc.

> P.S. One day I have to really understand the CSP...
For a hacker these non-strict CSPs act as a convenient, public list of 
ways in to the site.

-Andy

> Thanks a lot!
> Alexander.
> 
> 
> On 31/01/2019, Andy Green <andy at warmcat.com> wrote:
>>
>>
>> On 31/01/2019 08:04, Alexander Zvyagin wrote:
>>> Hi,
>>>
>>> I have a question concerning Content-Security-Policy.
>>>
>>> My application is split into two parts. The server is written in a C++
>>> code with libwebsocket interface (based on minimal-ws-server.c code).
>>> The client is meteor-react application (which is basically means it
>>> consists from lots of nodejs packages). The client code after
>>> "building" stage compiles into two files "index.html" and "index.js".
>>> And the server successfully serves them and my websocket protocol, so
>>> I am happy.
>>>
>>> Almost. I had to disable in firefox browser checks for
>>> Content-Security-Policy.
>>
>> Well, it's a good problem... you have some restrictive CSP in place
>> already.
>>
>> The default is not send anything and then anything is considered fine at
>> the client, including script injection, hacks etc.
>>
>> The one applied by
>> LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE is that
>> used by libwebsockets.org and the minimal examples, it's extremely
>> strict and provides some meaningful secuity improvements.
>>
>>> Now it is time to fix this little problem, but I am not sure how. The
>>> "index.js" file is built with webpack. The file is big. It contains
>>> lots of "eval()" calls from external libraries. Modifying it is not an
>>
>> When I first started looking at this a couple of years ago I also
>> started with that approach... how can I keep this working with some CSP.
>>
>> However when I started thinking about how lws should promote CSP itself,
>> the kind of workarounds I was doing there were clearly usless and
>> counterproductive for any real security.
>>
>> Last year I went through all the minimal examples and test server, and
>> libwebsockets.org and warmcat.com (and gitohashi) sources and eliminated
>> all the problematic things that stopped me having a super strict CSP.
>> Particularly for gitohashi where you can't control what is uploaded and
>> rendered, a CSP that totally bans any form of inline script or css, or
>> stuff injected outside of head is mandatory.
>>
>> So I think this is maybe a two-step journey for everyone... just try to
>> survive it, and then later adapt what you serve so you can really
>> leverage it.
>>
>> "solving" this with unsafe-eval and friends just means the insecure
>> stuff is still served and exploitable, removing a lot of the point of
>> CSP.  Really using CSP means to change the stuff you're using so it
>> doesn't do insecure things itself, and then use CSP to absolutely ban
>> any way to reintroduce those insecure or deceptive things you purged...
>> which is by then painless since your own stuff is clean of it.
>>
>>> option. Most probably I need to apply a different security policy on
>>> the server side, right? Something with "unsafe-eval", I think. The
>>> file "./lib/roles/http/header.c" has the code with
>>> Content-Security-Policy settings, but I am not sure it is a good idea
>>> to modify it.
>>>
>>> What would you recommended me to do?
>>
>> The docs for the BEST_PRACTICES_ENFORCE option describe how can roll
>> your own headers per-vhost instead
>>
>> 	LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE	= (1 <<
>> 28),
>> 	/**< (VH) Send lws default HTTP headers recommended by Mozilla
>> 	 * Observatory for security.  This is a helper option that sends canned
>> 	 * headers on each http response enabling a VERY strict Content Security
>> 	 * Policy.  The policy is so strict, for example it won't let the page
>> 	 * run its own inline JS nor show images or take CSS from a different
>> 	 * server.  In many cases your JS only comes from your server as do the
>> 	 * image sources and CSS, so that is what you want... attackers hoping
>> 	 * to inject JS into your DOM are completely out of luck since even if
>> 	 * they succeed, it will be rejected for execution by the browser
>> 	 * according to the strict CSP.  In other cases you have to deviate from
>> 	 * the complete strictness, in which case don't use this flag: use the
>> 	 * .headers member in the vhost init described in struct
>> 	 * lws_context_creation_info instead to send the adapted headers
>> 	 * yourself.
>> 	 */
>>
>>
>>
>> 	const struct lws_protocol_vhost_options *headers;
>> 		/**< VHOST: pointer to optional linked list of per-vhost
>> 		 * canned headers that are added to server responses */
>>
>> They're done as pvos because if you are using lwsws or the lejp_conf
>> stuff for JSON config, you can add the extra headers there in the vhost
>> definition in JSON, eg from the config for warmcat.com vhost
>>
>> ...
>>
>>                   "headers": [{
>>                           "content-security-policy": "default-src 'none';
>> img-src 'self' data: https://travis-ci.org https://api.travis-ci.org
>> https://ci.appveyor.com https://scan.coverity.com
>> https://bestpractices.coreinfrastructure.org https://api.codacy.com;
>> script-src 'self'; font-src 'self'; style-src 'self'; connect-src
>> 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'",
>>                           "x-content-type-options": "nosniff",
>>                           "x-xss-protection": "1; mode=block",
>>                           "x-frame-options": "deny",
>>                           "referrer-policy": "no-referrer"
>>                   }],
>> ...
>>
>>
>> -Andy
>>
>>
>>> Thanks a lot in advance!
>>> Alexander.
>>> _______________________________________________
>>> Libwebsockets mailing list
>>> Libwebsockets at ml.libwebsockets.org
>>> https://libwebsockets.org/mailman/listinfo/libwebsockets
>>>
>>
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> https://libwebsockets.org/mailman/listinfo/libwebsockets
> 


More information about the Libwebsockets mailing list