Why using the '-execdir' action is insecure for directory which is in the PATH?












15















Why this is insecure to using the combination of -execdir action of find while using -exec isn't?



When I'm running the below command I'm getting the following prompt message:



/path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

find: The current directory is included in the PATH environment variable, which is insecure
in combination with the -execdir action of find. Please remove the current directory
from your $PATH (that is, remove "." or leading or trailing colons)


What may caused this prompt appearing?










share|improve this question





























    15















    Why this is insecure to using the combination of -execdir action of find while using -exec isn't?



    When I'm running the below command I'm getting the following prompt message:



    /path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

    find: The current directory is included in the PATH environment variable, which is insecure
    in combination with the -execdir action of find. Please remove the current directory
    from your $PATH (that is, remove "." or leading or trailing colons)


    What may caused this prompt appearing?










    share|improve this question



























      15












      15








      15


      4






      Why this is insecure to using the combination of -execdir action of find while using -exec isn't?



      When I'm running the below command I'm getting the following prompt message:



      /path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

      find: The current directory is included in the PATH environment variable, which is insecure
      in combination with the -execdir action of find. Please remove the current directory
      from your $PATH (that is, remove "." or leading or trailing colons)


      What may caused this prompt appearing?










      share|improve this question
















      Why this is insecure to using the combination of -execdir action of find while using -exec isn't?



      When I'm running the below command I'm getting the following prompt message:



      /path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

      find: The current directory is included in the PATH environment variable, which is insecure
      in combination with the -execdir action of find. Please remove the current directory
      from your $PATH (that is, remove "." or leading or trailing colons)


      What may caused this prompt appearing?







      command-line environment-variables find






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 19 '17 at 12:34







      αғsнιη

















      asked May 8 '15 at 15:26









      αғsнιηαғsнιη

      24.4k2295157




      24.4k2295157






















          4 Answers
          4






          active

          oldest

          votes


















          18














          You could run the wrong program. Someone could make you run their program.



          The -execdir action runs your command from the directory that contains the file(s) found. When $PATH contains relative paths, such as . or anything that doesn't start with /, -execdir is insecure because a directory where a file is found (or another directory resolved relative to it) could also contain an executable of the same name as the one you are trying to run. That potentially untrusted executable would then get run instead.



          This could be deliberately exploited by another user to cause you to run their program, which might cause harm or breach data security, instead of the program you are trying to run. Or, less often, it might simply result in the wrong program inadvertently being run, even without anyone trying to make the problem happen.



          If everything in your PATH environment variable is an absolute path, this error should not occur, even if the directory you're searching and -execdiring from is contained in PATH. (I've checked that this works.) If you believe you don't have any relative directories in $PATH but are still getting this error, please update your question with details including the output of echo "$PATH".



          A concrete example.



          As an example of what could go wrong, suppose:




          • Alice has . in her $PATH because she wants to be able to run programs in whatever directory she's cd'd to, without bothering to prepend their names with ./.

          • Alice's frenemy Eve has shared /home/eve/shared with Alice.

          • Alice wants statistics (lines, words, bytes) on the .c files Eve has shared with her.


          So Alice runs:



          find ~eve/shared -name *.c -execdir wc {} ;


          Unfortunately for Alice, Eve has created her own script, named it wc, set it executable (chmod +x), and placed it clandestinely in one of the directories under /home/eve/shared. Eve's script looks like this:



          #!/bin/sh
          /usr/bin/wc "$@"
          do_evil # Eve replaces this command with whatver evil she wishes to do


          So when Alice uses find with -execdir to run wc on the files Eve has shared, and it gets to files in the same directory as Eve's custom wc script, Eve's wc runs--with all of Alice's privileges!



          (Being crafty, Eve has made her wc script act as a wrapper for the system wc, so Alice won't even know something has gone wrong, i.e., that do_evil was run. However, simpler--and also more sophisticated--variations are possible.)



          How find prevents this.



          find prevents this security problem from happening by refusing to take the -execdir action when $PATH contains a relative directory.



          find offers two diagnostic messages depending on the specific situation.





          • If . is in $PATH, then (as you've seen) it says:



            find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)



            It probably has a special message for the . case as it's especially common.




          • If a relative path other than .--say, foo--appears in $PATH and you run find with -execdir, it says:



            find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




          It's better not to have relative paths in $PATH at all.



          The risk of having . or other relative paths in $PATH is especially heightened when using a utility that automatically changes the directory, which is why find won't let you use -execdir in this situation.



          But having relative paths, especially ., in your $PATH is inherently risky and is really best avoided anyway. Consider the fictional situation in the example above. Suppose instead of running find, Alice simply cds to ~eve/shared/blah and runs wc *.c. If blah contains Eve's wc script, do_evil runs as Alice.






          share|improve this answer





















          • 2





            I don't know if you have heard this before that you would make a very good teacher :)

            – heemayl
            May 8 '15 at 17:26






          • 3





            @heemayl all those who write useful stuff on the net, are already teachers :-)

            – Ciro Santilli 新疆改造中心 六四事件 法轮功
            Jan 13 at 14:15



















          4














          There is a much detailed information here. Another excellent reference is here. To quote from the first reference:




          The option -execdir is a more modern option introduced in GNU find
          is an attempt to create a more safe version of -exec. It has the same
          semantic as -exec with two important enhancements:



          It always provides absolute path to the file (using relative path to a
          file is really dangerous in case of -exec).



          In addition to providing
          absolute path it also checks the PATH variable for safety (if dot is
          present in the PATH env variable, you can pickup executable from the
          wrong directory)




          From second reference:




          The ‘-execdir’ action refuses to do anything if the current directory
          is included in the $PATH environment variable. This is necessary
          because ‘-execdir’ runs programs in the same directory in which it
          finds files – in general, such a directory might be writable by
          untrusted users. For similar reasons, ‘-execdir’ does not allow ‘{}’
          to appear in the name of the command to be run.







          share|improve this answer


























          • Can you please extend your answer why "if dot is present in the PATH env variable, you can pickup executable from the wrong directory"? which wrong directory? And why we have to do this for making it secure? Thanks

            – αғsнιη
            May 8 '15 at 15:49













          • I hope the second link in my updated post will answer your question

            – Ron
            May 8 '15 at 15:59



















          2














          The main problem is with the value of system variable PATH which contains relative folders in it, so for security reasons find command won't allow you to execute binaries, because potentially it can execute wrong programs.





          So for example, if you have your current dir in your PATH as per warning which you get:




          The current directory is included in the PATH environment variable.




          and you'll run your command:



          find . -type f -name 'partOfFileNames*' -execdir rm -- {} +


          in case you'll have local script (rm with executable flags) containing rm -fr / in it, it can remove all your files, because instead of executing expected /bin/rm, you'll execute rm from the current dir, so probably it's not what you wanted.





          As a side note, this is known issue in Travis CI (GH #2811) when it fails with the error:




          find: The relative path `./node_modules/.bin' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




          So the solution is to remove affected entry from PATH variable, e.g.



          PATH=`echo $PATH | sed -e 's/:./node_modules/.bin//'`


          as proposed by drogus. The progress of this bug, can be followed at GH #4862.





          Here is Bash version workaround:



          PATH=${PATH//:./node_modules/.bin/}


          Example usage (passing filtered PATH to specific command):



          env PATH=${PATH//:./node_modules/.bin/} find . -type f





          share|improve this answer


























          • Here is a sed that seems to remove all things find does not like: askubuntu.com/questions/621132/…

            – Ciro Santilli 新疆改造中心 六四事件 法轮功
            Jan 13 at 14:07



















          2














          For those who have hopes that there exists a way to ignore find's opinionatedness, let me crush that with some source:




          • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2847

          • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2944


          From that we see that there seems to be no way to turn off the path checking.



          The exact rule it checks is: fail if the PATH is either empty or does not start with /.



          So the best I can do is to workaround with sed as:



          PATH="$(echo "$PATH" | sed -E 's/(^|:)[^/][^:]*//g')" find . -execdir echo '{}' ;


          A testcase:



          [ "$(printf '/a/b::c/d:/e/fn' | sed -E 's/(^|:)[^/][^:]*//g')" = '/a/b:/e/f' ] || echo fail


          For rename specifically, you can also work around with some Perl regex-fu: https://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971






          share|improve this answer

























            Your Answer








            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "89"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f621132%2fwhy-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            18














            You could run the wrong program. Someone could make you run their program.



            The -execdir action runs your command from the directory that contains the file(s) found. When $PATH contains relative paths, such as . or anything that doesn't start with /, -execdir is insecure because a directory where a file is found (or another directory resolved relative to it) could also contain an executable of the same name as the one you are trying to run. That potentially untrusted executable would then get run instead.



            This could be deliberately exploited by another user to cause you to run their program, which might cause harm or breach data security, instead of the program you are trying to run. Or, less often, it might simply result in the wrong program inadvertently being run, even without anyone trying to make the problem happen.



            If everything in your PATH environment variable is an absolute path, this error should not occur, even if the directory you're searching and -execdiring from is contained in PATH. (I've checked that this works.) If you believe you don't have any relative directories in $PATH but are still getting this error, please update your question with details including the output of echo "$PATH".



            A concrete example.



            As an example of what could go wrong, suppose:




            • Alice has . in her $PATH because she wants to be able to run programs in whatever directory she's cd'd to, without bothering to prepend their names with ./.

            • Alice's frenemy Eve has shared /home/eve/shared with Alice.

            • Alice wants statistics (lines, words, bytes) on the .c files Eve has shared with her.


            So Alice runs:



            find ~eve/shared -name *.c -execdir wc {} ;


            Unfortunately for Alice, Eve has created her own script, named it wc, set it executable (chmod +x), and placed it clandestinely in one of the directories under /home/eve/shared. Eve's script looks like this:



            #!/bin/sh
            /usr/bin/wc "$@"
            do_evil # Eve replaces this command with whatver evil she wishes to do


            So when Alice uses find with -execdir to run wc on the files Eve has shared, and it gets to files in the same directory as Eve's custom wc script, Eve's wc runs--with all of Alice's privileges!



            (Being crafty, Eve has made her wc script act as a wrapper for the system wc, so Alice won't even know something has gone wrong, i.e., that do_evil was run. However, simpler--and also more sophisticated--variations are possible.)



            How find prevents this.



            find prevents this security problem from happening by refusing to take the -execdir action when $PATH contains a relative directory.



            find offers two diagnostic messages depending on the specific situation.





            • If . is in $PATH, then (as you've seen) it says:



              find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)



              It probably has a special message for the . case as it's especially common.




            • If a relative path other than .--say, foo--appears in $PATH and you run find with -execdir, it says:



              find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            It's better not to have relative paths in $PATH at all.



            The risk of having . or other relative paths in $PATH is especially heightened when using a utility that automatically changes the directory, which is why find won't let you use -execdir in this situation.



            But having relative paths, especially ., in your $PATH is inherently risky and is really best avoided anyway. Consider the fictional situation in the example above. Suppose instead of running find, Alice simply cds to ~eve/shared/blah and runs wc *.c. If blah contains Eve's wc script, do_evil runs as Alice.






            share|improve this answer





















            • 2





              I don't know if you have heard this before that you would make a very good teacher :)

              – heemayl
              May 8 '15 at 17:26






            • 3





              @heemayl all those who write useful stuff on the net, are already teachers :-)

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:15
















            18














            You could run the wrong program. Someone could make you run their program.



            The -execdir action runs your command from the directory that contains the file(s) found. When $PATH contains relative paths, such as . or anything that doesn't start with /, -execdir is insecure because a directory where a file is found (or another directory resolved relative to it) could also contain an executable of the same name as the one you are trying to run. That potentially untrusted executable would then get run instead.



            This could be deliberately exploited by another user to cause you to run their program, which might cause harm or breach data security, instead of the program you are trying to run. Or, less often, it might simply result in the wrong program inadvertently being run, even without anyone trying to make the problem happen.



            If everything in your PATH environment variable is an absolute path, this error should not occur, even if the directory you're searching and -execdiring from is contained in PATH. (I've checked that this works.) If you believe you don't have any relative directories in $PATH but are still getting this error, please update your question with details including the output of echo "$PATH".



            A concrete example.



            As an example of what could go wrong, suppose:




            • Alice has . in her $PATH because she wants to be able to run programs in whatever directory she's cd'd to, without bothering to prepend their names with ./.

            • Alice's frenemy Eve has shared /home/eve/shared with Alice.

            • Alice wants statistics (lines, words, bytes) on the .c files Eve has shared with her.


            So Alice runs:



            find ~eve/shared -name *.c -execdir wc {} ;


            Unfortunately for Alice, Eve has created her own script, named it wc, set it executable (chmod +x), and placed it clandestinely in one of the directories under /home/eve/shared. Eve's script looks like this:



            #!/bin/sh
            /usr/bin/wc "$@"
            do_evil # Eve replaces this command with whatver evil she wishes to do


            So when Alice uses find with -execdir to run wc on the files Eve has shared, and it gets to files in the same directory as Eve's custom wc script, Eve's wc runs--with all of Alice's privileges!



            (Being crafty, Eve has made her wc script act as a wrapper for the system wc, so Alice won't even know something has gone wrong, i.e., that do_evil was run. However, simpler--and also more sophisticated--variations are possible.)



            How find prevents this.



            find prevents this security problem from happening by refusing to take the -execdir action when $PATH contains a relative directory.



            find offers two diagnostic messages depending on the specific situation.





            • If . is in $PATH, then (as you've seen) it says:



              find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)



              It probably has a special message for the . case as it's especially common.




            • If a relative path other than .--say, foo--appears in $PATH and you run find with -execdir, it says:



              find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            It's better not to have relative paths in $PATH at all.



            The risk of having . or other relative paths in $PATH is especially heightened when using a utility that automatically changes the directory, which is why find won't let you use -execdir in this situation.



            But having relative paths, especially ., in your $PATH is inherently risky and is really best avoided anyway. Consider the fictional situation in the example above. Suppose instead of running find, Alice simply cds to ~eve/shared/blah and runs wc *.c. If blah contains Eve's wc script, do_evil runs as Alice.






            share|improve this answer





















            • 2





              I don't know if you have heard this before that you would make a very good teacher :)

              – heemayl
              May 8 '15 at 17:26






            • 3





              @heemayl all those who write useful stuff on the net, are already teachers :-)

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:15














            18












            18








            18







            You could run the wrong program. Someone could make you run their program.



            The -execdir action runs your command from the directory that contains the file(s) found. When $PATH contains relative paths, such as . or anything that doesn't start with /, -execdir is insecure because a directory where a file is found (or another directory resolved relative to it) could also contain an executable of the same name as the one you are trying to run. That potentially untrusted executable would then get run instead.



            This could be deliberately exploited by another user to cause you to run their program, which might cause harm or breach data security, instead of the program you are trying to run. Or, less often, it might simply result in the wrong program inadvertently being run, even without anyone trying to make the problem happen.



            If everything in your PATH environment variable is an absolute path, this error should not occur, even if the directory you're searching and -execdiring from is contained in PATH. (I've checked that this works.) If you believe you don't have any relative directories in $PATH but are still getting this error, please update your question with details including the output of echo "$PATH".



            A concrete example.



            As an example of what could go wrong, suppose:




            • Alice has . in her $PATH because she wants to be able to run programs in whatever directory she's cd'd to, without bothering to prepend their names with ./.

            • Alice's frenemy Eve has shared /home/eve/shared with Alice.

            • Alice wants statistics (lines, words, bytes) on the .c files Eve has shared with her.


            So Alice runs:



            find ~eve/shared -name *.c -execdir wc {} ;


            Unfortunately for Alice, Eve has created her own script, named it wc, set it executable (chmod +x), and placed it clandestinely in one of the directories under /home/eve/shared. Eve's script looks like this:



            #!/bin/sh
            /usr/bin/wc "$@"
            do_evil # Eve replaces this command with whatver evil she wishes to do


            So when Alice uses find with -execdir to run wc on the files Eve has shared, and it gets to files in the same directory as Eve's custom wc script, Eve's wc runs--with all of Alice's privileges!



            (Being crafty, Eve has made her wc script act as a wrapper for the system wc, so Alice won't even know something has gone wrong, i.e., that do_evil was run. However, simpler--and also more sophisticated--variations are possible.)



            How find prevents this.



            find prevents this security problem from happening by refusing to take the -execdir action when $PATH contains a relative directory.



            find offers two diagnostic messages depending on the specific situation.





            • If . is in $PATH, then (as you've seen) it says:



              find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)



              It probably has a special message for the . case as it's especially common.




            • If a relative path other than .--say, foo--appears in $PATH and you run find with -execdir, it says:



              find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            It's better not to have relative paths in $PATH at all.



            The risk of having . or other relative paths in $PATH is especially heightened when using a utility that automatically changes the directory, which is why find won't let you use -execdir in this situation.



            But having relative paths, especially ., in your $PATH is inherently risky and is really best avoided anyway. Consider the fictional situation in the example above. Suppose instead of running find, Alice simply cds to ~eve/shared/blah and runs wc *.c. If blah contains Eve's wc script, do_evil runs as Alice.






            share|improve this answer















            You could run the wrong program. Someone could make you run their program.



            The -execdir action runs your command from the directory that contains the file(s) found. When $PATH contains relative paths, such as . or anything that doesn't start with /, -execdir is insecure because a directory where a file is found (or another directory resolved relative to it) could also contain an executable of the same name as the one you are trying to run. That potentially untrusted executable would then get run instead.



            This could be deliberately exploited by another user to cause you to run their program, which might cause harm or breach data security, instead of the program you are trying to run. Or, less often, it might simply result in the wrong program inadvertently being run, even without anyone trying to make the problem happen.



            If everything in your PATH environment variable is an absolute path, this error should not occur, even if the directory you're searching and -execdiring from is contained in PATH. (I've checked that this works.) If you believe you don't have any relative directories in $PATH but are still getting this error, please update your question with details including the output of echo "$PATH".



            A concrete example.



            As an example of what could go wrong, suppose:




            • Alice has . in her $PATH because she wants to be able to run programs in whatever directory she's cd'd to, without bothering to prepend their names with ./.

            • Alice's frenemy Eve has shared /home/eve/shared with Alice.

            • Alice wants statistics (lines, words, bytes) on the .c files Eve has shared with her.


            So Alice runs:



            find ~eve/shared -name *.c -execdir wc {} ;


            Unfortunately for Alice, Eve has created her own script, named it wc, set it executable (chmod +x), and placed it clandestinely in one of the directories under /home/eve/shared. Eve's script looks like this:



            #!/bin/sh
            /usr/bin/wc "$@"
            do_evil # Eve replaces this command with whatver evil she wishes to do


            So when Alice uses find with -execdir to run wc on the files Eve has shared, and it gets to files in the same directory as Eve's custom wc script, Eve's wc runs--with all of Alice's privileges!



            (Being crafty, Eve has made her wc script act as a wrapper for the system wc, so Alice won't even know something has gone wrong, i.e., that do_evil was run. However, simpler--and also more sophisticated--variations are possible.)



            How find prevents this.



            find prevents this security problem from happening by refusing to take the -execdir action when $PATH contains a relative directory.



            find offers two diagnostic messages depending on the specific situation.





            • If . is in $PATH, then (as you've seen) it says:



              find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)



              It probably has a special message for the . case as it's especially common.




            • If a relative path other than .--say, foo--appears in $PATH and you run find with -execdir, it says:



              find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            It's better not to have relative paths in $PATH at all.



            The risk of having . or other relative paths in $PATH is especially heightened when using a utility that automatically changes the directory, which is why find won't let you use -execdir in this situation.



            But having relative paths, especially ., in your $PATH is inherently risky and is really best avoided anyway. Consider the fictional situation in the example above. Suppose instead of running find, Alice simply cds to ~eve/shared/blah and runs wc *.c. If blah contains Eve's wc script, do_evil runs as Alice.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 11 '17 at 4:20

























            answered May 8 '15 at 16:55









            Eliah KaganEliah Kagan

            81.9k21227364




            81.9k21227364








            • 2





              I don't know if you have heard this before that you would make a very good teacher :)

              – heemayl
              May 8 '15 at 17:26






            • 3





              @heemayl all those who write useful stuff on the net, are already teachers :-)

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:15














            • 2





              I don't know if you have heard this before that you would make a very good teacher :)

              – heemayl
              May 8 '15 at 17:26






            • 3





              @heemayl all those who write useful stuff on the net, are already teachers :-)

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:15








            2




            2





            I don't know if you have heard this before that you would make a very good teacher :)

            – heemayl
            May 8 '15 at 17:26





            I don't know if you have heard this before that you would make a very good teacher :)

            – heemayl
            May 8 '15 at 17:26




            3




            3





            @heemayl all those who write useful stuff on the net, are already teachers :-)

            – Ciro Santilli 新疆改造中心 六四事件 法轮功
            Jan 13 at 14:15





            @heemayl all those who write useful stuff on the net, are already teachers :-)

            – Ciro Santilli 新疆改造中心 六四事件 法轮功
            Jan 13 at 14:15













            4














            There is a much detailed information here. Another excellent reference is here. To quote from the first reference:




            The option -execdir is a more modern option introduced in GNU find
            is an attempt to create a more safe version of -exec. It has the same
            semantic as -exec with two important enhancements:



            It always provides absolute path to the file (using relative path to a
            file is really dangerous in case of -exec).



            In addition to providing
            absolute path it also checks the PATH variable for safety (if dot is
            present in the PATH env variable, you can pickup executable from the
            wrong directory)




            From second reference:




            The ‘-execdir’ action refuses to do anything if the current directory
            is included in the $PATH environment variable. This is necessary
            because ‘-execdir’ runs programs in the same directory in which it
            finds files – in general, such a directory might be writable by
            untrusted users. For similar reasons, ‘-execdir’ does not allow ‘{}’
            to appear in the name of the command to be run.







            share|improve this answer


























            • Can you please extend your answer why "if dot is present in the PATH env variable, you can pickup executable from the wrong directory"? which wrong directory? And why we have to do this for making it secure? Thanks

              – αғsнιη
              May 8 '15 at 15:49













            • I hope the second link in my updated post will answer your question

              – Ron
              May 8 '15 at 15:59
















            4














            There is a much detailed information here. Another excellent reference is here. To quote from the first reference:




            The option -execdir is a more modern option introduced in GNU find
            is an attempt to create a more safe version of -exec. It has the same
            semantic as -exec with two important enhancements:



            It always provides absolute path to the file (using relative path to a
            file is really dangerous in case of -exec).



            In addition to providing
            absolute path it also checks the PATH variable for safety (if dot is
            present in the PATH env variable, you can pickup executable from the
            wrong directory)




            From second reference:




            The ‘-execdir’ action refuses to do anything if the current directory
            is included in the $PATH environment variable. This is necessary
            because ‘-execdir’ runs programs in the same directory in which it
            finds files – in general, such a directory might be writable by
            untrusted users. For similar reasons, ‘-execdir’ does not allow ‘{}’
            to appear in the name of the command to be run.







            share|improve this answer


























            • Can you please extend your answer why "if dot is present in the PATH env variable, you can pickup executable from the wrong directory"? which wrong directory? And why we have to do this for making it secure? Thanks

              – αғsнιη
              May 8 '15 at 15:49













            • I hope the second link in my updated post will answer your question

              – Ron
              May 8 '15 at 15:59














            4












            4








            4







            There is a much detailed information here. Another excellent reference is here. To quote from the first reference:




            The option -execdir is a more modern option introduced in GNU find
            is an attempt to create a more safe version of -exec. It has the same
            semantic as -exec with two important enhancements:



            It always provides absolute path to the file (using relative path to a
            file is really dangerous in case of -exec).



            In addition to providing
            absolute path it also checks the PATH variable for safety (if dot is
            present in the PATH env variable, you can pickup executable from the
            wrong directory)




            From second reference:




            The ‘-execdir’ action refuses to do anything if the current directory
            is included in the $PATH environment variable. This is necessary
            because ‘-execdir’ runs programs in the same directory in which it
            finds files – in general, such a directory might be writable by
            untrusted users. For similar reasons, ‘-execdir’ does not allow ‘{}’
            to appear in the name of the command to be run.







            share|improve this answer















            There is a much detailed information here. Another excellent reference is here. To quote from the first reference:




            The option -execdir is a more modern option introduced in GNU find
            is an attempt to create a more safe version of -exec. It has the same
            semantic as -exec with two important enhancements:



            It always provides absolute path to the file (using relative path to a
            file is really dangerous in case of -exec).



            In addition to providing
            absolute path it also checks the PATH variable for safety (if dot is
            present in the PATH env variable, you can pickup executable from the
            wrong directory)




            From second reference:




            The ‘-execdir’ action refuses to do anything if the current directory
            is included in the $PATH environment variable. This is necessary
            because ‘-execdir’ runs programs in the same directory in which it
            finds files – in general, such a directory might be writable by
            untrusted users. For similar reasons, ‘-execdir’ does not allow ‘{}’
            to appear in the name of the command to be run.








            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited May 8 '15 at 15:57

























            answered May 8 '15 at 15:38









            RonRon

            14.6k44058




            14.6k44058













            • Can you please extend your answer why "if dot is present in the PATH env variable, you can pickup executable from the wrong directory"? which wrong directory? And why we have to do this for making it secure? Thanks

              – αғsнιη
              May 8 '15 at 15:49













            • I hope the second link in my updated post will answer your question

              – Ron
              May 8 '15 at 15:59



















            • Can you please extend your answer why "if dot is present in the PATH env variable, you can pickup executable from the wrong directory"? which wrong directory? And why we have to do this for making it secure? Thanks

              – αғsнιη
              May 8 '15 at 15:49













            • I hope the second link in my updated post will answer your question

              – Ron
              May 8 '15 at 15:59

















            Can you please extend your answer why "if dot is present in the PATH env variable, you can pickup executable from the wrong directory"? which wrong directory? And why we have to do this for making it secure? Thanks

            – αғsнιη
            May 8 '15 at 15:49







            Can you please extend your answer why "if dot is present in the PATH env variable, you can pickup executable from the wrong directory"? which wrong directory? And why we have to do this for making it secure? Thanks

            – αғsнιη
            May 8 '15 at 15:49















            I hope the second link in my updated post will answer your question

            – Ron
            May 8 '15 at 15:59





            I hope the second link in my updated post will answer your question

            – Ron
            May 8 '15 at 15:59











            2














            The main problem is with the value of system variable PATH which contains relative folders in it, so for security reasons find command won't allow you to execute binaries, because potentially it can execute wrong programs.





            So for example, if you have your current dir in your PATH as per warning which you get:




            The current directory is included in the PATH environment variable.




            and you'll run your command:



            find . -type f -name 'partOfFileNames*' -execdir rm -- {} +


            in case you'll have local script (rm with executable flags) containing rm -fr / in it, it can remove all your files, because instead of executing expected /bin/rm, you'll execute rm from the current dir, so probably it's not what you wanted.





            As a side note, this is known issue in Travis CI (GH #2811) when it fails with the error:




            find: The relative path `./node_modules/.bin' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            So the solution is to remove affected entry from PATH variable, e.g.



            PATH=`echo $PATH | sed -e 's/:./node_modules/.bin//'`


            as proposed by drogus. The progress of this bug, can be followed at GH #4862.





            Here is Bash version workaround:



            PATH=${PATH//:./node_modules/.bin/}


            Example usage (passing filtered PATH to specific command):



            env PATH=${PATH//:./node_modules/.bin/} find . -type f





            share|improve this answer


























            • Here is a sed that seems to remove all things find does not like: askubuntu.com/questions/621132/…

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:07
















            2














            The main problem is with the value of system variable PATH which contains relative folders in it, so for security reasons find command won't allow you to execute binaries, because potentially it can execute wrong programs.





            So for example, if you have your current dir in your PATH as per warning which you get:




            The current directory is included in the PATH environment variable.




            and you'll run your command:



            find . -type f -name 'partOfFileNames*' -execdir rm -- {} +


            in case you'll have local script (rm with executable flags) containing rm -fr / in it, it can remove all your files, because instead of executing expected /bin/rm, you'll execute rm from the current dir, so probably it's not what you wanted.





            As a side note, this is known issue in Travis CI (GH #2811) when it fails with the error:




            find: The relative path `./node_modules/.bin' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            So the solution is to remove affected entry from PATH variable, e.g.



            PATH=`echo $PATH | sed -e 's/:./node_modules/.bin//'`


            as proposed by drogus. The progress of this bug, can be followed at GH #4862.





            Here is Bash version workaround:



            PATH=${PATH//:./node_modules/.bin/}


            Example usage (passing filtered PATH to specific command):



            env PATH=${PATH//:./node_modules/.bin/} find . -type f





            share|improve this answer


























            • Here is a sed that seems to remove all things find does not like: askubuntu.com/questions/621132/…

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:07














            2












            2








            2







            The main problem is with the value of system variable PATH which contains relative folders in it, so for security reasons find command won't allow you to execute binaries, because potentially it can execute wrong programs.





            So for example, if you have your current dir in your PATH as per warning which you get:




            The current directory is included in the PATH environment variable.




            and you'll run your command:



            find . -type f -name 'partOfFileNames*' -execdir rm -- {} +


            in case you'll have local script (rm with executable flags) containing rm -fr / in it, it can remove all your files, because instead of executing expected /bin/rm, you'll execute rm from the current dir, so probably it's not what you wanted.





            As a side note, this is known issue in Travis CI (GH #2811) when it fails with the error:




            find: The relative path `./node_modules/.bin' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            So the solution is to remove affected entry from PATH variable, e.g.



            PATH=`echo $PATH | sed -e 's/:./node_modules/.bin//'`


            as proposed by drogus. The progress of this bug, can be followed at GH #4862.





            Here is Bash version workaround:



            PATH=${PATH//:./node_modules/.bin/}


            Example usage (passing filtered PATH to specific command):



            env PATH=${PATH//:./node_modules/.bin/} find . -type f





            share|improve this answer















            The main problem is with the value of system variable PATH which contains relative folders in it, so for security reasons find command won't allow you to execute binaries, because potentially it can execute wrong programs.





            So for example, if you have your current dir in your PATH as per warning which you get:




            The current directory is included in the PATH environment variable.




            and you'll run your command:



            find . -type f -name 'partOfFileNames*' -execdir rm -- {} +


            in case you'll have local script (rm with executable flags) containing rm -fr / in it, it can remove all your files, because instead of executing expected /bin/rm, you'll execute rm from the current dir, so probably it's not what you wanted.





            As a side note, this is known issue in Travis CI (GH #2811) when it fails with the error:




            find: The relative path `./node_modules/.bin' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH




            So the solution is to remove affected entry from PATH variable, e.g.



            PATH=`echo $PATH | sed -e 's/:./node_modules/.bin//'`


            as proposed by drogus. The progress of this bug, can be followed at GH #4862.





            Here is Bash version workaround:



            PATH=${PATH//:./node_modules/.bin/}


            Example usage (passing filtered PATH to specific command):



            env PATH=${PATH//:./node_modules/.bin/} find . -type f






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 13 at 14:34

























            answered Sep 28 '15 at 20:47









            kenorbkenorb

            4,40513953




            4,40513953













            • Here is a sed that seems to remove all things find does not like: askubuntu.com/questions/621132/…

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:07



















            • Here is a sed that seems to remove all things find does not like: askubuntu.com/questions/621132/…

              – Ciro Santilli 新疆改造中心 六四事件 法轮功
              Jan 13 at 14:07

















            Here is a sed that seems to remove all things find does not like: askubuntu.com/questions/621132/…

            – Ciro Santilli 新疆改造中心 六四事件 法轮功
            Jan 13 at 14:07





            Here is a sed that seems to remove all things find does not like: askubuntu.com/questions/621132/…

            – Ciro Santilli 新疆改造中心 六四事件 法轮功
            Jan 13 at 14:07











            2














            For those who have hopes that there exists a way to ignore find's opinionatedness, let me crush that with some source:




            • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2847

            • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2944


            From that we see that there seems to be no way to turn off the path checking.



            The exact rule it checks is: fail if the PATH is either empty or does not start with /.



            So the best I can do is to workaround with sed as:



            PATH="$(echo "$PATH" | sed -E 's/(^|:)[^/][^:]*//g')" find . -execdir echo '{}' ;


            A testcase:



            [ "$(printf '/a/b::c/d:/e/fn' | sed -E 's/(^|:)[^/][^:]*//g')" = '/a/b:/e/f' ] || echo fail


            For rename specifically, you can also work around with some Perl regex-fu: https://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971






            share|improve this answer






























              2














              For those who have hopes that there exists a way to ignore find's opinionatedness, let me crush that with some source:




              • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2847

              • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2944


              From that we see that there seems to be no way to turn off the path checking.



              The exact rule it checks is: fail if the PATH is either empty or does not start with /.



              So the best I can do is to workaround with sed as:



              PATH="$(echo "$PATH" | sed -E 's/(^|:)[^/][^:]*//g')" find . -execdir echo '{}' ;


              A testcase:



              [ "$(printf '/a/b::c/d:/e/fn' | sed -E 's/(^|:)[^/][^:]*//g')" = '/a/b:/e/f' ] || echo fail


              For rename specifically, you can also work around with some Perl regex-fu: https://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971






              share|improve this answer




























                2












                2








                2







                For those who have hopes that there exists a way to ignore find's opinionatedness, let me crush that with some source:




                • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2847

                • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2944


                From that we see that there seems to be no way to turn off the path checking.



                The exact rule it checks is: fail if the PATH is either empty or does not start with /.



                So the best I can do is to workaround with sed as:



                PATH="$(echo "$PATH" | sed -E 's/(^|:)[^/][^:]*//g')" find . -execdir echo '{}' ;


                A testcase:



                [ "$(printf '/a/b::c/d:/e/fn' | sed -E 's/(^|:)[^/][^:]*//g')" = '/a/b:/e/f' ] || echo fail


                For rename specifically, you can also work around with some Perl regex-fu: https://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971






                share|improve this answer















                For those who have hopes that there exists a way to ignore find's opinionatedness, let me crush that with some source:




                • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2847

                • https://git.savannah.gnu.org/cgit/findutils.git/tree/find/parser.c?h=v4.6.0#n2944


                From that we see that there seems to be no way to turn off the path checking.



                The exact rule it checks is: fail if the PATH is either empty or does not start with /.



                So the best I can do is to workaround with sed as:



                PATH="$(echo "$PATH" | sed -E 's/(^|:)[^/][^:]*//g')" find . -execdir echo '{}' ;


                A testcase:



                [ "$(printf '/a/b::c/d:/e/fn' | sed -E 's/(^|:)[^/][^:]*//g')" = '/a/b:/e/f' ] || echo fail


                For rename specifically, you can also work around with some Perl regex-fu: https://stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 13 at 15:03

























                answered Jan 13 at 14:06









                Ciro Santilli 新疆改造中心 六四事件 法轮功Ciro Santilli 新疆改造中心 六四事件 法轮功

                9,61944448




                9,61944448






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Ask Ubuntu!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f621132%2fwhy-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Mouse cursor on multiple screens with different PPI

                    Agildo Ribeiro

                    Sometime when accessing a menu: “Ubuntu 16.04 has experienced an internal error”