Web Serial Terminal Means It’s Always Hacking Time

Arguably one of the most important pieces of software to have in your hardware hacking arsenal is a nice serial terminal emulator. There’s plenty of choice out there, from classic command line tools to flashier graphical options, which ultimately all do the same thing in the end: let you easily communicate with gadgets using UART. But now you’ve got a new choice — instead of installing a serial terminal emulator, you can simply point your browser to the aptly-named serialterminal.com.

Well, maybe. As of this writing it only works on Chrome/Chromium (and by extension, Microsoft Edge), so Firefox fans will be left out in the cold unless Mozilla changes their stance on the whole Web Serial API concept. But assuming you are running the appropriate browser, you’ll be able to connect with your serial gadgets with a simple interface that should be familiar to anyone who’s worked with more traditional terminal software. In a quick test here at the Hackaday Command Center, we were able to bring up the Bus Pirate UI with no problems using Chrome on Linux.

The project comes our way from [Mike Molinari] of Autodrop3D who, unsurprisingly, often finds himself in a position where he needs to talk to 3D printer control boards over USB-to-serial. Since he’s using a Chromebook as his primary device these days, he thought a fast serial terminal emulator that he could use without leaving the browser would make his life a lot easier. With less than 150 lines of code between the HTML, CSS and JavaScript, he was in business. Add in a shiny new domain name, and now we’ve all got a handy tool for hacking on the go.

This isn’t the first hacker-friendly application of the Web Serial API that’s come our way. Last year we featured a web oscilloscope that worked in conjunction with the Logic Green LGT8F328P microcontroller, and more recently the Gabuino platform that provides an STM32 compiler and debugging environment in your browser.

66 thoughts on “Web Serial Terminal Means It’s Always Hacking Time

    1. That’s a strange limitation. Why wouldn’t you use a serial terminal just because you have to download it from the Internet?
      For a decade now my preferred windows serial terminal has to be downloaded (PuTTY)
      Any terminal for Linux is downloaded from the Internet, either as a package or because it is built in and the OS was downloaded.

      Personally I already downloaded the single html file and have it stashed away on my fileserver to give it a try.
      Being a single self-contained html file has all the advantages of a portable executable, with the bonus that it isn’t an executable so is even more portable.

      1. It’s more a case of, if that site can access a serial port on your machine and manipulate something connected to it, so can any other website you load up in your browser. WebUSB and WebSerial set a dangerous precedent there.

        As for whether such tools ship with particular OSes… well, Ubuntu I think ships `busybox` in its stock image, including its `microcom` applet. So maybe you don’t need to download such a program on Linux. OpenBSD ships `cu`. Not sure about MacOS X.

        Windows used to ship with Terminal in Windows 3.1, and Windows 95 used to ship with HyperTerminal., not sure about today, been a long time since I used that OS.

          1. I just want to know when and why someone would link a serial PC connection to, I’m guessing a browser plugin, other than for hobby software? Like, a virtual serial connection to talk to old software? I might just be way out of touch or something, in which case, I apologize :/

        1. “It’s more a case of, if that site can access a serial port on your machine”

          Yea, but it can’t. Except for the github link to download the html file, the site isn’t involved.
          Or put another way, the “website” is my C drive :P
          The file is 150 lines and other than one A tag (the same link to github to download it) there’s nothing that accesses the Internet in that file.

          “WebUSB and WebSerial set a dangerous precedent there.”
          I’d argue javascript itself set that dangerous precedent long ago, and nearly everyone is seemingly fine with that. They blindly run whatever JS code a site throws at them.

          This instance is one of those rare cases you can see everything it does.
          I can’t say the same for putty. I blindly trust the executable does what they claim and nothing more.

          “Ubuntu I think ships `busybox` in its stock image, including its `microcom` applet. So maybe you don’t need to download such a program on Linux”
          My point was you probably downloaded that Ubuntu stock image, thus everything included with it, to highlight that ‘coming from the Internet’ is a ridiculous criteria on its own.

          1. Sort of… you seen how big Chromium is lately? If I update it on my systems (I run Gentoo), it’s usually a full day of compiling on a 6-core Phenom II X6.

            The code when compressed weighs in at over a gigabyte. That “150 lines” needs some big dependencies.

            This isn’t the point though… the point is, if “a” HTML/JS file can access serial ports, theoretically so can anything else running in that environment. It’s a question of how good the sandboxing/security/permissions are.

            JS is definitely being conscripted into tasks it was never designed for, no question. It “took off” because at the time no one really had a compelling alternative. Microsoft tried to push VBScript, but no one else took them up on that. CNRI Grail tried to do client-side scripting with Python, but by that time, Netscape had pretty much won the argument. It was everywhere and the competitors were nowhere.

            Maybe webassembly might be a pathway to something better, but time will tell, we’re going to have to put up with unreadable blobs in the meantime until the “something better” materialises.

        2. No, any other website can NOT do that. Any new API like this has strict same-origin requirements, content security policy requirements, must be served over a secure connection, and requires explicit user consent for each site. If anything, it’s safer – it’s a locked down sandboxed environment.

          (Context: For several years I was as a senior software engineer at Mozilla, working on Firefox)

          1. Ahh “same origin” meaning only one HTTPS server on the planet can serve a file up that accesses peripherals on your host? No?

            There’s my point. If one site can do so (meeting the same-origin/security policy/transport requirements), so can any other. Including malicious sites, and compromised sites operated by otherwise “trusted” administrators.

        3. I’m curious why you are ok accessing your bank, Facebook, email and a multitude of other risky activities over the internet, but connecting to a serial device that has zero power over your life is suddenly a concern?
          Not a criticism, just pointing out a flaw in the logic.

          1. “I’m curious why you are ok accessing your bank, Facebook, email and a multitude of other risky activities over the internet, but connecting to a serial device that has zero power over your life is suddenly a concern?”

            Okay, let’s deal with these one by one:

            – “my bank”: actually, I’m NOT OK with having to do this over the Internet… I have two bank accounts, the first is the passbook account I’ve had since 1995 and is NOT internet accessible, the latter is a recent addition purely for doing the “internet” stuff — begrudgingly opened because society FORCES me to.
            – “Facebook”: I’m not, and have never been, a user of Facebook
            – “Email”: IMAP ≠ HTTP
            – “serial device has zero power over your life”: Mmm hmm, so the console for my border router to which I log in as `root` has “zero power over my life”?

            Not a criticism, just pointing out a flaw in your flaw.

        4. Thanks for the microcom tip, @Redhatter. That’s a handy tool to have, considering it’s even in the initrd. I had been using screen.

          For those trying microcom out for the first time, to disconnect, use Ctrl-X. ;)

  1. Mozilla’s stance on literally every generic device API drives me up the wall. By the same rationale of “there are potential abuse cases so nobody gets to have it” they should be removing all features from Firefox including internet access.

    1. No. Firefox stance on this is right. My previous laptop had 13 serial ports. Most connected to internal devices.
      For the average user it is impossible to understand the security implications.

      As for internet access, that is what it is designed to do. We are just asking not to add exposed 230V pins to your toaster just because a few people want to hook up their home made clock to it.

      1. “My previous laptop had 13 serial ports. Most connected to internal devices.
        For the average user it is impossible to understand the security implications.”

        Considering the average user has a 99% chance of not even having a serial port, let alone it being connected to anything, then that argument is mute.

        1. You’d be surprised how many serial ports modern computers have. Just because DB9 ports have mostly gone the way of the dodo doesn’t mean computers don’t have serial ports any more. These days they’re just mostly used as internal interconnects, and *most* of the time OSes are intelligent enough to classify these devices separately instead of as just ttyS0 or COM1.

    2. Both ironic and sad, given many of these APIs originally came from Mozilla. A lot were implemented in FirefoxOS, but a bunch of them predate that – we were experimenting with some of this stuff in Ubiquity and Mozilla Labs back in the day. Hell, one of my (unofficial) little side projects while working at Mozilla was a patch for Firefox to get Microsoft Kinect streaming it’s video and depth data through a web-accessible API. Fun times!

    3. I think it’s quite rational. Serial and USB devices were never designed to have access from the Internet.

      The same way desktop apps don’t need to validate user input against malicious attacks, since all they do is access local resources and a user with appropriate rights can circumvent them anyways. If they access Internet services, then those services should implement the security on the server, as any local tests could easily be circumvented.

      Your server (or any local service/deamon) is responsible for making sure that no right escalation is possible.

      Browsers allow external access to internal resources and therefore need to ensure there is no way to break out of the isolation they provide. That’s what USB and Serial implicitly relies on, you can’t retroactively change the security model.

  2. Why on earth would I want a website to access a local serial connection? Not everything has to be done just because it’s technically possible and honestly, every “app” being a website is becoming a huge pain.

    1. Because it significantly lowers the barrier to entry.

      Almost any PC/tablet can run a web browser – you don’t need to install and setup an embedded development environment, you just need to load a webpage to start creating. Or if you want to create something that interacts with devices, then you can do that by just making a webpage.

      You take this to an environment like a classroom with a bunch of Chromebooks or old donated PCs or BYODs where it’s either impossible or unrealistic to install/setup/maintain an embedded development toolchain on every machine. Instead you can have students loading up a webpage that gives them an editor or IDE or a visual block programming interface that can generate firmware & flash it onto real devices in minutes. It’s transformative.

      Speaking from experience of trying to run workshops with BYOD to introduce students to this type of thing, half the time is often spent just trying to set up the tools. And there’s always some machine that has particular trouble that takes too long to fix, so some student misses out. And that’s with expert guidance right there with them – in a typical classroom environment it’s even harder, at home most won’t even try and most that do will give up in frustration before they’ve gotten to the fun part of creating. Being able to just load it up in a webpage completely changes that.

      On the other end of the spectrum it’d also allow you to reflash & monitor serial output of devices in the field, using your smartphone with a webapp open. You don’t need to haul around a development toolchain and the raw computing power needed to run it quickly – you let the server do that.

      As a practical example that I use, ESPHome is a tool for creating software to run on ESP8266/ESP32 devices for home automation. It has a web dashboard that you can load in any browser on any machine without needing an embedded development toolchain installed & setup. You open the dashboard in your browser, edit a device config & code, the firmware is compiled on the server, transferred back to your browser, and flashed onto the device connected to USB on the machine running your browser. Tasmota is a similar project that has something similar. I think the Arduino Web Editor still relies on a locally installed agent, but it could be updated to use WebSerial instead. While those examples use a server to do the compiling, it’s not the only model – some projects use interpreted languages loaded onto the device, or you could do the compiling entirely locally in the browser (possibly enabled by tech like WASM).

      1. It is a cool use case. But you can’t tell me that all those chrome books couldn’t run a plain Linux as well (if you don’t like Windows).

        Aside from that it’s not more work to type in an applications name vs. a websites name. So there really is not more effort involved at all. The local app should open faster though.

  3. Nice project. But I fail to understand the real life application. If I have my arduino on desk next to my laptop why should I connect to it through other continent? Hardware needed is the same (except of all added internet infrastructure between me and that server on the other continent). Software needed is even less (no need for browser, cloud holding the web and the web itself). In the end power usage – any local serial terminal will consume less power than local machine and all that stuff to maintain the webpage.

    So what am I missing?

    1. What if you’re using a Chromebook? I recently finished a web project that streamed data to a microcontroller using WebSerial – the data was sent to the microcontroller over USB by way of a CP2104 USB-to-serial convertor, and then serial sent into the microcontroller via its hardware UART. Reading the debug messages from the microcontroller when attempting to program and debug it was a real pain without a serial terminal, and on Chromebook that’s best accomplished using some kind of web app (though of course you can download something dedicated). This site seems perfect for that use case!

  4. Ok, WHY?

    I mean, ok, I understand, it is possible, some will do it, just to show it can be done.
    Great! Congratulations! seriously.

    But then.
    Why would it be a good idea to allow a browser to run a program which has access to serial ports?
    Is there a legitimate use case?

    Even on device when there is access control for serial ports, if user “A” has access to /dev/ttyS0, then browser run by user “A” will also have access to /dev/ttyS0. Who expects this?

    I click the link I select port (but I can imagine a script which does not ask for this) and it connects and successfully talks to my device on the other end and at no point did the browser (chrome, windows10) ask if this is ok for me.

    (Side note, on this computer there are very multiple devices connected, some through USB serial ports, some seen as serial ports by OS even if this is actually a different interface. Sometimes I have ports from COM1 to COM75 (not all active and available at once, at this moment I have COM2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 19, 20, 41, 46, 47, 48, 49, 73, 74, 75))

    The terminal itself.
    I can select the baudrate from some predefined values.
    I can input some custom baudrate and it works. Ok.
    But where are other settings?
    parity? data bits? stop bits? flow control?
    character encoding?
    I have “send with /r/n”. Shouldn’t it be “\r\n”?
    But where is sending just “\r” or just “\n”?
    (One my device accepts commands ending with \r or \n. But when received \r it will start executing the command but then the next \n will make it stop outputting the results)
    “Send Char” is strange. It will change a number (decimal or hex) to a single character but it will NOT SEND it. Instead it will replace the entry field with this character and then I have to click “send” again.
    But even with this I cannot send ‘\r’ or ‘\n’ as 13 or 10 will not be converted to ‘\r’ or ‘\n’ but to ” (nothing)
    “Send Char” accepts numbers above 255. So this is the character ID from Unicode I think.
    So if I want to send the byte 0xFF, “send char” will convert it to “ÿ” but I’m afraid that sending it will not send 0xFF but the Unicode (utf-8?) encoding of “ÿ” (But I didn’t verify it with a logic analyser)
    When I send with echo then “> ” is appended to my text displayed on terminal.
    So “ABC” will become “> ABC”. When I send for example “ABC” one character at a time (without \r\n) it will become “> A> B> C”.

    1. Kiosks, ticket printers, information displays… Writing code for standard browsers greatly eases the development process and let’s you use readily available libraries, development and design talent (as opposed to, say, QT et al.)

  5. I did some reading about the WebSerial api and it’s strange that the possible flow control options are ‘hardware’ (which is RTS/CTS) and ‘none’.
    If some device requires DTR/DSR or XON/XOFF, the application will have to implement it on a higher level.

    1. I doubt the design plan was “implement all possible serial protocol variants.” It was probably “implement a minimal serial interface for the most common protocol variant.” If your needs are uncommon, you should probably use a dedicated serial terminal app.

  6. To all the people wondering why anyone would use Web Serial, I have a few reasons to offer.

    For initial configuration of a device. If you present a web site that a user can go to that will connect to your device and offer a nice user interface for configuration of that device, then the user doesn’t have to download and install any software. This is a huge plus for groups who don’t want to have to make apps for ios, android, mac, windows, and linux and can instead make a single web site and host it on a domain the user trusts. As an example, I’m working on a product that is a BLE-WiFi gateway for an IoT device. This gateway gets power over USB and has no buttons or display. To configure the WiFi credentials, you could do what all the other companies do and present as a WiFi access point and require the user switch their WiFi to that access point and then go to a web page hosted on that device, or use a custom app you have to download. What we have chosen to do is tell the user to plug it in, either to a computer or to a charger, and go to a url we host. If the user is plugged in to the computer, we can use Web Serial to send the WiFi credentials. If it’s plugged in to a charger we can use Web Bluetooth. Either way uses the same workflow for the user, doesn’t require they download any software, and doesn’t require they change their WiFi connection.

    The web serial terminal is particularly useful for developing test software. I have a device that I want to test, so rather than typing a bunch of commands I can easily create buttons for each of the common commands. Then I can parse and upload the responses automatically as well. And I can give the QA team access to this tool without having to give them something they need to install.

    The connection only lasts for the duration of the page being open. If it is refreshed, the connection is lost. If the tab is closed, the connection is lost. In order to connect you have to have the user click on the device when a popup appears, and there’s no way to get around it. An icon shows on the tab when a connection is active. They’ve really thought about security here, and in many ways it’s better than needing a downloaded application, which may require administrative privileges to install, may maintain a connection to the port even when the window is closed, may connect on its own to any serial device plugged in without the user’s knowledge, etc.

    If you don’t want to use serialterminal.com because you don’t trust that site, then that’s fair. But you can download the code and inspect it and host it yourself elsewhere with whatever additional features you want to add.

    1. For the example you give of configuring WiFi credentials, you may be interested in Improv WiFi: https://www.improv-wifi.com/

      It’s an open standard with open source libraries specifically aimed at solving this in a standardised way, using either Bluetooth LE or USB Serial. And it has libraries to do it in the browser, one using WebSerial (https://github.com/improv-wifi/sdk-serial-js) and one using WebBluetooth (https://github.com/improv-wifi/sdk-ble-js)

  7. For anyone interested in similar projects:

    ESP-Web-Tools uses WebSerial to flash firmware to ESP boards, mointor serial output, as well as automatically detect what type of ESP board is connected. It’s used by several projects, including ESPHome’s Dashboard, Tasmota, WLED, ESPEasy, and CanAirIO. https://esphome.github.io/esp-web-tools/

    Adafruit has built several tools using WebSerial:
    ESPTool to flash ESP devices: https://adafruit.github.io/Adafruit_WebSerial_ESPTool/
    WebSerial Plotter, which is like a web version of Arduino IDE’s serial plotter: https://adafruit.github.io/Adafruit_WebSerial_Plotter/
    WebSerial 3D Model Viewer, used to visual output from an IMU: https://adafruit.github.io/Adafruit_WebSerial_3DModelViewer/
    WebSerial IMU Calibration, for calibrating an IMU: https://adafruit.github.io/Adafruit_WebSerial_IMU_Calibration/

    Espressif also built their own WebSerial based tool for flashing their ESP chips: https://espressif.github.io/esptool-js/

    There’s a lot of potential there when you start combining it with things like VS Code running in the browser, and the ability to compile tools to WASM to run in the browser. You could now have an entire embedded development toolchain running in the browser with no install, no maintenance, and no server-side compute resources needed (just static files served). And it would work on say a Chromebook in a classroom.

  8. I guess I am old school. I prefer to do all my serial interfacing locally with minicom or putty … or my own applications. In a browser just seems intuitively not the right place for accessing hardware devices connected to my system. Each to their own though :) .

      1. Not sure what you mean. With putty or minicom (as examples) you don’t have to be connected to the internet to use. True, I may have initially installed from a repository the first time. However then the program is used locally on that computer, never pings the install server again. I prefer to just keep everything ‘in-house’ as much as possible. Only reason to ‘ever’ be on the internet is to access something that isn’t available locally. Like information on the 555 or install gfortran, or write this in this discussion as examples. Otherwise browser stays de-activated.

      2. But they have well defined and restricted interfaces. Also regarding WebGL some restrictions were applied, there too, for security reasons.

        Disk drive partitions or raw physical disks cannot be accessed, just a very limited set of files for user storage!

        Serial is not a well defined interface nor was it designed with any kind of security in mind, quite the opposite. It assumes a trusted environment.

  9. It would be terrible if someone broke into the non existent serial ports to talk to non existent hardware. 99.999 percent of users fall into this category. The rest are hacker types who apparently have appropriate levels of sophistication to handle the security issues.

  10. WebSerial really brought out the tinfoil hats in the comments.

    I am curious, my Ubuntu device tree has 32 serial TTYs, but I’ve used serial libraries that know that only ttyS0 is connected to a real serial port. Presumably the details can be inspected somehow, e.g. the `setserial` command shows only ttyS0 has a UART.

    Meanwhile this serialterminal web page shows all 32. Limitation of the WebSerial API? But perhaps if those phantom TTYs were filtered out it might appease some of the FUD being spread here.

    I may plug in a USB serial dongle and see if that’s detected or not, would be a shame if it isn’t.

    1. The webserial API has a filtering function that will let you filter ports based on USB ID information, but this intentionally-very-simple program does not use it. The source is available for anyone to modify should they wish to add bells and whistles.

      The serial ports that show up in your Ubuntu are probably placeholders for ports that might be connected at some point. The limitation is not in the webserial API but rather in the way that Linux discovers devices and handles the possibility of old-school non-USB serial ports. The set of possibilities is pretty complicated and it is hard to make something that works the way you want while being compatible with historical use cases that other people might want. Serial port discovery and handling have been a sore point since I first started using Unix in 1979.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.