@@ -47,12 +47,14 @@ func (a allInterpreters) AtLeast(minimalVersion string) (*Interpreter, error) {
4747
4848var ErrNoPythonInterpreters = errors .New ("no python3 interpreters found" )
4949
50+ const worldWriteable = 0o002
51+
5052func DetectInterpreters (ctx context.Context ) (allInterpreters , error ) {
5153 found := allInterpreters {}
5254 paths := strings .Split (os .Getenv ("PATH" ), string (os .PathListSeparator ))
5355 seen := map [string ]bool {}
5456 for _ , prefix := range paths {
55- entries , err := os .ReadDir (prefix )
57+ info , err := os .Stat (prefix )
5658 if errors .Is (err , fs .ErrNotExist ) {
5759 // some directories in $PATH may not exist
5860 continue
@@ -61,6 +63,27 @@ func DetectInterpreters(ctx context.Context) (allInterpreters, error) {
6163 // some directories we cannot list
6264 continue
6365 }
66+ if err != nil {
67+ return nil , fmt .Errorf ("stat %s: %w" , prefix , err )
68+ }
69+ if ! info .IsDir () {
70+ continue
71+ }
72+ perm := info .Mode ().Perm ()
73+ if perm & worldWriteable != 0 {
74+ // we try not to run any python binary that sits in a writable folder by all users.
75+ // this is mainly to avoid breaking the security model on a multi-user system.
76+ // If the PATH is pointing somewhere untrusted it is the user fault, but we can
77+ // help here.
78+ //
79+ // See https://github.com/databricks/cli/pull/805#issuecomment-1735403952
80+ continue
81+ }
82+ entries , err := os .ReadDir (prefix )
83+ if errors .Is (err , fs .ErrPermission ) {
84+ // some directories we cannot list
85+ continue
86+ }
6487 if err != nil {
6588 return nil , fmt .Errorf ("listing %s: %w" , prefix , err )
6689 }
0 commit comments