Terrible title but I will do my best to explain.

I have a simple robot that uses an Arduino Uno plugged into the USB. To interact with this as serial it requires me to run the application under sudo. I then take that command and create an interface to run it using NodeJS and Koa using exec sync...

export class Movement extends SubRoute {
  constructor() {
    this.setRoute('get', '/forward', this.onForwardGet.bind(this));
  async onForwardGet(ctx) {
        const stdOut = execSync("python3 /.../Code/pi-serial-example/robot/python/robot-hack/forward.py")
        ctx.body = stdOut.toString('utf-8');
    } catch(err){
        // TODO: Remove error message
        ctx.body = `There was an internal service error ${err}`;
        ctx.response.status = 500;

// Another example using just Node...

const port = new SerialPort('/dev/ttyACM0', {
  baudRate: 115200

port.on('readable', function () {
  let record
  while (record = port.read()) {
    console.log(`The collection is \n ${JSON.stringify(output)}`);
port.on('error', function(err) {
  console.log('Error: ', err.message);
port.on('close', function(){
  console.log('The port is closed');
port.on('open', err =>{
  console.log("The port is opened");

Now in order to run this I have to run the entire node application under sudo like...

sudo node --experimental-modules server.mjs

This seems like a security risk, it seems like I should be able to escalate individual requests instead of the entire app. What is the way to handle this more securely?

  • 1
    Assuming the code normally runs under www-data could you try adding that user to the dialout and / or GPIO groups?
    – user115418
    Apr 14, 2020 at 15:53
  • Not sure if you will need to restart all www-data services or reboot for this to take place - sorry forgot till just now and edit has gone!
    – user115418
    Apr 14, 2020 at 15:59
  • Probably not what you want to do but a conventional solution would be to use a separate back-end. Instead of working the hardware directly, the web server passes requests on to a local server that's not accessible from outside. This way the web server can be run without privileges so that if compromised it can be reasonably contained.
    – goldilocks
    Apr 14, 2020 at 18:12
  • @goldilocks, thank you, even if it was on another app wouldn't I still need elevated permissions? I think you also misunderstand my architecture I can write straight C code and import it using a native node module but that isn't going to change the fact I need to elevate for it to run.
    – Jackie
    Apr 14, 2020 at 18:20
  • The best solution in context is to just add the www server process user to a group with permissions on the dev node, but short of that (or alongside, which might be overkill), using the separate backend, the www server does not need special permissions, only the backend does (eg., likely pigpiod could be used here). But that backend can only be accessed by local processes (this is easy to ensure via firewall, etc). Is there still a security risk if that process is running root?
    – goldilocks
    Apr 15, 2020 at 14:04


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.