[tw5] I Think I Hacked TiddlyWiki

Hello All,

Following the discovery of the iframe content to execute JS in TiddlyWiki, I began pentesting TW to find other methods of executing JS, but without any kind of sandbox. What I discovered is that TW correctly sanitizes tags, but did not know how to deal with base64 encoded urls.

What I was then able to do was create an auto-executing JavaScript keylooger using this method, which is invisible to the user. Below is a minimal-reproducible example of the code I used.

Try pasting it into a tiddler, and it will alert your keystrokes back to you. What makes this more dangerous than the iframe is that it has DIRECT ACCESS to your TW instance, so practically anything can be done. For example, I could steal your tiddlywiki instance, encrypt it, and hold it for ransom, as soon as your page loaded.

Furthermore, this method of attack does not have to be downloaded. It can be pasted in a TiddlyWiki, saved, and then anyone who visits that TW will be infected.

Someone let me know that this, is, indeed, a security flaw. Meanwhile I will let the Github devs know.

Update: just let the devs know ([BUG] Did I Hack TW? · Issue #5960 · Jermolene/TiddlyWiki5 · GitHub)

Hi Finn,

Could you perhaps post a video of what you see on your end? I tried on several instances and don’t get the “will alert your keystrokes back to you” part, just a seemingly empty tiddler.

Best,
R²

@R2, the tiddler is blank by design. Once you have saved the tiddler, press a key on your keyboard, and it alerts the keynumber back to you. Typing multiple keys it will alert each key you’ve pressed as part of every keypress.

OK, got it to execute. For some mysterious reason, the first few keypresses didn’t do anything, then a few did, I clicked elsewhere and modified another tiddler, the next few didn’t, and when I went back to the malicious tiddler to get it to execute again, it hadn’t recorded keypresses made in the other tiddler. It does seem as if it’s at least partly sandboxed but I’ll defer to the core coders, I was just curious to see what this was about.

Best,
R²

I’m trying to understand what the problem is.

TW isn’t multi-user. If someone can sit down at your desk and insert code, then you already have security problems way beyond code.Likewise, if you have a publicly exposed TW that anyone can save with, then you have security problems beyond a code hack.

So I’m not seeing what the concern is. If someone has the ability to save to your TW, then you already have a security breach, regardless of the nature of the inserted code.

Mark,

The scenario I had in mind was: Person A (attacker), adds malicious code to his TW instance, which is accessible via the web through GitHub pages, or something similar. He then shares his wiki link with Person B, who unknowingly goes to take a look at Person A’s wiki. On doing this, Person B then has this malicious JS execute on his end, thereby hacking/infecting him.

With JS, this exploit could be crafted in a variety of ways, as stated, there is already pure-JS ransomware, which, combined with some creativity, could trick the user into allowing the wiki to access the local filesystem. There is also ways of installing damaging malware to the users system (see Drive-by download - Wikipedia), purely from vulnerabilities like this.

So this exploit can reach beyond the scope of there being someone who “can sit down at your desk and insert code.”

I’m still confused about this scenario. If we’re not talking about inserting the code into someone else’s wiki via XSS or something, how does TiddlyWiki allow anything here that an arbitrary website wouldn’t? If a malicious user can post a page on the web and make the target go to it, then surely anything that a browser allows is fair game, and if there’s fault here it should lie with the web browser, not TiddlyWiki. Because even if TW changed to disallow this, surely the malicious user could just revert that change in their own fork of TiddlyWiki and build their malicious wiki on that TW edition?

I’d be more concerned about people being tricked into importing a tiddler that contained code like this.

I’d be more concerned about people being tricked into importing a tiddler that contained code like this.

In my test, the code didn’t do anything. So it’s hard to evaluate. What exactly could the code do? Unless it could write to the file system (which is really hard in JS), or if it could send the keystrokes back to a server-based entity, it would not be able to accomplish anything. What browser are you testing with?

I think the WP article is talking about abilities that existed before modern browsers. Modern browsers, as we have found out to our chagrin, tell you that they are doing a download. They can only download to one place, which is usually the download directory. They know nothing about the file system, and can’t even tell you the path of an image that has been loaded (also to our chagrin). Once a file is downloaded, it can only be executed by a deliberate action. On Linux, most file managers won’t execute from the GUI anymore, so no accidental clicking. On Windows, Windows pops up a message warning you that you are about to run a potentially dangerous file. So it’s not easy to get your code executed even if it is downloaded.

If a person deliberately puts code on their page that does malicious things, it doesn’t matter how it is inserted.

So basically, you’re just saying that TW uses Javascript and somebody could insert additional JS. But that is a weakness/strength of all AJAX pages. It’s not like I could go to an existing TW site and add my own malicious code. It would have to be running a special server based version of TW (node, Bob, ) to make that possible – not the standalone.

In terms of self-protection, the best away to avoid malicious code would be to only use code/plugins that are WikiText based (after reviewing that it doesn’t create JS tiddlers), or only using plugins from sources that you really, really trust (e.g. Eric S.)

That was one of the concerns with TWederation. You could import from someone you trusted who imported from someone they trusted who … actually couldn’t be trusted. It’s kind of a hard problem.

Mark S. wrote:

… Modern browsers, as we have found out to our chagrin, tell you that they are doing a download. They can only download to one place, which is usually the download directory. They know nothing about the file system, and can’t even tell you the path of an image that has been loaded (also to our chagrin). Once a file is downloaded, it can only be executed by a deliberate action. On Linux, most file managers won’t execute from the GUI anymore, so no accidental clicking. On Windows, Windows pops up a message warning you that you are about to run a potentially dangerous file. So it’s not easy to get your code executed even if it is downloaded.

Ciao Mark. I enjoyed this for both it’s accuracy and it’s acknowledgment of ongoing CHAGRIN.

As it happens I am still on Timimi previous to latest on Firefox (i.e. the Saver & LAUNCHER) that lets you launch apps directly (with a bit la-di-dah) from TiddlyWiki.

So, if that is insecurity, I’d like more of it.

I think it insane to force web pages to be stupid when they can be really clever.
TW, in particular, is really great when you also can control the computer from it.

Regarding the OP. The tech part of it is above my tech level, but I can’t see any real issue that differs from the normal caveats about switching on a computer.

Best wishes
TT

Mark S. wrote:

That was one of the concerns with TWederation. You could import from someone you trusted who imported from someone they trusted who … actually couldn’t be trusted. It’s kind of a hard problem.

Right! It IS an interesting issue. But maybe as much an anthropological issue as a technical one.
Suddenly tech switches into “HOW CAN I TRUST?” mode.
Despite the fact most everyone, well everyone, here (you, reading this) is completely trust-worthy.
I think its a basic sociological fact that much of the internet is NOW premised on the idea you can’t trust anyone.
It has led to a kind of “authentication gymnastics” that makes doing some things very convoluted.

Just rambles
TT

I am currently playing with “real-time multiplayer” capabilities for TW5, so this is an interesting security vulnerability to be aware of.

My primary concern was “what if a malicious user connected a MIS-IDENTIFIED wiki to a real-time server. It has a bunch of malicious tiddlers, and it DOES NOT have a bunch of tiddlers that exist in the server copy.”

The real-time sync, once authenticated and authorized, would just absoloutely wreck the server-copy of the wiki in this instance.

Similarly, being able to some-how sync malicious javascript code, hidden in a data-uri to the server, which will sync it to all connected users is a concern…

Best,
Joshua Fontany

TW wasn’t built from the ground-up for mult-user, and it’s definitely not how most people are using it. I’m sure products built as server-side entities (e.g. WikiMedia) have all sorts of protection against injected code.

Anyone who can write and save a tiddler can make a javascript tiddler, or a widget, or overwrite a javascript filte operator, or maybe header scripts, or maybe in-frame code. I guess you would have to think of all the ways that code could be injected and then neutralize everything that matched. But you’d have to do it before the tiddlers got written to the common pool, and you’d have to either block legitimate uses of the iframe, or figure out some way to detect that the frame doesn’t contain js source code.

Mark et al

You said TW wasn’t built from the ground-up for mult-user, and it’s definitely not how most people are using it. I’m sure products built as server-side entities (e.g. WikiMedia) have all sorts of protection against injected code.

I agree, yet we have Bob which makes this plausible at least where people who access the wiki are trusted such as in a team. Perhaps not secure on the internet where anyone can get to it.

  • I think this may be a self fulfilling prophesy, we don’t have secure methods to share online or run in a multi-user mode, so no one does.
  • Because we don’t have multi-user solutions on the internet people come to expect all the control they want on their own local wikis, I don’t want the security tail wagging the dog, if I want to iframe sites I use, or use it to drag and drop patches between wikis, I would not like this being locked down.
  • Despite me calling for this mulit-user functionality, see Check in and out critical to the use of tiddlywiki #5919 with the simplest form serial editing using a check out and in facility I can’t seem to get any traction on this.
    Given the discussion in this thread, perhaps we need a way to harden tiddlywiki for the internet, but I hope we don’t harden it for the sole or LAN users or teams. It seems we may need to “bifurcate” to the risky and less risky environments, another possibility is being able to run a vulnerability check on a wiki.

The best security will give us our cake and we can eat it too, the wrong security will mean we can’t eat the cake, or look at it in the security of our own room.

In closing of great importance are the many possible ways tiddlywiki can be made use of, but we need to maintain flexibility even when attempting to secure it the the “great unwashed internet”, because it often has little or nothing to do with the internet.

Regards
Tones

Well, what I see is this:

If you use TW, you use JavaScript. And if you use JavaScript code from unknown / unsafe sources, you will run the risk of the code doing things that it shouldn’t be doing. That should actually be clear to everyone. But that’s not a problem for TW, but in principle for every website that takes full advantage of the possibilities of HTML5. And at last, it’s the problem of all data: You have to trust in it.

A particular security problem of TW is, of course, that TW has all the tools to integrate new (dangerous) code in the simplest possible way, without the user always being aware of what he is doing. The special thing about it is not only that it is so easy to do. It is also particularly difficult to understand and keep track of, because the file is constantly being changed and saved.

Of course, you can take the trouble to review the code you are adopting and also ensure that no one else can insert their own code. But honestly, who does it? We usually trust what we find - at least on the sites we know. And what we are inserting is not always obvious. The example code above, for example. In plain language it reads:

Which of you deciphered it before trying it out?

Excellent points John. Most users will indeed not review the full text of every single tiddler they import. I’m now thinking that pointing out which ones should indeed be reviewed more explicitly would be both easy and worthwhile.

At the tm-import-tiddlers widget level, any JS that’s being imported could be flagged, with a simple highlight inviting the user to review the code before confirming the import when standard declared JS is detected, and a more insistent alert when the code is hidden or obfuscated (as in Finn’s Base64 example). A simple exhaustive filter search should be able to cover all or most cases, including content-type=application/javascript, , ,

I feel (at my very modest level of understanding) that this would add a significant extra layer of security when drag-and-dropping as users could react when seeing JavaScript being imported where none was expected — when simply importing a random content tiddler for instance.

Given that new JS is only executable after rebooting the TW instance, even if the potentially malicious code is executed while parsing the imports, it shouldn’t prove too much of an issue as the user with sudden doubts could immediately delete the imports and avoid any potential issues and would be invited to then share any concern with the TW community to understand if anything is wrong and nip the problem in the bud.

Best,
R²

I never got the alert. I’m curious why some people are reporting that it worked. Also, “alert” is very public and generally pretty harmless. Possibly it could be used as part of a phishing scheme. It’s not clear to me that you could create code that could modify anything outside the iframe sandbox. The suggestion was made that it could download something. Is there a demo for that?

Really, it gets back to trust and reputation.

A TW coder could write a tiddler that contains no javascript tiddlers, but that, when run, creates a javascript tiddler that will later get run. So you would never see javascript code during import. The core TW is already pretty huge. Adding patch after patch for each imagined scenario eventually renders TW less and less useful.

Also, it hasn’t been demonstrated what harm could be done even if your standalone code was infiltrated. Could keystrokes be sent back to a server? Could file blocks be written anywhere other than the download directory? Of course on node or especially on any multi-user platform things become more hazardous. In theory any server-based solution (e.g. node) could write to your file system and possibly invoke code. In practice, I found it very difficult to set up even when I wanted something like that.