Skip to content

Make scripts and styles compatible with content security policy #59

@cokernel

Description

@cokernel

In order to make the application more compatible with the introduction of Content-Security-Policy headers, all inline script and style elements should add the attribute nonce="SERVER_CSP_NONCE" (with exactly that text), and any HTML onchange attributes (I found one in the pagination view) should be replaced with explicit event listeners attached separately. Details follow.


I have attempted to make a minimal content security policy which is as strict as is compatible with the app functioning. The current draft is (broken across lines for readability):

add_header Content-Security-Policy 
   "default-src 'self'; 
    img-src 'self' https://exploreuk.uky.edu;
    script-src 'self' 'nonce-$csp_nonce';
    style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://use.fontawesome.com;
    font-src 'self' https://use.fontawesome.com;
    frame-ancestors 'self';
    base-uri 'none'";

Every URL listed is there because I needed to permit at least one thing from that host that would otherwise be a CSP violation, although some can probably be removed with more extensive editing of the application.

One of the things I am least comfortable with is adding 'unsafe-inline' (instead of 'nonce-$csp_nonce') to style-src because of the way the included version of Modernizr mucks about with style. Therefore, I recommend checking if Modernizr is actually used, and if so, whether the CSP issues still exist in more recent versions. Failing that, there is a 2014-era CSP workaround in Modernizr/Modernizr#1263 . I have not tested that last option, and I hope that is not the road we must travel.

Inline scripts and style elements will need to have the attribute nonce="SERVER_CSP_NONCE". In my testing, I needed to modify the following views:

Additionally, I found one example of an HTML event listener attribute, in https://github.com/uklibraries/exploreuk-web-app/blob/dev/app/application/libraries/ExploreUK/views/pagination.php#L12 . The onchange="this.form.submit()" on the select element could be replaced with something like the following (I recommend const instead of var, but this is what was straightforward to get working in my testing):

var elements = [...document.querySelectorAll(".pagination-rows")];
elements.forEach(rowCountSelector => {
    rowCountSelector.addEventListener("change", function (e) {
        this.form.submit();
    });
});

At this point in my testing, searching within books is not functional. For example, if you visit the application page /catalog/xt7m901zd99j?q=bear, then the book will load properly, mark search results, and allow general navigation, but if you type "cat" in the book reader search box and click "go", the search results will not be updated. In the console a message similar to the following appears:

Content-Security-Policy: The page’s settings blocked an inline script (script-src-elem) from being executed because it violates the following directive: “script-src 'self' 'nonce-06307a16e651f4af0397611f6d02d069cadc44dd508f964744ea86d2eb2ed7ef'”. Consider using a hash ('sha256-6t/LTj1Zqw8pxEEiyufi3u0fKHkQ+XY/JLzkyNN8itA=') or a nonce.
Source: javascript:br.search($("#textSrch").val(… paged

Since I was just testing what could be done with adding nonce attributes to script and style elements, I did not pursue this issue further into the Internet Archive BookReader code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions