node.jslinuxdockerdockerfilesudoers

container Docker get sudo not found error


i am currently making a react application with a backend

i have made page that let me change the date of my machine using a nodejs code,

the command to change the date is : sudo date -s "2024-05-29 15:13:00" as you can see there is a sudo,

i have changed the sudoers file to let everyone change the date of my machine :

Cmnd_Alias DATEE=/bin/date
ALL ALL=NOPASSWD: DATEE

and everything was working fine ,

the thing is : when i am running my application in a container docker , i get the error : /bin/sh: sudo: not found if you have any idea on how to modify my docker to make it work.

here is the dockerfile of my application :

FROM docker.io/node:14-alpine as build

WORKDIR /app

COPY package*.json ./

RUN npm install

RUN npm install -g nodemon

COPY . .

COPY get_host_ip.sh /usr/local/bin/get_host_ip.sh

RUN npm prune --production

RUN chmod +x /usr/local/bin/get_host_ip.sh

RUN ls -l /app/start.sh && cat /app/start.sh && chmod +x /app/start.sh

EXPOSE 8080 8000

CMD ["/usr/local/bin/get_host_ip.sh", "sh", "-c", "./start.sh"]

and here is the code of my backend :

exports.UpdateDate = (req, res, next) => {
    const payload = req.body;
    const date = payload.date;
console.log(date);
const command = `sudo date -s "${date}"`;
    exec(command, (error, stdout, stderr) => {
        if (error) {
          console.error(`Erreur lors de l'exécution de la commande : ${error.message}`);
          res.status(500).send("Erreur interne du serveur");
          return;
        }
        if (stderr) {
          console.error(`Erreur lors de l'exécution de la commande : ${stderr}`);
          res.status(500).send("Erreur interne du serveur");
          return;
        }
        console.log(stdout);
        res.send(stdout);
      });
;
};

i have tried to build my image using sudo , run it like that but nothing seems to work


Solution

  • In a Docker context, you don't need sudo. Linux has a set of capabilities(7) that control more specific privileges, and if the process has the CAP_SYS_TIME capability then it can change the system time. When you run the container, docker run has a --cap-add option to add arbitrary capabilities to the main container process.

    You should be able to change your code to remove the sudo call (and the shell-injection vulnerability), like

    execFile('date', ['-s', date], (error, stdout, stderr) => { ... });
    

    (You may need to use util.promisify(), make the handler function be async, and handle the result using await to ensure the HTTP response object is still valid when the process completes.)

    When you run the container, give it CAP_SYS_TIME

    docker run --cap-add SYS_TIME ... your-image