Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"", "gen_ut":1731653551, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"511f6594a09831e342d5167fdd7d131a", "oid":{ "oid": "6328231f2aa628632344d96a58e25c3b194af506", "alias": [ "refs/heads/main"]},"blobname": "READMEs/README.content-security-policy.md", "blob": "## Using Content Security Policy (CSP)\n\n### What is it?\n\nModern browsers have recently implemented a new feature providing\na sort of \u0022selinux for your web page\u0022. If the server sends some\nnew headers describing the security policy for the content, then\nthe browser strictly enforces it.\n\n### Why would we want to do that?\n\nScripting on webpages is pretty universal, sometimes the scripts\ncome from third parties, and sometimes attackers find a way to\ninject scripts into the DOM, eg, through scripts in content.\n\nCSP lets the origin server define what is legitimate for the page it\nserved and everything else is denied.\n\nThe CSP for warmcat.com and libwebsockets.org looks like this,\nI removed a handful of approved image sources like travis\nstatus etc for clarity...\n\n```\n\u0022content-security-policy\u0022: \u0022default-src 'none'; img-src 'self' data:; script-src 'self'; font-src 'self'; style-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'none';\u0022,\n\u0022x-content-type-options\u0022: \u0022nosniff\u0022,\n\u0022x-xss-protection\u0022: \u00221; mode\u003dblock\u0022,\n\u0022x-frame-options\u0022: \u0022deny\u0022,\n\u0022referrer-policy\u0022: \u0022no-referrer\u0022\n```\n\nThe result of this is the browser won't let the site content be iframed, and it\nwill reject any inline styles or inline scripts. Fonts, css, ajax, ws and\nimages are only allowed to come from 'self', ie, the server that served the\npage. You may inject your script, or deceptive styles: it won't run or be shown.\n\nBecause inline scripts are banned, the usual methods for XSS are dead;\nthe attacker can't even load js from another server. So these rules\nprovide a very significant increase in client security.\n\n### Implications of strict CSP\n\nHalfhearted CSP isn't worth much. The only useful approach is to start\nwith `default-src 'none'` which disables everything, and then allow the\nminimum needed for the pages to operate.\n\n\u0022Minimum needed for the pages to operate\u0022 doesn't mean defeat the protections\nnecessary so everything in the HTML can stay the same... it means adapt the\npages to want the minimum and then enable the minimum.\n\nThe main point is segregation of styles and script away from the content, in\nfiles referenced in the document `\u003chead\u003e` section, along these lines:\n\n```\n\u003chead\u003e\n \u003cmeta charset\u003dutf-8 http-equiv\u003d\u0022Content-Language\u0022 content\u003d\u0022en\u0022/\u003e\n \u003clink rel\u003d\u0022stylesheet\u0022 type\u003d\u0022text/css\u0022 href\u003d\u0022test.css\u0022/\u003e\n \u003cscript type\u003d'text/javascript' src\u003d\u0022/lws-common.js\u0022\u003e\u003c/script\u003e\n \u003cscript type\u003d'text/javascript' src\u003d'test.js'\u003e\u003c/script\u003e\n \u003ctitle\u003eMinimal Websocket test app\u003c/title\u003e\n\u003c/head\u003e\n```\n\n#### Inline styles must die\n\nAll styling must go in one or more `.css` file(s) best served by the same\nserver... while you can approve other sources in the CSP if you have to,\nunless you control that server as well, you are allowing whoever gains\naccess to that server access to your users.\n\nInline styles are no longer allowed (eg, \u0022style\u003d'font-size:120%'\u0022 in the\nHTML)... they must be replaced by reference to one or more CSS class, which\nin this case includes \u0022font-size:120%\u0022. This has always been the best\npractice anyway, and your pages will be cleaner and more maintainable.\n\n#### Inline scripts must die\n\nInline scripts need to be placed in a `.js` file and loaded in the page head\nsection, again it should only be from the server that provided the page.\n\nThen, any kind of inline script, yours or injected or whatever, will be\ncompletely rejected by the browser.\n\n#### onXXX must be replaced by eventListener\n\nInline `onclick()` etc are kinds of inline scripting and are banned.\n\nModern browsers have offered a different system called [\u0022EventListener\u0022 for\na while](https://developer.mozilla.org/en-US/docs/Web/API/EventListener)\nwhich allows binding of events to DOM elements in JS.\n\nA bunch of different named events are possible to listen on, commonly the\n`.js` file will ask for one or both of\n\n```\nwindow.addEventListener(\u0022load\u0022, function() {\n...\n}, false);\n\ndocument.addEventListener(\u0022DOMContentLoaded\u0022, function() {\n...\n}, false);\n```\n\nThese give the JS a way to trigger when either everything on the page has\nbeen \u0022loaded\u0022 or the DOM has been populated from the initial HTML. These\ncan set up other event listeners on the DOM objects and aftwards the\nevents will drive what happens on the page from user interaction and / or\ntimers etc.\n\nIf you have `onclick` in your HTML today, you would replace it with an id\nfor the HTML element, then eg in the DOMContentLoaded event listener,\napply \n\n```\n document.getElementById(\u0022my-id\u0022).addEventListener(\u0022click\u0022, function() {\n ...\n }, false);\n```\n\nie the .js file becomes the only place with the \u0022business logic\u0022 of the\nelements mentioned in the HTML, applied at runtime.\n\n#### Do you really need external sources?\n\nDo your scripts and fonts really need to come from external sources?\nIf your caching policy is liberal, they are not actually that expensive\nto serve once and then the user is using his local copy for the next\ndays.\n\nSome external sources are marked as anti-privacy in modern browsers, meaning\nthey track your users, in turn meaning if your site refers to them, you\nwill lose your green padlock in the browser. If the content license allows\nit, hosting them on \u0022self\u0022, ie, the same server that provided the HTML,\nwill remove that problem.\n\nBringing in scripts from external sources is actually quite scary from the\nsecurity perspective. If someone hacks the `ajax.googleapis.com` site to serve\na hostile, modified jquery, half the Internet will instantly\nbecome malicious. However if you serve it yourself, unless your server\nwas specifically targeted you know it will continue to serve what you\nexpect.\n\nSince these scripts are usually sent with cache control headers for local\ncaching duration of 1 year, the cost of serving them yourself under the same\nconditions is small but your susceptibility to attack is reduced to only taking\ncare of your own server. And there is a privacy benefit that google is not\ninformed of your users' IPs and activities on your site.\n\n","s":{"c":1731653551,"u": 334}} ],"g": 3430,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 1, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}