The web has evolved from serving simple non-interactive HTML documents to fully branded and dynamic web applications. But what are the risks and costs of downloading and executing foreign code on your PC? Should we use this style of building websites even for blogs?
Client-side scripting vs server-side scripting
Originally web was built with web servers serving static HTML files. To change the content of the served document, a webmaster would upload the new files to the web server from which they were served to visitors browsers and rendered on their screens.
This approach was very limited and more methods of handling of dynamically changing content - often using user-submitted data (User-generated content) - were developed. A Common Gateway Interface specification was defined and used to integrate custom programs (or scripts) running on the server with the web server daemon for it to serve HTML and other media generated on the fly by the script. Later many stand-alone HTTP application server technologies were developed. These application servers would handle the HTTP protocol themselves. Applications hosted this way would usually connect to an SQL database to store and retrieve data for each client request.
All of this can be called server-side scripting and is still the main way to serve dynamic content on the web.
Benefits of running client-side scripting
When you visit a website your browser may be asked by the server to download arbitrary programs and execute them on your computer. This way the web application developer can drive your browser though interactive behaviours without the need to communicate with the server on every click. For certain types of applications, this may reduce the data transferred between your browser and the server. It may let the browser to perform complex actions like drawing images or producing sounds. Also, it could help to avoid potentially lengthy page re-loads.
Another very important factor that made client-side scripting so successful is that browsers are everywhere and offer a relatively standardised programming environment compared to the native operating systems. If you want to write an application that runs on Windows, Linux, Android, iOS and more you can do it with web technologies. You don't have to worry about Apple taking 30% of your subscription revenue or Google blocking you out from Play store, installers on Windows or binary compatibility with Linux's glibc. People don't need to install anything, they just need the URL which they will hopefully discover via a web search engine. All the code, media and dependencies will be downloaded by the browser automatically and transparently.
Browser as an attack target
Today browsers are a very important tool of our daily digital lives. We use them to get informed, communicate with people, do banking and order food. All these activities require private data to be transferred in and out of the browser, and our selves to be authenticated via the browser to various 3rd parties. This makes your browser a valuable target for an attacker.
Common goals of attackers are:
- Session cookie values of other visitors of a website - this allows them to impersonate the visitor (log-in as someone else without even knowing the password!).
- Steal your secrets like credit card details or crypto-currency wallets to later take your money.
- Steal your electricity and CPU power by running crypto miners to monetize on crypto-currency sale.
- Access personal information to later sell it or use it in a fraud against you or your family and friends.
- Post messages from your social media account to spread fake news in your name.
- Create Botnets to attack other targets.
- Install Backdoors, Trojans and other types of malware to use later in other ways.
- Install Ransomware that will encrypt your files until a ransom is paid.
- Deceive you to download and install malicious software.
- Hack your home router via web call to insecure LAN-side management server.
- Use Browser fingerprinting techniques to track you across the internet to build a behavioural profile of you.
- And many more...
Execution of arbitrary code on your computer is not without risks. Web browser designers try very hard to make sure that any script running within the browser is contained and won't be able to access data beyond what browser will allow it to access. In practice, this is impossible to achieve.
In practice, the design and implementation are not perfect. Clever trick may allow script code to access restricted information from the browser or operating system. It may even allow injecting native code to be executed as part of normal browser runtime (Remote Code Execution). This in effect can lead to the compromise of the whole system.
Because of the design of operating systems, an attacker exploiting browser vulnerability (zero-day or e.g. user using old version of the browser) can gain full access to the computer running the browser (user-level access, but gaining administrative access is usually possible). This includes all your information stored on your computer reachable through it.
- Google patches Chrome zero-day under active attacks
- Compromising the macOS Kernel through Safari by Chaining Six Vulnerabilities
- TiYunZong: An Exploit Chain to Remotely Root Modern Android Devices
Hardware isolation bugs
Design issues in web standards
Web standards consist of a large volume of specifications. Sometimes designers make mistakes and properly implemented standards can be abused for malicious purposes.
Some examples of misused standards and attacks are:
- abuse of iframes,
- WebRTC leaks,
- Canvas fingerprinting,
- misguided APIs like Battery Status API,
- abuse of the Notifications API,
- WebSockets allowing for port scanning,
- browser download functionality abused with Drive-by download technique to get your browser to download malicious content,
- and many more...
For some recent examples see:
- How your home router can be hacked from the browser: SOHO Device Exploitation
- How Reddit "hacks" your browser to protect themselves from bots and to track you: Reddit's website uses DRM for fingerprinting
- List of well-known web sites that port scan their visitors
- Apple declined to implement 16 Web APIs in Safari due to privacy concerns
- Web Browsers still allow drive-by-downloads in 2020
- NAT Slipstreaming is a recent attack (as of Nov 2020) that "allows an attacker to remotely access any TCP/UDP services bound to a victim machine, bypassing the victim's NAT/firewall (arbitrary firewall pinhole control), just by the victim visiting a website."
Malicious script delivery vectors
Even if you trust a website to not serve malicious scripts, there are many techniques an attacker can use to get their script served to you without the website owner knowledge.
Ads and ad networks
A typical website will serve ads. Advertiser or advertising network may serve malicious scripts through ads that are part of the website you trust. The website your are visiting is not in control of what scripts are served to your browser - they merely include a script provided by the ad network.
XSS via web cache
Supply chain attack
Security issues in foreign code
Even if your browser is fully patched, a script loaded in it can have security issues on its own. Similarly to supply chain attack code of a third-party dependency of the web application can introduce a weakness in the whole application without the developers knowing about it.
See also: The Curious Case of Copy & Paste.
Hacked web servers
See also: Boing Boing was hacked
Downsides of single-page applications
Single-page applications tend to break some fundamental assumptions on how the web works for the visitor.
On the server-side generated website the navigation can be done via the browsers back button. This is often broken for web application and for some apps it can even log you out if used by "mistake".
Another fundamental feature that easily breaks is the links. A web application often use buttons that trigger some code to run on the browser so you cannot copy the link to the page the button leads to. Similarity bookmarking or sharing links form the browser address bar is pointless as this often stays the same no matter where you are in the app. Also visited links are normally rendered differently on the website so you can see what information you already accessed in the past.
Browsers try to keep scroll positions across going back and forth in history consistent between reloads. This helps you to orient yourself in a long page quickly. Unfortunately when content is dynamically loaded this often breaks. It is very annoying for example when you are browsing products in on-line shops.
This issues can be worked around by some extra code and use of history API but it requires extra work. When using the server-side generated website you get this for free.
For the web developer, on the other hand, the issues are:
- Content of your application cannot be easily archived (e.g. by archive.org).
- Typically all application code needs to be downloaded before it can run which may increase the bounce rate.
- "Generically-designed REST API that tries not to mix "concerns" will produce a frontend application that has to make lots of requests to display a page" - forcing you to join data from multiple tables/API endpoints on the client-side, which is the worst performance-wise place to do it.
- They can be a resource hog for the client where hardware specification is unpredictable.
- Non-interactive websites are easier to test.
See also: Second-guessing the modern web
Web standards are designed in such a way to allow progressive fallback from full HTML + CSS + JS stack through to HTML only without loss of content. Sure your website won't look pretty if you strip it of CSS but it should be readable and functional by default... that is unless you work to break this fallback.
See also: CSS Naked Day.
Use native browser features
Browsers and extensions to help you mitigate the risk
Mozilla has made big mistakes regarding user privacy and is far from perfect in this regards. They are also effectively sponsored by Google even though their many attempts to break free from their monetary influence. But compared to Chrome-based browsers, Firefox has better support for content blockers. This allows extensions like uBlock Origin to block malicious scripts more effectively including first-party trackers compared to similar extensions for Chrome. Google has recently crippled ad-blocking functionality of Chrome extensions while Firefox got built-in tracking protection.
Many browsers derive from either Firefox or Chrome. They come with their trade-offs but may be worth looking into. Currently, I use Fennec on my de-Googled Android phone. Do your research.
Browser extension uBlock Origin does not only block ads and trackers but also malicious scripts like the one used for port scanning. It works well out of the box and requires little configuration. Most websites will work correctly with it enabled. I highly recommend this plugin for anybody unless you want to use more advanced tools like uMatrix.
uMatrix is an advanced browser extension that implements features of uBlock Origin and NoScript combined. To use it though you need to know what you are doing as default settings are very restrictive of what requests your browser is allowed to make.
So if your focus is on running only free software on your computer you may want to look into this extension.
Life beyond HTTP
When you are browsing the internet make sure you use proper tools to stay safe and encourage safe website designs with your choices and feedback.
Updates to this article
- 2020-11-11 - Added note about NAT Slipstreaming