Write to a file without redirection?

20,154

Solution 1

How about this:

echo -n 'magic' | sudo tee /some/where/file > /dev/null

Sure there are redirections in this but only tee runs as root not a shell. Works with dd of=... too.

Solution 2

Without output redirect, without pipe, but with "here string":

dd of=/some/where/file <<<'magic'

Solution 3

There's another consideration, which is that you don't want to put the value of the magic cookie on a command line, since that can be observed by other users. Even if the program is short-lived (including if the program zeros out the command line string), there is the opportunity for attack. So, a theoretical:

writestringtofile 'magic' /some/where/file

is a dangerous approach. Therefore, I endorse @stribika's suggestion: write the value to a temporary file and copy it into place. Make sure to use a secure function to create the temporary file (mkstemp()) so that there's not a race condition there as well.

Solution 4

sponge from moreutils - soak up standard input and write to a file:

echo -n 'magic' | sponge /some/where/file

Unlike a shell redirect, sponge soaks up all its input before writing the output file. When possible, sponge creates or updates the output file atomically by renaming a temp file into place.

See more

Share:
20,154

Related videos on Youtube

zoul
Author by

zoul

Updated on September 17, 2022

Comments

  • zoul
    zoul over 1 year

    I am writing a regular compiled application that needs to create a special file and write a magic cookie into it. I can’t write the file directly from the application, the system security model requires me to launch a helper tool with elevated privileges to do the trick. I can supply any number of arguments to the helper tool. Now I would like to pick some very simple system command that would serve as the helper tool and create the file for me. Something like this:

    /bin/sh -c "/bin/echo -n 'magic' > /some/where/file"

    Simple touch does not cut it as I need to write the cookie into the file, a simple echo without the shell wrapper does not work as it needs redirection to write the file. I don’t feel comfortable calling the shell with root privileges to do such a trivial task. Is there some really simple, constrained system command that I could call to write the file for me?

    • Arcege
      Arcege about 13 years
      Is there a reason why /bin/sh -c 'echo magic > /path/to/magic/file' does not work? That would be an executable file and two arguments. You would need to build the last argument as a string (with sprintf or equivalent). Is there as reason this wouldn't work for you? From your question it sounds like doCommandAsRoot() does not take input to stream to the command, correct? Otherwise you could replace the last argument with 'cat > /path/to/magic/file' and pass the data instead of constructing a string.
    • zoul
      zoul about 13 years
      The shell example works, but I’d hate to call the shell with root privileges just to create a simple file. The library does take a communication pipe argument (it’s AuthorizationExecuteWithPrivileges), that could be used to write the cookie using tee. Thanks!
    • LDS
      LDS over 7 years
  • zoul
    zoul about 13 years
    Sorry, I obviously have trouble explaining myself lately. The problem is that when I want to run something with the elevated privileges, I have to go through a special library call (something like doCommandAsRoot). And this function only accepts a path to the command and its arguments, so there’s no way for me to use output redirection right away. I could go through shell (as shown in the question), but I don’t like that security-wise.
  • stribika
    stribika about 13 years
    @zoul: I thought you are writing a shell script. Is it OK to write the magic cookie to a file that is accessible for unprivileged processes? If it is then write it to such a file and call doCommandAsRoot("dd", "if=/tmp/unprotected_file", "of=/some/where/file").
  • zoul
    zoul about 13 years
    No, it’s a regular compiled application (question updated). I’m just looking for “shell” commands to serve as the helper so that I don’t have to write it myself. Yes, the cookie is nothing sensitive. The dd example is pretty close to what I want, thank you. Could you think of something even simpler?
  • mattdm
    mattdm about 13 years
    Sure — you could use cp or mv instead of dd.
  • zoul
    zoul about 13 years
    I mean simpler as without the need to copy :)
  • mattdm
    mattdm about 13 years
    I don't think there are any standard programs which take a value on the command line and write that value to a file. However, since the command line and arguments aren't necessarily secure from snooping, you probably shouldn't do that with a magic cookie value anyway. So the copy approach is the best one I can think of.
  • zoul
    zoul about 13 years
    Thank you, this is a useful discussion. Fortunately the “magic cookie” is not a security device, it can be plainly seen by anybody.
  • Daco
    Daco almost 6 years
    One downside of this approach is dd writes some stats to stdout. You can use > /dev/null to hide them, but at that point you might as well use tee.
  • Amitav Pajni
    Amitav Pajni over 4 years
    This worked for me in an unusual situation where I could not use output redirection or pipes. status=none will suppress all other output from modern versions of GNU coreutils dd.
  • fei0x
    fei0x about 3 years
    Yes, i used this to set data to a file inside an LXD container: lxc exec $LXC -- dd of=/path/to/file/file.txt <<< "$MYMESSAGE" &> /dev/null