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

Should Svelte/SvelteKit expose which versions are running? #8636

Closed
Rich-Harris opened this issue May 25, 2023 · 41 comments · Fixed by #8761
Closed

Should Svelte/SvelteKit expose which versions are running? #8636

Rich-Harris opened this issue May 25, 2023 · 41 comments · Fixed by #8761

Comments

@Rich-Harris
Copy link
Member

Rich-Harris commented May 25, 2023

Context

Tools like Wappalyzer use heuristics to determine which technologies are used on a given page. Some of them can be a bit brittle. For example Svelte is detected via the svelte- CSS scoping classname prefix...

"dom": "[class*='svelte-']"

...which only works for apps that use Svelte's built-in CSS scoping (rather than, say, Tailwind). This mechanism is also subject to change in future, at which point the heuristic will fail.

There's also no way to know which version of Svelte (or SvelteKit) is running. This information is potentially useful (hypothetical use cases: devtools, tracking the speed of adoption of new versions, reaching out to sites that are running a version with a known vulnerability) and, in fact, the CWV tech report plans to add version information to the report in future. Currently, Svelte is systematically underrepresented in reports of technology usage, and will be excluded altogether from these more granular reports.

The question under discussion here is whether Svelte and SvelteKit should expose information about whether they're being used on a given page, and if so, whether they should expose which versions are in use.

Security and privacy

Of course, exposing version information provides potential attackers with information about which sites to target, if a version with a known vulnerability exists. Having said that, both client-side libraries and servers have been exposing version information for many years (see e.g. a default Apache 404 page, or log _.VERSION on any site running Underscore), and to my knowledge this isn't a practice that's frowned upon.

If we do deem granular version information to be too sensitive, then there are alternatives (which might differ between Svelte and SvelteKit — for example we could provide major/minor/patch for Svelte but only major for SvelteKit):

  • expose nothing
  • expose a boolean ('this site is running some version of Svelte/SvelteKit')
  • expose a major version ('this site is running Svelte 4 and SvelteKit 2')
  • expose major/minor
  • expose major/minor/patch

Crucially, an explicit mechanism (as opposed to a heuristic based on implementation details) can have an opt-out mechanism, so exposing the boolean is arguably more privacy/security conscious than the status quo (and certainly not less).

For this to be at all useful, it would have to be opt-out rather than opt-in.

Implementation

For Svelte, we could add something like this to an internal module...

// svelte/internal/tracking.js
(window.__svelte_versions ??= []).push(VERSION);

...and then import that module in every compiled component (unless the compiler were configured to opt out):

import 'svelte/internal/tracking';

For SvelteKit, it would be natural to use the <meta name="generator"> tag, which is used by things like Wordpress:

<meta name="generator" content="SvelteKit 1.20.0">

Should we do this?

The consensus among maintainers was that exposing a boolean (with an opt-out) for both Svelte and SvelteKit would make sense, since it would simply be a more reliable and privacy-forward version of existing detection mechanisms. We're undecided about whether or not we should expose version information, however.

It's important to us that decisions like these happen with the community's consent and consultation, so we'd very much welcome your thoughts on this question.

This post has been edited, so the first couple of replies might not make much sense

@Rich-Harris Rich-Harris added this to the 4.x milestone May 25, 2023
@Conduitry
Copy link
Member

I'm not jazzed about this. Where would this go? As one-time top-level code in svelte/internal? Would there be any way to opt out of it?

@Rich-Harris
Copy link
Member Author

As one-time top-level code in svelte/internal? Would there be any way to opt out of it?

If it was a compiler option like track: false then we could default to importing svelte/internal/track or something, which contains that line, but let people opt out

@irishburlybear
Copy link

irishburlybear commented May 26, 2023

If you want this it should be reversed. Opt everyone out. Let everyone know about it, have them decide to turn it on via a "do this for me, please ad campaign". It wouldn't hurt to maybe have a little carrot dangling on the other side. I do not know what that carrot would be. Maybe another feature of some sorts. I know this isn't the most powerful route. But. It is the most(ish) honorable / transparent.

@Rich-Harris Rich-Harris changed the title Enable Svelte version detection Should Svelte/SvelteKit expose which versions are running? May 26, 2023
@sbyware
Copy link

sbyware commented May 26, 2023

As a professional Pen. Tester / Red Team Operator, being able to view the SK ver. no. is a big thing, as it presents a more broad attack surface given the presence of (previously patched) vulnerability becoming exploitable due to a potentially out of date version of SK.

I say hide it, that's my two cents. It provides no usage to the end user so.

@ahme-dev
Copy link

ahme-dev commented May 26, 2023

@irishburlybear Don't other frameworks already expose that the site is running them by default? I don't see why Svelte doing it would not be quite honorable.

So, yes. I think the boolean with an opt-out is good.

@brandonmcconnell
Copy link
Contributor

My initial thought was that something like this should def be an opt-in setting, but I see how that would remove most of the value here.

I guess the main thought I have is— what are the main downsides to doing this? Vulnerabilities if certain versions of Svelte/SvelteKit are exposed to be vulnerable to SSR attacks somehow? If that's not an issue and there isn't any risk involved, I don't immediately see any glaring issues with this, maybe exposing via the JS prop.

If there is risk, I wonder if there would be some sort of way to encrypt/hash it in a way that the svelte team can interpret but cannot be interpreted easily otherwise.

@korywka
Copy link

korywka commented May 26, 2023

Isn't that a gift for vulnerabilities scanners?

@SarcevicAntonio
Copy link
Member

SarcevicAntonio commented May 26, 2023

Security by obscurity is generally not the way, but it does have some value here‽

I'd say expose usage of Svelte/Kit for everyone, version as opt in to be on the safe side.

@samal-rasmussen
Copy link

samal-rasmussen commented May 26, 2023

If you want this it should be reversed. Opt everyone out. Let everyone know about it, have them decide to turn it on via a "do this for me, please ad campaign". It wouldn't hurt to maybe have a little carrot dangling on the other side. I do not know what that carrot would be. Maybe another feature of some sorts. I know this isn't the most powerful route. But. It is the most(ish) honorable / transparent.

There's no reason to have this at all if it is opt in. Too few would use it, so it wouldn't be useful for statistics.

@TGlide
Copy link
Member

TGlide commented May 26, 2023

I'd say stick with exposing a boolean. Exposing the version has much more to lose than to gain

@lucianoratamero
Copy link

also, if they could detect sveltekit apps using the css selector, is there a native and easy way to change the prefix for generated css classes?
because having a boolean for exposing the version sounds nice, but without having an option to change the prefix, it wouldn't be a complete solution, imo.

@paoloricciuti
Copy link
Member

I think this can be beneficial and I'm with you guys to expose the boolean to prevent exposing potentially old and prepatched versions of websites.

@korywka
Copy link

korywka commented May 26, 2023

devtools

So svelte can expose version only in dev mode

tracking the speed of adoption

Sounds like a feature request for npm package statistics (afaik github packages do this)

Tools like Wappalyzer

Let's do not make Wappalyzer's work boring 🙂

@dominikg
Copy link
Member

is there a native and easy way to change the prefix for generated css classes?

https://svelte.dev/docs#compile-time-svelte-compile

compileOptions: {
  cssHash:({hash,css}) =>`yourprefixhere-${hash(css)}`
}

Beware:
you absolutely must return a value that is unique to the component style, otherwise you would horribly break scoping. so the hash(css) part is not optional. It must also be a string usable as css class.

So yes there is, but it hash strings attached.

@paoloricciuti
Copy link
Member

devtools

So svelte can expose version only in dev mode

tracking the speed of adoption

Sounds like a feature request for npm package statistics (afaik github packages do this)

Tools like Wappalyzer

Let's do not make Wappalyzer's work boring 🙂

I think what they mean by devtools is the ability to know which svelte version is running in prod for some devtools. Other than that obviously is their will to ease as much as possible the tools that tracks usage: some people rely on those tools to justify the choosing of a framework so slow those numbers down can actually hurt the framework ecosystem... it's not just a vanity badge...also it's not like they don't track those things already...they are just much more likely to do it wrong. What's the reasoning for not wanting them to know if a website is built with svelte?

@LorisSigrist
Copy link

Exposing a boolean seems like the right choice here, especially if it's opt-out. It gives most of the benefits of exposing technology & version information, but without giving much information away that could be used maliciously in case of a security vulnerability. It's most wise to be a bit conservative here in what is exposed.

If a major version change actually warrants exposing more detailed information more can always be exposed, but currently I don't really see the use-case for fine-grained version information.

If people do need to expose more detailed version information (maybe because their crashlytics benefit from it), they can always just add their own <meta name="generator" content="SvelteKit x.y.z" />. Having a standard format for doing this would be nice though.

I really appreciate that you are discussing this publicly btw.

@plutoniumm
Copy link

plutoniumm commented May 26, 2023

There's no reason to have this at all if it is opt in. Too few would use it for it, so it wouldn't be useful for statistics.

As a (former) security person I would say exposing any information at all about the build system is bad since it saves me a lot of time in checking the potential attack surface. The idea should be to remove as much information as possible to slow down adversaries

A middle route could be say have it opt-in only and then tell people that it has been set to false by default by showing it in the vite config

config = {
// ... other stuff
compiler: {
  track: false // expose svelte ver info in build
  }
}

The potential problems with this are

  1. It doesn't really solve the people not opting in issue by a lot, its only MARGINALLY better
  2. It opens a big floodgate into letting the config be infinitely complicated in the future, I would personally have it be as minimal as possible for a template so that beginners have less to worry about. The middle-middle route here could be to have it in specific templates which are let's say the detailed ones

The counter-argument to the security issue could be that since svelte is a compiler closer to the HTML type stuff its safe to expose even the patch version for that since the probability that there would be a critical security vulnerability in there is close to 0. The issue might really be in exposing the Kit version since that has more server side stuff. (Its effectively like if I knew the Express/NGNIX version of a certain backend)

@Antonio-Bennett
Copy link

Antonio-Bennett commented May 26, 2023

I believe the major version should be good. Might be useful for performance tracking over different versions or something like that blog post Astro did. Just a Boolean is perfectly fine too though

@SarcevicAntonio
Copy link
Member

Now I'm on the fence... This ain't a trivial decision 😄
How about major version always, and the exact version behind an opt-in flag?

@JeffLoucks
Copy link

I'm cool with the bool. Anything more makes me a little nervous 😬.

@pyronaur
Copy link

pyronaur commented May 26, 2023

If it's opt-in, then what value does it provide in terms of being able to tell what percentage of sites out there are SvelteKit? The data is going to be unreliable. WordPress, for example, is really easy to detect with pretty high confidence.

On the other hand, I don't want it to be opt-in-by-default for some reason either.

And the transition period is interesting too - vulnerability scanners can look for "is it a version pre- #8636 was released" down the line.

No strong opinions on this from me, but this is really, tricky, mostly I'm just thinking about what value this adds if the usage data is unreliable anyway.

@iltimasd
Copy link

iltimasd commented May 26, 2023

expose major/minor/patch. hiding that an app is behind on a security update, doesnt change the fact that the vuln is still there. fwiw, looks like next is exposing the version pretty granularly (only checked my vercel dashboard where window.next returns {version: '13.4.4-canary.11', emitter: {…}}.

opt-out is good for those who are being told be stakeholders to suppress that info

@0gust1
Copy link

0gust1 commented May 26, 2023

(personal opinion)

I would say: opt-in, with nothing/hidden as default. I have seen too much http logs with scanners targeting specific/explicit strings of versions of softwares to be at ease with a full opt-out behavior.
If compromise needed, I would be ok with an opt-out boolean (rendering to "Svelte"/"SvelteKit") and opt-in for the rest.

Svelte/Sveltekit does already an awesome job pushing web good practices as default behavior (a11y, semantic HTML, etc.). Don't fall for the clout-chasing (even if, as a Svelte afficionado, I would be very happy to see growing stats). On my own website, I would opt-in for all.

But I'm thinking about the average non-dev/non-engineer person that will install SvelteKit for its own website or the website of its uncle/aunt (like he/she would do with wordpress, in my mind, it's an adequate comparison imho). Lot of people just want to make a website and install things to get the job done, and forget later to watch and maintain.

Let's not make the evil script-kiddies's life easier.

🤡 -> If fully opted-out, just return "cooked with Umami"

@weepy
Copy link

weepy commented May 26, 2023

Is there any major benefit beyond the bool ?

@antony
Copy link
Member

antony commented May 26, 2023

As discussed, I'm pretty happy with any incarnation of this because I think the explicit (variable) is better than the implicit (scraping for svelte- prefixed css classes)

In an ideal world I'd like three options:

  • hidden
  • minimal "Svelte" (default)
  • full "Svelte 4.2"

I'm of the opinion that this has a variety of uses, but for security, we always omit the patch version (thanks shodan).

@hazre
Copy link

hazre commented May 26, 2023

Perhaps this should be a choice in the create cli prompts. To choose between hidden, minimal and full for any new project. And Minimal by default for already existing projects.

@JustMrMendez
Copy link

A boolean should be good enough, displaying the svelte version has security inplications that outweight the benefit.

It needs to be opt-out or it will have no use.

@mojoaxel
Copy link

I don't see real security implications. If there is a known vulnerability, attack tools will find a way tests for them. They are doing this for a long time and the risks don't get bigger by transparency. These tools are already willing to go the extra mile. Security by obscurity was never a good concept!
On the other hand it would be possible to easily and maybe even automated warn webmasters if a vetsion has a known vulnerability. For this more information is better than less (patch level).
I say let's go for it, but an opt-out should still be possible.

@khromov
Copy link
Contributor

khromov commented May 26, 2023

I believe this is a bad idea because I think a lot of security scanning is "drive-by attacks". First a very basic attack (or just fetching the front page) is attempted, and if a vulnerable version is detected then more complicated attacks can be executed against the target. By keeping the version unavailable, the attacker would need to commit resources on an up-to-date site to try to (unsuccessfully) breach it.

As a counter-point, I'll present the same discussion in the WordPress project. In the end, they decided to keep the version in a meta tag:
https://core.trac.wordpress.org/ticket/23394

@sheecegardezi
Copy link

whats the use case for this feature?

there's a huge description on the top... thinking

Well butter my biscuits and call me a biscuit baker! I missed that gargantuan description at first, hence I tried to pull a Houdini and make my comment vanish, but darn it, your quick fingers outplayed me!

@bertybot
Copy link
Contributor

Honestly, as someone who is the lead dev on a very highly visited site that uses Svelte extensively, I am totally okay with this.

Like the old saying goes if there is a will there is a way. If a big vulnerability comes out in Svelte it doesn't really matter if attackers know the version number or not. They will probably hit big sites that are known to use Svelte pretty quickly, and if you build applications at an enterprise level this is a situation that you should have a plan for on any dependency you have.

On top of that, at my company at least, we have code checks constantly auditing our dependencies checking for vulnerabilities like this.

To me this is only a win for Svelte. I know our website doesn't show up on the analyzer either and has more visits than daisy.ui too. I'm sure there are a lot more sites like this. Showing people that Svelte works at scale can only help the community.

@amr3k
Copy link

amr3k commented May 27, 2023

I think it should be on by default but add an option to disable it in the cli.

@rezk2ll
Copy link

rezk2ll commented May 27, 2023

expose a major version and provide an option to opt-out

@antony
Copy link
Member

antony commented May 27, 2023

Security by obscurity was never a good concept!

@mojoaxel agreed, but as pointed out by Conduitry, a security vulnerability disclosure policy is already security by obscurity.

@andirady
Copy link

I think for production, provide a documented way on how to know the page was using svelte, and for dev mode, provide the version always.

@KoljaL
Copy link

KoljaL commented May 27, 2023

Give all you have to give (SvelteKit 4.0.0) and show the hint to the opt-out after the install and in the docs.

@katriellucas
Copy link

To be the devil advocate. If you, as a developer, are this aware that it's a security issue, then you also should keep in mind that if you are building a production app with sensitive information, you should disable the feature. If you don't disable, I mean, it just shows that you weren't that worried to begin with.

I think it's a good feature, I say that it's fine to display Svelte version as long as it's easy enough to opt-out.

@TheRolfFR
Copy link

Disclosure, I am just a dude, and no security expert, so PLEASE don't hesitate to correct me.

Patch or not patch?

but for security, we always omit the patch version

I think minor still gives you what are the vulnerabilities if not updated to next minors? Semver states: "Patch version MUST be reset to 0 when minor version is incremented." As a result, latest minor would raise doubts but outdated minors would not change anything.

I do not say the solution to that problem is easy, but you can't give it nor not give it.
Considering a (human) developer browsing the web, the relevant questions are:
Would he like know what tech is used in this incredible website? Yes
Would he like to know what version could allow him to have the same features for its own project? Yes BUT what version will he use to make its project? The latest. Why? Because Frameworks normally have same or more features when major changes. Or some features are not revamped because a library liked the idea and now does it better.
Would this fellow developer read the minor and patch, compare with CVE entries and warn the webmaster about this outdated svelte version? I think the probability is low.
Would the minor and patch still be relevant for individuals? Probably not.

Warn about vulnerabilities?

On the other hand it would be possible to easily and maybe even automated warn webmasters if a vetsion has a known vulnerability.

I think there is a small probability that a friendly person would warn webmasters with know vulnerabilities (as previous part explains). I'd love to leave my door unlocked when I leave my house, but this ain't Canada. It's the Internet.

Automated tools may directly use manifest or lockfile. There are not 500 ways to retrieve this data: Register to some kind of service or scrap the web/repositories).
Open-source developer may share their package.json on their repository, done.
Companies, now that's another problem. Responsible companies should monitor all of their projects for security or be smart enough to take the opportunity to make the client pay you for giving "friendly (not legally obligated)" reminders. My company runs a security bot daily on on all current and past projects, with every tech or system used, to warn the clients about it, done.

Sorry I thought I could say that faster, thanks for reading, and good luck!

@iojason
Copy link

iojason commented May 27, 2023

(+1) expose a major version ('this site is running Svelte 4 and SvelteKit 2')

@qurafi
Copy link
Contributor

qurafi commented May 27, 2023

Even if you hide the version, It does not change the fact that it's still vulnerable. A hacker still could detect if a website is running svelte(kit) by detecting common patterns by checking specific headers or requests(e.g. data requests). Even if he does not know the specific version, he could try, if it worked, it worked!

A possible ways is to reduce the surface area and increase the effort done by the hacker. You could protect your website against bots using services like Cloudflare and add tools to notify you about vulnerabilities. At the end, If you don't maintain your app regularly or you don't do precautions, it's partially your fault.

If you ask me, I will always hide it, I don't think there's a benefit of showing version information to the user. Although this will affect svelte(kit) in the statistics.

@gtm-nayan gtm-nayan mentioned this issue Jun 19, 2023
5 tasks
@dummdidumm
Copy link
Member

Thank you for participating in the discussion everyone! We decided to show the major version by default, and you can opt out of it through setting discloseVersion to false in your Svelte compiler options. We think this strikes a good balance between getting a rough indicator of how current Svelte deployments are in the wild while preserving security through obscurity to some extent.

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

Successfully merging a pull request may close this issue.