RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.67k stars 1.23k forks source link

CSP errors possible fix #2475

Open jeran-urban opened 4 years ago

jeran-urban commented 4 years ago

Hello,

I have been researching getting rid of the errors that come up using NSWAG with content-security-policies in place, without just allowing all.

I have narrowed the issues unresolvable by hashes and secure settings down to the following 2:

1) if I change the code in the index.html: 32 by removing the style tag:

before: 
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">

after:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

and change the swagger-ui.css to include that inline style mentioned above:

added:
svg {
        position: absolute;
        width: 0px;
    }

That takes care of one of the errors and leaves the page looking the same.

2) The second error I resolved by doing the following: prettifying the swagger-ui-bundle.js and on line 3739: commenting out the following lines:

//return function (e) {
    //    for (var n, r, i, o, a, s = e.textContent, u = 0, l = s[0], c = 1, p = e.innerHTML = "", f = 0; r = n,
    //        n = f < 7 && "\\" == n ? 1 : c;) {
    //        if (c = l,
    //            l = s[++u],
    //            o = p.length > 1,
    //            !c || f > 8 && "\n" == c || [/\S/.test(c), 1, 1, !/[$\w]/.test(c), ("/" == n || "\n" == n) && o, '"' == n && o, "'" == n && o, s[u - 4] + r + n == "--\x3e", r + n == "*/"][f])
    //            for (p && (e.appendChild(a = t.createElement("span")).setAttribute("style", ["color: #555; font-weight: bold;", "", "", "color: #555;", ""][f ? f < 3 ? 2 : f > 6 ? 4 : f > 3 ? 3 : +/^(a(bstract|lias|nd|rguments|rray|s(m|sert)?|uto)|b(ase|egin|ool(ean)?|reak|yte)|c(ase|atch|har|hecked|lass|lone|ompl|onst|ontinue)|de(bugger|cimal|clare|f(ault|er)?|init|l(egate|ete)?)|do|double|e(cho|ls?if|lse(if)?|nd|nsure|num|vent|x(cept|ec|p(licit|ort)|te(nds|nsion|rn)))|f(allthrough|alse|inal(ly)?|ixed|loat|or(each)?|riend|rom|unc(tion)?)|global|goto|guard|i(f|mp(lements|licit|ort)|n(it|clude(_once)?|line|out|stanceof|t(erface|ernal)?)?|s)|l(ambda|et|ock|ong)|m(icrolight|odule|utable)|NaN|n(amespace|ative|ext|ew|il|ot|ull)|o(bject|perator|r|ut|verride)|p(ackage|arams|rivate|rotected|rotocol|ublic)|r(aise|e(adonly|do|f|gister|peat|quire(_once)?|scue|strict|try|turn))|s(byte|ealed|elf|hort|igned|izeof|tatic|tring|truct|ubscript|uper|ynchronized|witch)|t(emplate|hen|his|hrows?|ransient|rue|ry|ype(alias|def|id|name|of))|u(n(checked|def(ined)?|ion|less|signed|til)|se|sing)|v(ar|irtual|oid|olatile)|w(char_t|hen|here|hile|ith)|xor|yield)$/.test(p) : 0]),
    //                a.appendChild(t.createTextNode(p))),
    //                i = f && f < 7 ? f : i,
    //                p = "",
    //                f = 11; ![1, /[\/{}[(\-+*=<>:;|\\.,?!&@~]/.test(c), /[\])]/.test(c), /[$\w]/.test(c), "/" == c && i < 2 && "<" != n, '"' == c, "'" == c, c + l + s[u + 1] + s[u + 2] == "\x3c!--", c + l == "/*", c + l == "//", "#" == c][--f];)
    //                ;
    //        p += c
    //    }
    //}(e)

With these two changes, I am able to use simple hashes to apply CSP rules without errors. I have been unable to determine exactly how that function I commented out works, but in all variations to the api and swagger xml annotations, I have not seen any difference to the swagger ui page without that code. I know that function triggers when you click the get/put/delete etc routes, but could not determine more than that. Could you share the unminified version of that code or explain what it does? If it is not needed, could these 2 changes be made to the code so we can stop having the CSP errors when using NSWAG in production?

If these changes are not possible to the core code, is there a way to make these 2 changes locally and easily?

Thank you.

pwhe23 commented 6 months ago

Interesting that no one else has run into this in 4 years. While going through our SOC2 security process we implemented CSP and so far NSwag is the only thing I can't figure out how to fix. We're using nonces so we aren't able to allow inline scripts or styles. To fix it for us, I believe we would just need to pass our CSP nonce value to NSwag and then it can add the nonce attribute to any loaded JS and CSS file tags. I'm willing to put in a pull request if you like this idea.

pwhe23 commented 6 months ago

Maybe a better approach would be to create an option similar to this code: c.CustomAsset("index", containingAssembly, "YourWebApiProject.SwaggerExtensions.index.html");

It could allow a func returning a custom string which could be dynamically generated instead of requiring a static embedded resource? c.CustomAsset("index", () => "<html><script src='' nonce=''>...</html>");

Using this technique I could then just pull out the embedded NSwag index.html string, use HtmlAgilityPack to add a placeholder for the nonces on the Githubissues.

  • Githubissues is a development platform for aggregating issues.