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

Restricting JavaScript from accessing secrets #536

Open
craigfrancis opened this issue Nov 14, 2017 · 2 comments
Open

Restricting JavaScript from accessing secrets #536

craigfrancis opened this issue Nov 14, 2017 · 2 comments

Comments

@craigfrancis
Copy link
Contributor

craigfrancis commented Nov 14, 2017

All modern browsers block JavaScript from accessing httpOnly cookies; and Chrome blocks JavaScript from accessing the nonce attribute in <script nonce="abc123"> (details).

Would it be possible for websites to also block (potentially malicious) JavaScript from accessing other values from the DOM?

For example, I'd like to stop any JavaScript/CSS from accessing the CSRF token from a hidden input field (used in addition to SameSite cookies).

Two features I'd find useful would include:

  1. An attribute on the <input> so it's value (or the element) can't be accessed via the DOM, or via CSS selectors.
  2. A header to block XMLHttpRequest (or fetch) from accessing the content from a same-site request.

The first might be possible to introduce via the inert attribute, which is currently being specced as a simple flag to stop interaction events, text search, selecting text, and hiding from assistive technology.

The second could be as simple as recognising Access-Control-Allow-Origin: 'none' to stop all origins from being allowed to read the contents of the response (effectively causing same-site requests to be treated like a cross-origin request).


In Google Chrome, this example shows how the <script nonce="abc123"> can't be accessed, whereas the hidden input field named "csrf" can be.

Content-Security-Policy:
    default-src 'none';
    script-src 'nonce-123js';
    style-src 'nonce-123css';
    connect-src 'self';

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Sensitive Page</title>
</head>
<body>

    <form action="./?id=5" method="post">
        <input type="hidden" name="csrf" value="123csrf" />
        <input type="submit" value="Delete" />
    </form>

    <script nonce="123js">

        var script = document.getElementsByTagName('script')[0],
            input = document.getElementsByTagName('input')[0];

        console.log(script.getAttribute('nonce'));
        console.log(script.outerHTML); // Returns <script nonce="">...
        console.log(script.nonce); // Works, but not needed for this case.
        console.log(input.getAttribute('value'));

        fetch(window.location).then(function(response) {
            return response.text();
        }).then(function(text) {
            console.log(text);
        });

    </script>

    <style nonce="123css">
        input[value^="123"] + input {
            border: 1px solid red;
        }
    </style>

</body>
</html>
@mikewest
Copy link
Member

This sounds somewhat similar to https://mikewest.github.io/credentialmanagement/writeonly/, which basically no one but me was interested in. :)

I don't think it's a terrible idea, but it needs a lot more work to be a robust defense. Some of that work we've done for nonces, so reusing it wouldn't be terrible. shrug

@craigfrancis
Copy link
Contributor Author

That would be ideal for this case as well - while I was thinking of read and write protection, if some JS decides to replace the CSRF value (writeonly), it would simply break the validation (as it should).

I suspect most developers weren’t interested because they use JS for everything, but there will be some websites (e.g. banking) where this type of protection would be very useful.

Any thoughts on the second part? Where a response from the server (typically HTML) could include a header to block JS from reading the content.

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

No branches or pull requests

2 participants