python.lang.security.audit.insecure-file-permissions.insecure-file-permissions

profile photo of semgrepsemgrep
Author
unknown
Download Count*

These permissions $BITS are widely permissive and grant access to more people than may be necessary. A good default is 0o644 which gives read and write access to yourself and read access to everyone else.

Run Locally

Run in CI

Defintion

rules:
  - id: insecure-file-permissions
    languages:
      - python
    severity: WARNING
    metadata:
      category: security
      owasp:
        - A01:2021 - Broken Access Control
      cwe:
        - "CWE-276: Incorrect Default Permissions"
      technology:
        - python
      references:
        - https://owasp.org/Top10/A01_2021-Broken_Access_Control
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: LOW
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Improper Authorization
    message: These permissions `$BITS` are widely permissive and grant access to
      more people than may be necessary. A good default is `0o644` which gives
      read and write access to yourself and read access to everyone else.
    patterns:
      - pattern-inside: os.$METHOD(...)
      - metavariable-pattern:
          metavariable: $METHOD
          patterns:
            - pattern-either:
                - pattern: chmod
                - pattern: lchmod
                - pattern: fchmod
      - pattern-either:
          - patterns:
              - pattern: os.$METHOD($FILE, $BITS, ...)
              - metavariable-comparison:
                  metavariable: $BITS
                  comparison: $BITS >= 0o650 and $BITS < 0o100000
          - patterns:
              - pattern: os.$METHOD($FILE, $BITS)
              - metavariable-comparison:
                  metavariable: $BITS
                  comparison: $BITS >= 0o100650
          - patterns:
              - pattern: os.$METHOD($FILE, $BITS, ...)
              - metavariable-pattern:
                  metavariable: $BITS
                  patterns:
                    - pattern-either:
                        - pattern: <... stat.S_IWGRP ...>
                        - pattern: <... stat.S_IXGRP ...>
                        - pattern: <... stat.S_IWOTH ...>
                        - pattern: <... stat.S_IXOTH ...>
                        - pattern: <... stat.S_IRWXO ...>
                        - pattern: <... stat.S_IRWXG ...>
          - patterns:
              - pattern: os.$METHOD($FILE, $EXPR | $MOD, ...)
              - metavariable-comparison:
                  metavariable: $MOD
                  comparison: $MOD == 0o111

Examples

insecure-file-permissions.py

import os

# ruleid:insecure-file-permissions
os.chmod("file", 0o777)
# ruleid:insecure-file-permissions
os.chmod("file", 511)
# ruleid:insecure-file-permissions
os.chmod("file", 0x1ff)
# ruleid:insecure-file-permissions
os.chmod("file", 0o776)
# ruleid:insecure-file-permissions
os.chmod("file", 0o775)
# ruleid:insecure-file-permissions
os.chmod("file", 0o774)
# ruleid:insecure-file-permissions
os.chmod("file", 0o767)
# ruleid:insecure-file-permissions
os.chmod("file", 0o757)
# ruleid:insecure-file-permissions
os.chmod("file", 0o747)
# ruleid:insecure-file-permissions
os.chmod("file", 0o654)
# ruleid:insecure-file-permissions
os.chmod("file", 0o100777)
# ruleid:insecure-file-permissions
os.chmod("file", 0o100775)
# ruleid:insecure-file-permissions
os.chmod("file", 0o100774)
# ruleid:insecure-file-permissions
os.chmod("file", 0o100767)
# ruleid:insecure-file-permissions
os.lchmod("file", 0o747)
# ruleid:insecure-file-permissions
os.lchmod("file", 0o100777)
f = open("file", 'w')
# ruleid:insecure-file-permissions
os.fchmod(f, 0o654)
# ruleid:insecure-file-permissions
os.fchmod(f, 0o100775)


# ok:insecure-file-permissions
os.fchmod(f, 423)
# ok:insecure-file-permissions
os.fchmod(f, 0x1a1)

import stat
# ruleid:insecure-file-permissions
os.chmod("file", stat.S_IRWXU | stat.S_IRGRP | stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH)

# Try to inject Semgrep. Perms end up OK.
# ok:insecure-file-permissions
os.chmod("file", stat.S_IRWXU | print("GOTCHA"))

# Try to inject Semgrep.
# ruleid:insecure-file-permissions
os.chmod("file", stat.S_IRWXO | print("GOTCHA"))

def ensure_exec_perms(file_):
    st = os.stat(file_)
    # ruleid:insecure-file-permissions
    os.chmod(file_, st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
    return file_

def ensure_exec_perms2(file_):
    st = os.stat(file_)
    # ruleid:insecure-file-permissions
    os.chmod(file_, st.st_mode | 0o111)
    return file_

# ok:insecure-file-permissions
os.chmod("file", 0o644)
# ok:insecure-file-permissions
os.chmod("file", 0o444)
# ok:insecure-file-permissions
os.chmod("file", stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
# ok:insecure-file-permissions
os.chmod("file", stat.S_IRWXU)