Cross-platform JS addons for the reviewer

Same proposal of [Idea and Feature Request] Cross platform JavaScript Addons Support

As you said here, @dae, it should be discussed later when the clients share more code, and I think that now is the time.

5 Likes

I want to incorporate a progress bar into the card templates, so I need a function to get the number of cards remaining in the current deck to the card template. For now I can create a timer progress bar. If official Anki has a plan to incorporate that into AnkiMobile, I don’t think it is necessary.

Edit : For now the progressbar is the most downloaded add-on among the 59 add-ons I have uploaded to AnkiWeb, it is in high demand from Anki users, so I think it would be useful to incorporate it into the official Anki.

2 Likes

One of the concerns I mentioned in the past is that there are security implications with exposing more functionality to JavaScript. It is still a problem - any endpoint we expose to the review screen will also be accessible by e.g. shared decks. We may be able to better isolate things by moving the card content into an iframe - it’s something to explore when more of the review screen gets moved into Svelte.

2 Likes

What I propose is to do it now, with Typescript that could be used in any of the clients, instead of waiting until the reviewer goes to Svelte.

I want this unblocked and to get things moving. Are you fine with only read-only methods for now, like getting info about the current card/deck/etc, so we can do a proof of concept?

I’m sorry, I think this is something that needs care due to the security concerns. Any APIs that shared decks can access are a potential attack surface, and even read-only methods can leak collection data, or in bad cases, arbitrary files/data.

1 Like

Let’s say that I create a simple read-only JS function called getDeckName() that sends a POST request and Anki returns the current deck name.

How exactly would that expose to an attack more than what the current POST requests do?

And I need an specific answer here. Saying that there are “security concerns” without an example doesn’t help getting things forward.

What are you concerned about? That a shared deck will collect the deck name and report it to an external server? Add-ons can do worse and they aren’t blocked.

If that is a real concern, should millions of people simply be stopped from having a feature just because they didn’t pay attention to some rare malicious decks they downloaded with that? Currently I guess that shared decks could have even a bitcoin miner, so the API wouldn’t be the biggest of the problems.

If you have any idea about something simple enough that would be safe to implement and get a proof of concept, it would help a lot.

1 Like

The difference is that add-ons are a known security risk. The add-on download pages warn users not to download add-ons they don’t trust. We make this clear to the user, so they can make their own mind up about whether the utility is worth the possible risk.

In contrast, shared decks are used by a larger percentage of the userbase, and I think that most users reasonably expect that downloading a shared deck won’t leak information about their collection, or allow for arbitrary code execution like add-ons do.

You may not consider things like your deck names to be sensitive, but not all users feel the same way. And presumably the goal is not to stop at a few read-only methods, but expand the API to include destructive operations as well. I don’t think it would be responsible as a maintainer to do that without first ensuring that shared decks can’t access those methods.

At the moment, I’m not aware of a better way to solve this than moving the shared deck content into an iframe, and relying on message passing to limit access to the internal API. Other suggestions are welcome.

2 Likes

The difference is that add-ons are a known security risk.

So, for now, just make the JS API an opt-in setting to make them a “known security risk”.

Whenever the reviewer is in Svelte, the iframe solution can be done.

1 Like

I’m not a contributor (yet, anyway), just an interested card creator, but I thought I might chime in that Anki could use a similar approach to AnkiConnect and require auth for any API requests, preferably with finer-grained permissions.

Although it’s probably outside the scope of this thread, I think that exposing an AnkiConnect-like API via HTTP (with auth) would be preferable to some sort of hidden message-passing system, since this sort of functionality would also be extremely useful outside of the reviewer.

1 Like

Just read through this quickly. Personally, I think that decks should not have any crazy scripting abilities. However, I am in full support for cross-platform (javascript?) addons as a separate feature.
It would be so nice to get the same experience on desktop and mobile.

2 Likes

Lest the idea of cards accessing this API get thrown out I’d just add that it would enable often-requested features such as the ability to edit notes from within the reviewer and for notes to share fields, among other things. I agree that giving cards unfettered access to the system without permission from the user would be a terrible idea (although they more or less already can do whatever they want with the JS fetch API) but if it is possible to create a secure generic interface for this functionality I don’t think cards should be arbitrarily excluded.

1 Like

That is the approach I had to take with LaTeX generation, but it’s far from ideal. There will be users who toggle it accidentally, or toggle it and forget about it, and they’ll be at risk from that point onwards. And if any popular shared decks/templates/add-ons start depending on the API, that will encourage more users to put themselves at risk.

I’m sorry, I don’t think it would be responsible to introduce this new functionality without ensuring it’s secure from the start.

And there’s more than just an iframe to do - Anki and AnkiMobile currently have no way of distributing/installing JS outside of card templates and Python add-ons. AnkiDroid has an initial implementation based on npm, but that’s only a partial solution, which doesn’t cover things like a browsable list of available add-ons, reviews, etc.

That may be a good idea for other reasons. But the issue is that Anki’s internal code, and any add-ons, would need to hold the authentication key. If that code is running in the same context as shared deck JS, we risk the shared deck JS being able to extract the authentication key and make its own requests.

I’d rather see card templates using less JS, not more. A lot of things being done in card templates currently isn’t necessarily specific to a particular card type (think answer timer, pretty tag formatting, etc). By moving these things out of the card templates and into separate add-ons that can be upgraded separately, it should make the shared decks more robust against upgrades, and hopefully make the templates less daunting to users as well.

1 Like

I don’t see how an opt-in toggle is essentially different from what the add-ons do and what shared decks can maliciously do with JS at the moment.

The stars need to align a lot for what are you proposing, while it would be nice if the JS add-ons ecosystem could start growing, since I guess that at the current development rhythm, that will only happen in at least 3-5 years from now.

So I personally give up and will left that to anyone else interested in it.

1 Like

I think there’s been some frustration on both sides, and some arguing at cross purposes. I apologise for my part in it, and will try to make my position clearer.

The feeling I got from your posts is that you are frustrated that an API hasn’t been implement yet, and I felt you were somewhat dismissive of the security concerns I (perhaps ineloquently) raised.

This in turn frustrated me, as I think security is important in the context of shared decks, due to user expectations. You’ve implied exposing these APIs would not be a significant change in security, but I think that’s incorrect. The majority of Anki’s private web APIs are blocked to the reviewer, to prevent this kind of abuse. That’s a fairly recent development, after demonstrated exploits were revealed. There have been some more since then, which have also been fixed. I want to see us tightening up this area further, not loosening it, as shared decks have always been intended to be safe to download.

We’re able to block the majority of APIs currently, because the reviewer itself doesn’t use them. I fear that with a public API, and a JS add-on running in the reviewer context, we won’t be able to keep them separate without something like an iframe, or moving the add-on into its own context.

A security-conscious solution is of course going to be more work than just exposing the methods without any protection, but I’m afraid I think it’s important in this case. I don’t think we’re going to make any progress debating that point further, but discussions on how exactly we could implement this securely would be welcome, and would be a step forward. If you or another developer is interested, a GitHub issue is probably the best place.

2 Likes

I wasn’t clear enough, and I’m sorry for that.

I get your concern about security and find it very reasonable, but that needs a big amount of infrastructure (that I called aligning the stars) which I can’t implement at the time being and the motive of me giving up.

My proposal about using an opt-in is something that I consider doable at the moment and is something that could kickstart the JS API ecosystem, so when it is fully safe, probably years from now, things are quite mature.

Right now, the question is what is the priority: full safety or giving power that requires responsibility. Both are commendable, but I personally prefer the latter. You answered that security is the priority, which is fine to me and something that only someone else will be able to do.

2 Likes

@dae, I too believe that adding more functionality (especially when developers are willing to work on it) is a better option. It is the software’s (Anki’s) responsibility to ensure that the users know about the security implications of their actions but after that, it is the user’s responsibility to remain cautious if they want to use the feature.

One way to solve the issue is to periodically display warnings when the feature is active. For example, if you enable developer-mode extensions in Microsoft Edge, a warning appears every time you launch the app. (See Developer mode extension notification - Microsoft Support)

A warning on every launch is probably excessive but we can have a warning popup once a month if the JS add-ons are enabled.

2 Likes

The opt-in can be done per notetype as well.

2 Likes