Is there a good browser plugin that tracks changes to sources of js files? That way you could mark certain sources as trusted, but whenever they change, they would be blocked until you mark them as trusted again.
The source doesn't matter, only the content. If the hash of the file matches the hash you've already approved for jquery-3.3, then the file is (unless someone's found a collision in the hashing algorithm that hasn't been disclosed) jquery-3.3.
This would be really neat, and not that hard to build from what I know about building extensions. Basically just store a hash of file, whenever external files are loaded see if their hash exists in your list, if not block it from loading until it's been reviewed.
As an extra (paid-for?) feature hook into an online system that keeps track of hashes of known-good popular libs, and can mark as untrusted when a vulnerability is found with a version of e.g. jQuery and auto-flag that for users.
In Firefox you can turn off updates for individual plugins, so you only need to trust Mozilla and the extension author once.
Chrome is currently looking into getting rid of the ability for extension authors to obfuscate code -- minification is the highest level of obfuscation they'll accept now, and (opinion me) minified Javascript code is not that hard to read. Chrome does still need to get on the "let people turn off automatic updates" train though. But I'm not sure what to tell you about that -- you should not be running Chrome as your main browser anyway if you care about security/privacy.
I'm not sure if Mozilla is planning to follow suite on blocking obfuscation. Assuming they are, if you don't trust the extension author even for the initial download, install the extension, read through the source code natively on your own computer, and then set it to not update after that point.
It would be better if you could download the unminified/unbundled source code and install the extension yourself locally, but for whatever reason Firefox and Chrome have decided that's insecure. I feel the opposite, since requiring signed extensions makes it harder for me to audit code or place additional safeguards around that code, but... eh, what do I know?
In any case, the current situation for extensions on Firefox is not all that different from installing something in a standard software repository.
In Firefox, loading unsigned extensions is severely restricted. It's a separate process to install them, and they'll only last until you restart the browser.
I'm not sure what Chrome's specific rules are; I think they allow loading local sources in dev mode, but warn you about it every time the browser launches? I generally advise people to avoid Chrome if they care about security/privacy anyway, so I've never checked in detail.
But if Chrome does have a way for you to easily load extensions from source, and you're comfortable using it as a main browser, that could be a valid way for you to tackle a problem like this.
It would be a good idea for Chrome to display an alert similar to the non-HTTPS resource loading if integrity checks are not present for externally loaded scripts.
The danger of serving external JS without integrity check its is very similar to having non-HTTPS connections in your website.
Yeah, especially if it's detecting a payment information form, just like they do with passwords atm. They can detect CC forms just fine (with their autocomplete functionality).
I'd also like browsers to do automatic integrity checking - they should be able to have an internal list of signatures, tracking releases of well known libraries.
> It would be a good idea for Chrome to display an alert similar to the non-HTTPS resource loading if integrity checks are not present for externally loaded scripts.
It would just teach users to ignore warnings.
> The danger of serving external JS without integrity check its is very similar to having non-HTTPS connections in your website.
> is very similar to having non-HTTPS connections in your website
I am very into the idea of doing integrity checks on web pages, I think that it's an important direction for the web to move (for multiple reasons) and will improve security a ton. I'd love for browsers to start adding 1st party support for stuff like that; I've even thought about trying to build an extension or something for my own personal use. 100% on board.
But... nah, I don't think these risks are comparable. Removing HTTPS is much more dangerous than shipping code without an integrity check. With an integrity check, you're just checking to see if the code has been changed. Without HTTPS, it's not just the code that could be changed -- anything on the page including your actual requests can be captured and changed. Plus all of your data can be read as well.
With HTTPS, the only fear is that the website itself is compromised. That's a valid fear, but it's so much smaller than the fear that anyone along the entire chain of you to your router to anyone between you and the website server could be compromised.
I think you are missing that, if any external script is compromised, anything in the page can be changed, including the destination of the data you send.
Correct if I'm wrong, but the "action" attribute for a <form> element could be changed to an external location, without having to bypass any cross-origin policy?
Even in that situation though, the only way for an external script to get compromised is for the website serving it to get compromised. With HTTP, it's not just the site that's vulnerable. Maybe you're connecting to an open access point, and someone sitting next to you in the coffee shop is reading your credentials out of thin air. Maybe the router itself is serving malware. Maybe your ISP is compromised, or a random proxy someplace.
Imagine you had a Google doc or a Github repo where 4 or 5 people had access to it. That's potentially a vulnerability, any of those people could change the doc behind your back. And if you don't trust them to keep their accounts secure, maybe someone uses them to sneak something in. It's a very valid concern.
Now imagine you had a Google doc or Github repo with open editing that anyone could connect to at any time and change, without logging any information about their change, or even running a 3rd-party server. That's the difference between being required to trust 3rd-party scripts and connecting to a site without HTTPS.
In your example about bypassing the cross-origin policy, POST requests in general are allowed to be cross-origin by default, so unless you're explicitly blocking that using something like an iFrame, a 3rd-party script can already just send requests directly.
Again, valid vulnerability that's worth being concerned about. But unencrypted web traffic is on a whole nother level. Without HTTPS there's just no mitigation for that vulnerability. Putting the 3rd-party code in an iFrame? I'll just move it out. Setting more restrictive CORS headers? I'll just change them. The difference is that if you're including 3rd-party scripts from sites that you don't trust, there are things you can do to limit their impact. There's nothing you can do to limit what an attacker can do to an unencrypted connection.
>In your example about bypassing the cross-origin policy, POST requests in general are allowed to be cross-origin by default, so unless you're explicitly blocking that using something like an iFrame, a 3rd-party script can already just send requests directly.
Not sure what you're trying to say here, as far as I know CORS is applicable to all HTTP methods except OPTIONS when using Ajax. If you're saying that it's allowed using Forms, then that's allowed for all HTTP methods as we're navigating away from the page.
Agreed, I phrased that poorly. What I mean is that you can send a POST request to any server from a webpage unless the page you're on has taken specific steps to mitigate that attack.
The remote server might have CORS headers set up so that the browser blocks the request. However, in this scenario (stealing payment information) we're talking about an attacker sending data to a remote domain that they control, so you really can't trust that they're going to block third-party AJAX requests to their own domain for their own attack.
To block requests or form actions from your own page, you'd need to explicitly set a CSP header, which isn't something that's on by default. Note that a CSP header does not protect you if you're using HTTP, because I can just turn your CSP header off when I intercept the unencrypted page.
I agree that it should be fixed but we can't know that the cost is going to be small. Some websites are generated via dozens of layers of abtractions and maybe there's no options to add the sri without going deep inside some messy frameworks and changing several of these layers.
Also, “risk acceptance” and “vulnerability” aren't mutually exclusive. Vulnerability is the risk, the acceptance is deciding that the vulnerability is necessary because the cost to avoid or fix it is too high.
But making that choice doesn't stop it from being a vulnerability.
First, the WHATWG is better to finally settle on the hash standard, and produce a final normal standard document. But it being WhatWG, will not do that.
Second, do not ever use 3rd party code served on payment pages, or, even better, have a wholely JS free payment page.
Third, that fact alone that people are using all kinds of js frameworks for super duper critical code, tells of how little concern is given to security there.
Fourth, PciDSS, where are you when we need you? Weren't it already against the rules to allow loading of code from third parties on payment pages???
> Fourth, PciDSS, where are you when we need you? Weren't it already against the rules to allow third party code on payment pages???
No.
You're required to get audited, document certain decisions, and follow some pretty high label 101 level security requirements. You can absolutely use third party libraries on payment pages (source: we do and are PCI certified).
I don't know, but I always had that feeling. Given that they are so paranoid with payment terminals, I thought that online payment pages will be no different.
"Deploy a change-detection
mechanism (for example, file-integrity
monitoring tools) to alert personnel to
unauthorized modification (including
changes, additions, and deletions) of
critical system files, configuration files, or
content files; and configure the software to
perform critical file comparisons at least
weekly."
...
"Examples of files that should be monitored:
• System executables
• Application executables
• Configuration and parameter files
• Centrally stored, historical or archived, log and audit files
• Additional critical files determined by entity (for example,
through risk assessment or other means)."
...
"Note: For change-detection purposes,
critical files are usually those that do not
regularly change, but the modification of
which could indicate a system compromise
or risk of compromise. Change-detection
mechanisms such as file-integrity
monitoring products usually come preconfigured
with critical files for the related
operating system. Other critical files, such
as those for custom applications, must be
evaluated and defined by the entity (that is,
the merchant or service provider)."
> What's especially annoying about this, is that the CDNJS website has a "one-click copy" for SRI.
Actually, from the screenshot it's clearly "two-click" and "one-click" provides a link without SRI. Obviously the vast majority of people in a rush are going to use the "one-click" option, secure or not.
There's no reason why the SRI option shouldn't be default on CDNJS when the URL is specifying a specific version.
Don't trust consumers to be competent, help them out with good UI patterns. We should be advocating default = secure here.
Leaving no room for them to screw it up is always a good option. I know (some) Junior (or really any) devs don't always consider security at all, so they will take the quickest option even if it's wrong or insecure, so long as it "works".
> If you absolutely have to load someone else's code, check to see if it has been altered.
Third party JavaScript code can be altered for legitimate reasons. e.g. adding new features, refactoring, security fixes, etc. In order to prevent a site which uses SRI from breaking every time a 3rd party makes an update to a js file, 3rd parties should version their JavaScript resources with a version number in the URL. This, of course, places the added burden on the site that uses the 3rd party JavaScript resource. They need to update the version number in the URL and update the SRI every time the 3rd party releases an update. And this should be a manual process because automating it would defeat the whole point of SRI.
It's because that can break the site due to the browser's sandbox permissions model. Scripts are only allowed to make ajax calls to their origin servers. Also, serving a 3rd party script from the 1st party's domain gives the 3rd party permission to make ajax calls to the 1st party domain, which may open up security holes.
You are totally right, but I'm wondering if we shouldn't change this practice. I'm starting to think if you're making a call to an external service, it should be proxied through your network.
It'd increase bandwidth/latency, but you can be assured that the network calls your page are making are hitting the correct 3rd parties, and even inspect to see that the payloads are "correct".
Edit: Surely, this at the very least should be the case for payment pages and banking websites.
To the second point, I was thinking of checking what came over the wire after AJAX calls from 3rd party JS (which may or may not have been loaded with SRI).
I'll have to concede the first point... I was thinking that you can whitelist entire URLs to be fetched as opposed to domains, but on second thought, I don't think that'd be a meaningful change.
Thanks, this has made me think a lot more on this, however :)
> Also, serving a 3rd party script from the 1st party's domain gives the 3rd party permission to make ajax calls to the 1st party domain, which may open up security holes.
What do you mean? The 3rd script served from 3rd party domain will still execute under 1st party domain in the client's browser and that's the origin that the server sees. It doesn't prevent the scripts from calling 1st party server.
If a 3rd party's script loaded from the 3rd party domain initiates any execution on its own (without being invoked by script on the 1st party's site), it won't have permissions to make calls to the 1st party's domain. Moving the 3rd party script to the 1st party domain opens this up.
Update: Given the responses, I'm starting to think I might be incorrect on this point. I'll admit, I'm working from memory here. I'll have to go back and validate this.
I have never heard of this. Can you share a link that goes into detail about this behavior? I don't immediately see anything on MDN's same-origin page talking about it
I'm 99% sure this is not a thing and if it was it would be incredibly broken and not secure and most non-trivial pages relying on it for security would be vulnerable to the third party script.
Anyway. This can easily be proved one way or another. `Here is an example that shows a third party script accessing a first party domain. There is no CORs as far as I can see:
I very strongly doubt this is part of the browsers same origin model. Basically, this is only secure under the assumption that the third party script can't trick the first party script into invoking it by modifying its state since the third party script and the first party script both share the same global namespace.
Lets see how this is broken when jquery is running as a first party script.
1. third party script calls $(document).on("..", function() {})
2. event executes which causes jquery to invoke a function in the third party script
3. third party script can now make a request to the 1st party origin bypassing the 'sandbox'
ok.. so maybe the browser tries to 'secure' against this attack by marking event listeners as either having a 'good' stack or a 'bad' stack. in this case when the third party script does $(document).on() it would be identified as 'bad' stack and couldn't then make the http request because the browser would see <bad stack> at the start of the event chain.
but this can still be worked around:
1. third party script calls $(document).on("event", ".selector", function() {}) after 1st party script had already set a listener on document (not an abnormal thing)
2. event happens and now it is run with 'good' stack because jquery uses a shared event handler and the event handler was originally registered with 'good' stack by the first party script. (the bad script doesn't even have to use the 'live' style. i suspect jquery shares event handlers for the same element so they would just need to try to add an event handler to an element that already has a jquery event handler)
there can be no security between scripts that share the same global state.
I don't think this is true. I just tried to replicate it with 2 different hostsnames pointing to 127.0.0.1 in my /etc/hosts. js loaded from origin2.foo on a page with an origin of origin1.foo can XHR things from origin1.foo, but not from origin2.foo.
Interestingly, MDN leads the article on same-origin policy with this sentence:
The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin.
This seems to support the way that OP described how SOP works.
> 3rd parties should version their JavaScript resources with a version number in the URL
I mean yes this is true, but it seems almost totally orthogonal to SRI (which is aimed at security AIUI), particularly given you can give more than one hash for a particular resource. If for some reason a third-party can't use fingerprinted URLs, they can still update the resource provided they give "sufficient" advanced notification of the new fingerprint to clients.
> And this should be a manual process because automating it would defeat the whole point of SRI.
Obviously it should be offline/write-once, but unless you're reviewing the actual assets as well I'm not sure I see the need to avoid automation.
Without versioned assets, both the 3rd and 1st parties would need to make the update at the exact same time or else the enforced SRI would cause failures. This kind of tight coordination is impractical or even impossible. Versioned assets allow you to deploy updates when using SRI without breaking anything.
The need to avoid automation stems from the fact that an automated process which simply detects that a change has been made and blindly updates the SRI attribute with a new hash would let a malicious code update through, which normally SRI would have blocked. This situation is no different than not using SRI at all.
It's for reasons like this that I recommend uMatrix for Firefox [0] and Chrome [1]. It's default function is to block scripts that don't belong to the root domain of the site you're visiting, and you can whitelist 3rd-Party domains by asset type on the fly from a dialogue.
It's really handy for eliminating dodgy dependencies, and it doesn't break half as many sites as NoScript.
uMatrix is great because it doesn't just block scripts. You can block iframes, images, etc... You can also turn off stuff like webworkers. It's not perfect (I've noticed a few holes around how it manages cookies, for example), but it's really good.
Removing scripts is nice, but if you're trying to prevent obscure attacks[0] or even common tracking techniques from 3rd-party sites, it's not enough. People look at Javascript like it's the primary insecurity on the web; in reality any time you can conditionally make a request to a server for any reason from anywhere, that's a vulnerability.
So with uMatrix you don't just get the ability to say, "don't run scripts", you get the ability to conditionally and granularly blacklist/whitelist domains themselves.
> Despite being a tofu-knitting member of the bourgeoisie, I am yet to subscribe to teh Gruan. If I did, I'd risk their affiliate tracker going rogue and stealing my organic credit card details.
How do people here feel about a website including 3rd party JavaScript from their payment processor or bank on the payment page? This article mentions Adyen JavaScript being included, but that seems fine here?
As I said, it is probably fine. But it does introduce yet another small risk. Perhaps the best solution is to just send a user to the payment provider rather than keeping them on your site.
What are the repercussions if Adyen was hacked in this case? Would they be able to steal session cookies for the user's account on Spotify? Something else malicious?
I wonder if SRI management could be done at the browser/plugin/unblock level? Ie block the loading of a script if the content hash different from the last time it was loaded.
> "SRI has been available for two years and it still isn't being used enough."
Two years is relatively fresh. There's probably a significant amount of customers with browsers that don't support this.
Can't we just implement a simple poor-man's SRI ourselves? Download the 3rd-party script, hash it, check hash, proceed to exec() if all is well? This should be supported by much older browsers.
I ALWAYS run 3rd party JavaScript on my payments page. That's what Stripe is, after all.
In this blog post the author identifies probably 1 questionable third party resource. As scary as it sounds it's not exactly easy to just compromise major JS providers and start stealing cc data. It's possible but instances of it happening are extremely rare.
Knowing what you're loading is more important than not loading anything. It's not realistic to expect no third party js in today's world, and even versioning+SRI has issues because it solves one problem by creating a new one.
I think they point they're trying to make is that there's no guarantee the script you get isn't hacked unless you use SRI. The focus isn't on third-party javascript, but un-secured javascript.
One problem with SRI and locking down your version of a third party JavaScript library is you won't get security updates the third party makes to that library until you manually update your link. Another issue is third parties don't offer versioned links at all so SRI will prevent the link from loading when the library code is updated.
What's the best solution to this? Expecting every website owner to manually review and approve each library version update has problems too and you have to be realistic in accepting most website owners aren't going to be constantly reviewing their libraries.
Why is there no mechanism to allow a JavaScript bundle to be signed so we can be more confident the original developer made the modification like we do in other ecosystems?
Are there ways you could add more sandboxing to scripts to limit their potential damage? Iframes let you do this (i.e. so scripts can't modify or read the outer page) to an extent for some scenarios.
Indeed, to comply with PCI-DSS v3.2.1, requirement 6.1 you must "Establish a process to identify security vulnerabilities, using reputable outside sources for security vulnerability information", and requirement 6.2 you must "Ensure that all system components and software are protected from known vulnerabilities by installing applicable vendor supplied security patches."
So you need to have an inventory of all vendor supplied software and hardware, monitor for security advisories from those vendors, and have an adequate change management process to respond to those advisories in a timely fashion.
> So responsible site owners are already testing and approving version changes.
I'm not saying it's not possible, I'm asking how it could be made easier and for sites in general, not just payment websites. The more resources something takes, the less developers that are going to do it so the web will be less secure.
Everything great and bad about JavaScript can be explained by a simple facet of human behavior and one simple principle of technology.
JavaScript has a low barrier of entry, which means you don't have to be incredibly competent to write code or get hired to write code. It also means a novice with incredible potential could eventually learn to build great things in the language.
An interesting phenomenon of human behavior is that people cannot practice charity and profit simultaneously (altruism versus egoism). It is a forced dichotomy. You have to choose and there is no middle ground. This forced choice is present even when the environment, incentives, and stimulus allow for both. This is long observed in scientific philosophy, but there is also a fair amount of behavioral health research on this as well.
These factors could explain, even when normalizing for hours of practice, why open source practitioners may develop more skill and interest than developers limiting their practice to employment contributions. It might also explain why code in commonly despised fields, such as online advertising or e-commerce checkout platforms, are so incredibly awful and negligent.
> An interesting phenomenon of human behavior is that people cannot practice charity and profit simultaneously (altruism versus egoism). It is a forced dichotomy. You have to choose and there is no middle ground. This forced choice is present even when the environment, incentives, and stimulus allow for both. This is long observed in scientific philosophy, but there is also a fair amount of behavioral health research on this as well.
This may be common but it's not an absolute. There is a middle ground, you can profit without exploiting anyone, for the definition "use [someone or something] in an unfair or selfish way". The trick is to exploit using the definition "make full use of and derive benefit from", and making full use of anyone's talents and skills always includes improving their morale, which is mutually exclusive with being a selfish or greedy company.
I am so old school, but I only use local installation of 3rd party tools and libraries. That means I have to update them, but that also means that no hidden update will break my site or worse, introduce vulnerabilities.
94 comments
[ 2.9 ms ] story [ 164 ms ] threadAs an extra (paid-for?) feature hook into an online system that keeps track of hashes of known-good popular libs, and can mark as untrusted when a vulnerability is found with a version of e.g. jQuery and auto-flag that for users.
Chrome is currently looking into getting rid of the ability for extension authors to obfuscate code -- minification is the highest level of obfuscation they'll accept now, and (opinion me) minified Javascript code is not that hard to read. Chrome does still need to get on the "let people turn off automatic updates" train though. But I'm not sure what to tell you about that -- you should not be running Chrome as your main browser anyway if you care about security/privacy.
I'm not sure if Mozilla is planning to follow suite on blocking obfuscation. Assuming they are, if you don't trust the extension author even for the initial download, install the extension, read through the source code natively on your own computer, and then set it to not update after that point.
It would be better if you could download the unminified/unbundled source code and install the extension yourself locally, but for whatever reason Firefox and Chrome have decided that's insecure. I feel the opposite, since requiring signed extensions makes it harder for me to audit code or place additional safeguards around that code, but... eh, what do I know?
In any case, the current situation for extensions on Firefox is not all that different from installing something in a standard software repository.
Do you mean for a proprietary extension? AFAIK loading sources locally works fine in chrome.
I'm not sure what Chrome's specific rules are; I think they allow loading local sources in dev mode, but warn you about it every time the browser launches? I generally advise people to avoid Chrome if they care about security/privacy anyway, so I've never checked in detail.
But if Chrome does have a way for you to easily load extensions from source, and you're comfortable using it as a main browser, that could be a valid way for you to tackle a problem like this.
The danger of serving external JS without integrity check its is very similar to having non-HTTPS connections in your website.
I'd also like browsers to do automatic integrity checking - they should be able to have an internal list of signatures, tracking releases of well known libraries.
It would just teach users to ignore warnings.
> The danger of serving external JS without integrity check its is very similar to having non-HTTPS connections in your website.
No, it's not similar at all.
/s
The wonderful web as we used to know it has devolved into a pretty sad thing (and web-developers with it).
I am very into the idea of doing integrity checks on web pages, I think that it's an important direction for the web to move (for multiple reasons) and will improve security a ton. I'd love for browsers to start adding 1st party support for stuff like that; I've even thought about trying to build an extension or something for my own personal use. 100% on board.
But... nah, I don't think these risks are comparable. Removing HTTPS is much more dangerous than shipping code without an integrity check. With an integrity check, you're just checking to see if the code has been changed. Without HTTPS, it's not just the code that could be changed -- anything on the page including your actual requests can be captured and changed. Plus all of your data can be read as well.
With HTTPS, the only fear is that the website itself is compromised. That's a valid fear, but it's so much smaller than the fear that anyone along the entire chain of you to your router to anyone between you and the website server could be compromised.
Correct if I'm wrong, but the "action" attribute for a <form> element could be changed to an external location, without having to bypass any cross-origin policy?
Imagine you had a Google doc or a Github repo where 4 or 5 people had access to it. That's potentially a vulnerability, any of those people could change the doc behind your back. And if you don't trust them to keep their accounts secure, maybe someone uses them to sneak something in. It's a very valid concern.
Now imagine you had a Google doc or Github repo with open editing that anyone could connect to at any time and change, without logging any information about their change, or even running a 3rd-party server. That's the difference between being required to trust 3rd-party scripts and connecting to a site without HTTPS.
In your example about bypassing the cross-origin policy, POST requests in general are allowed to be cross-origin by default, so unless you're explicitly blocking that using something like an iFrame, a 3rd-party script can already just send requests directly.
Again, valid vulnerability that's worth being concerned about. But unencrypted web traffic is on a whole nother level. Without HTTPS there's just no mitigation for that vulnerability. Putting the 3rd-party code in an iFrame? I'll just move it out. Setting more restrictive CORS headers? I'll just change them. The difference is that if you're including 3rd-party scripts from sites that you don't trust, there are things you can do to limit their impact. There's nothing you can do to limit what an attacker can do to an unencrypted connection.
Not sure what you're trying to say here, as far as I know CORS is applicable to all HTTP methods except OPTIONS when using Ajax. If you're saying that it's allowed using Forms, then that's allowed for all HTTP methods as we're navigating away from the page.
The remote server might have CORS headers set up so that the browser blocks the request. However, in this scenario (stealing payment information) we're talking about an attacker sending data to a remote domain that they control, so you really can't trust that they're going to block third-party AJAX requests to their own domain for their own attack.
To block requests or form actions from your own page, you'd need to explicitly set a CSP header, which isn't something that's on by default. Note that a CSP header does not protect you if you're using HTTP, because I can just turn your CSP header off when I intercept the unencrypted page.
"This appears to be more of a risk acceptance rather than a vulnerability."
I understand that some risk is acceptable but surely that is proportional to the cost of removing the risk and in this case that cost is so small.
But making that choice doesn't stop it from being a vulnerability.
Second, do not ever use 3rd party code served on payment pages, or, even better, have a wholely JS free payment page.
Third, that fact alone that people are using all kinds of js frameworks for super duper critical code, tells of how little concern is given to security there.
Fourth, PciDSS, where are you when we need you? Weren't it already against the rules to allow loading of code from third parties on payment pages???
No.
You're required to get audited, document certain decisions, and follow some pretty high label 101 level security requirements. You can absolutely use third party libraries on payment pages (source: we do and are PCI certified).
Which specific part of PCI do you feel third party libraries violates?
Several recent breakins at major retailers have been directly against payment terminals.
"Deploy a change-detection mechanism (for example, file-integrity monitoring tools) to alert personnel to unauthorized modification (including changes, additions, and deletions) of critical system files, configuration files, or content files; and configure the software to perform critical file comparisons at least weekly."
...
"Examples of files that should be monitored: • System executables • Application executables • Configuration and parameter files • Centrally stored, historical or archived, log and audit files • Additional critical files determined by entity (for example, through risk assessment or other means)."
...
"Note: For change-detection purposes, critical files are usually those that do not regularly change, but the modification of which could indicate a system compromise or risk of compromise. Change-detection mechanisms such as file-integrity monitoring products usually come preconfigured with critical files for the related operating system. Other critical files, such as those for custom applications, must be evaluated and defined by the entity (that is, the merchant or service provider)."
Actually, from the screenshot it's clearly "two-click" and "one-click" provides a link without SRI. Obviously the vast majority of people in a rush are going to use the "one-click" option, secure or not.
There's no reason why the SRI option shouldn't be default on CDNJS when the URL is specifying a specific version. Don't trust consumers to be competent, help them out with good UI patterns. We should be advocating default = secure here.
Leaving no room for them to screw it up is always a good option. I know (some) Junior (or really any) devs don't always consider security at all, so they will take the quickest option even if it's wrong or insecure, so long as it "works".
All the SRI, CSP, etc is great, but if you can't control your own site you're screwed regardless.
Third party JavaScript code can be altered for legitimate reasons. e.g. adding new features, refactoring, security fixes, etc. In order to prevent a site which uses SRI from breaking every time a 3rd party makes an update to a js file, 3rd parties should version their JavaScript resources with a version number in the URL. This, of course, places the added burden on the site that uses the 3rd party JavaScript resource. They need to update the version number in the URL and update the SRI every time the 3rd party releases an update. And this should be a manual process because automating it would defeat the whole point of SRI.
It'd increase bandwidth/latency, but you can be assured that the network calls your page are making are hitting the correct 3rd parties, and even inspect to see that the payloads are "correct".
Edit: Surely, this at the very least should be the case for payment pages and banking websites.
The browser's sandbox security model already does this for us with the same origin policy.
> ... and even inspect to see that the payloads are "correct".
This is what SRI already does for us.
I'll have to concede the first point... I was thinking that you can whitelist entire URLs to be fetched as opposed to domains, but on second thought, I don't think that'd be a meaningful change.
Thanks, this has made me think a lot more on this, however :)
What about the millions of sites that load jQuery from a CDN and then use $.ajax() to make requests to their home domain?
What do you mean? The 3rd script served from 3rd party domain will still execute under 1st party domain in the client's browser and that's the origin that the server sees. It doesn't prevent the scripts from calling 1st party server.
Update: Given the responses, I'm starting to think I might be incorrect on this point. I'll admit, I'm working from memory here. I'll have to go back and validate this.
Anyway. This can easily be proved one way or another. `Here is an example that shows a third party script accessing a first party domain. There is no CORs as far as I can see:
https://jsfiddle.net/aopmtn46/
If you open the console you will see "STATUS 404" which is not possible if same origin on third party scripts is enforced.
Lets see how this is broken when jquery is running as a first party script.
ok.. so maybe the browser tries to 'secure' against this attack by marking event listeners as either having a 'good' stack or a 'bad' stack. in this case when the third party script does $(document).on() it would be identified as 'bad' stack and couldn't then make the http request because the browser would see <bad stack> at the start of the event chain.but this can still be worked around:
there can be no security between scripts that share the same global state.Interestingly, MDN leads the article on same-origin policy with this sentence:
The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin.
This seems to support the way that OP described how SOP works.
I mean yes this is true, but it seems almost totally orthogonal to SRI (which is aimed at security AIUI), particularly given you can give more than one hash for a particular resource. If for some reason a third-party can't use fingerprinted URLs, they can still update the resource provided they give "sufficient" advanced notification of the new fingerprint to clients.
> And this should be a manual process because automating it would defeat the whole point of SRI.
Obviously it should be offline/write-once, but unless you're reviewing the actual assets as well I'm not sure I see the need to avoid automation.
The need to avoid automation stems from the fact that an automated process which simply detects that a change has been made and blindly updates the SRI attribute with a new hash would let a malicious code update through, which normally SRI would have blocked. This situation is no different than not using SRI at all.
1. Provider informs clients that a new version with digest X will be deployed.
2. Clients add the new digest in addition to the current digest.
3. Provider switches to new asset version.
4. Clients remove old digest (optional).
Versioned assets are obviously better unless you're in a really weird situation, but SRI doesn't particularly require them.
It's really handy for eliminating dodgy dependencies, and it doesn't break half as many sites as NoScript.
[0] https://addons.mozilla.org/en-US/firefox/addon/umatrix/ [1] https://chrome.google.com/webstore/detail/umatrix/ogfcmafjal...
Removing scripts is nice, but if you're trying to prevent obscure attacks[0] or even common tracking techniques from 3rd-party sites, it's not enough. People look at Javascript like it's the primary insecurity on the web; in reality any time you can conditionally make a request to a server for any reason from anywhere, that's a vulnerability.
So with uMatrix you don't just get the ability to say, "don't run scripts", you get the ability to conditionally and granularly blacklist/whitelist domains themselves.
[0]: https://www.mike-gualtieri.com/posts/stealing-data-with-css-...
> Despite being a tofu-knitting member of the bourgeoisie, I am yet to subscribe to teh Gruan. If I did, I'd risk their affiliate tracker going rogue and stealing my organic credit card details.
SCP covers dynamically loaded scripts also, which should provide more security than SRI.
Specifically script-src: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Co...
To many acronyms, my mind was probably thinking about SICP - https://mitpress.mit.edu/sites/default/files/sicp/index.html
Two years is relatively fresh. There's probably a significant amount of customers with browsers that don't support this.
Can't we just implement a simple poor-man's SRI ourselves? Download the 3rd-party script, hash it, check hash, proceed to exec() if all is well? This should be supported by much older browsers.
In this blog post the author identifies probably 1 questionable third party resource. As scary as it sounds it's not exactly easy to just compromise major JS providers and start stealing cc data. It's possible but instances of it happening are extremely rare.
Knowing what you're loading is more important than not loading anything. It's not realistic to expect no third party js in today's world, and even versioning+SRI has issues because it solves one problem by creating a new one.
Why it's not supported on "iOS Safari"...
What's the best solution to this? Expecting every website owner to manually review and approve each library version update has problems too and you have to be realistic in accepting most website owners aren't going to be constantly reviewing their libraries.
Why is there no mechanism to allow a JavaScript bundle to be signed so we can be more confident the original developer made the modification like we do in other ecosystems?
Are there ways you could add more sandboxing to scripts to limit their potential damage? Iframes let you do this (i.e. so scripts can't modify or read the outer page) to an extent for some scenarios.
So responsible site owners are already testing and approving version changes.
So you need to have an inventory of all vendor supplied software and hardware, monitor for security advisories from those vendors, and have an adequate change management process to respond to those advisories in a timely fashion.
All of that needs to be auditable.
I'm not saying it's not possible, I'm asking how it could be made easier and for sites in general, not just payment websites. The more resources something takes, the less developers that are going to do it so the web will be less secure.
JavaScript has a low barrier of entry, which means you don't have to be incredibly competent to write code or get hired to write code. It also means a novice with incredible potential could eventually learn to build great things in the language.
An interesting phenomenon of human behavior is that people cannot practice charity and profit simultaneously (altruism versus egoism). It is a forced dichotomy. You have to choose and there is no middle ground. This forced choice is present even when the environment, incentives, and stimulus allow for both. This is long observed in scientific philosophy, but there is also a fair amount of behavioral health research on this as well.
These factors could explain, even when normalizing for hours of practice, why open source practitioners may develop more skill and interest than developers limiting their practice to employment contributions. It might also explain why code in commonly despised fields, such as online advertising or e-commerce checkout platforms, are so incredibly awful and negligent.
This may be common but it's not an absolute. There is a middle ground, you can profit without exploiting anyone, for the definition "use [someone or something] in an unfair or selfish way". The trick is to exploit using the definition "make full use of and derive benefit from", and making full use of anyone's talents and skills always includes improving their morale, which is mutually exclusive with being a selfish or greedy company.
That is not a middle ground. It is one of two classes of motivations. Profit does not imply exploitation, manipulation, or any form of dishonesty.
It's not Google/CDN part to support SRI - its the browser itself