<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Guidelines for shell commands in the GitLab codebase > 原文:[https://docs.gitlab.com/ee/development/shell_commands.html](https://docs.gitlab.com/ee/development/shell_commands.html) * [References](#references) * [Use File and FileUtils instead of shell commands](#use-file-and-fileutils-instead-of-shell-commands) * [Always use the configurable Git binary path for Git commands](#always-use-the-configurable-git-binary-path-for-git-commands) * [Bypass the shell by splitting commands into separate tokens](#bypass-the-shell-by-splitting-commands-into-separate-tokens) * [Separate options from arguments with –](#separate-options-from-arguments-with---) * [Do not use the backticks](#do-not-use-the-backticks) * [Avoid user input at the start of path strings](#avoid-user-input-at-the-start-of-path-strings) * [Guard against path traversal](#guard-against-path-traversal) * [Properly anchor regular expressions to the start and end of strings](#properly-anchor-regular-expressions-to-the-start-and-end-of-strings) # Guidelines for shell commands in the GitLab codebase[](#guidelines-for-shell-commands-in-the-gitlab-codebase "Permalink") 本文檔包含使用 GitLab 代碼庫中的進程和文件的準則. 這些準則旨在使您的代碼更加可靠*和*安全. ## References[](#references "Permalink") * [Google Ruby Security Reviewer’s Guide](https://code.google.com/archive/p/ruby-security/wikis/Guide.wiki) * [OWASP Command Injection](https://wiki.owasp.org/index.php/Command_Injection) * [Ruby on Rails Security Guide Command Line Injection](https://guides.rubyonrails.org/security.html#command-line-injection) ## Use File and FileUtils instead of shell commands[](#use-file-and-fileutils-instead-of-shell-commands "Permalink") 有時,當還有 Ruby API 可以通過外殼調用基本的 Unix 命令時. 使用 Ruby API(如果存在). [http://www.ruby-doc.org/stdlib-2.0.0/libdoc/fileutils/rdoc/FileUtils.html#module-FileUtils-label-Module+Functions](http://www.ruby-doc.org/stdlib-2.0.0/libdoc/fileutils/rdoc/FileUtils.html#module-FileUtils-label-Module+Functions) ``` # Wrong system "mkdir -p tmp/special/directory" # Better (separate tokens) system *%W(mkdir -p tmp/special/directory) # Best (do not use a shell command) FileUtils.mkdir_p "tmp/special/directory" # Wrong contents = `cat #{filename}` # Correct contents = File.read(filename) # Sometimes a shell command is just the best solution. The example below has no # user input, and is hard to implement correctly in Ruby: delete all files and # directories older than 120 minutes under /some/path, but not /some/path # itself. Gitlab::Popen.popen(%W(find /some/path -not -path /some/path -mmin +120 -delete)) ``` 這種編碼風格可能阻止了 CVE-2013-4490. ## Always use the configurable Git binary path for Git commands[](#always-use-the-configurable-git-binary-path-for-git-commands "Permalink") ``` # Wrong system(*%W(git branch -d -- #{branch_name})) # Correct system(*%W(#{Gitlab.config.git.bin_path} branch -d -- #{branch_name})) ``` ## Bypass the shell by splitting commands into separate tokens[](#bypass-the-shell-by-splitting-commands-into-separate-tokens "Permalink") 當我們將 shell 命令作為單個字符串傳遞給 Ruby 時,Ruby 將讓`/bin/sh`評估整個字符串. 本質上,我們要求外殼程序評估單行腳本. 這會造成外殼注入攻擊的風險. 最好自己將 shell 命令拆分為令牌. 有時,我們使用外殼程序的腳本功能來更改工作目錄或設置環境變量. 所有這些都可以直接從 Ruby 安全地實現 ``` # Wrong system "cd /home/git/gitlab && bundle exec rake db:#{something} RAILS_ENV=production" # Correct system({'RAILS_ENV' => 'production'}, *%W(bundle exec rake db:#{something}), chdir: '/home/git/gitlab') # Wrong system "touch #{myfile}" # Better system "touch", myfile # Best (do not run a shell command at all) FileUtils.touch myfile ``` 這種編碼風格可能阻止了 CVE-2013-4546. ## Separate options from arguments with –[](#separate-options-from-arguments-with--- "Permalink") 使用`--`使系統命令的參數解析器可以清楚了解選項和參數之間的區別. 許多但并非所有 Unix 命令都支持此功能. 要了解什么`--`不,請考慮以下問題. ``` # Example $ echo hello > -l $ cat -l cat: illegal option -- l usage: cat [-benstuv] [file ...] ``` 在上面的示例中, `cat`的參數解析器假定`-l`是一個選項. 在上面的例子中的解決方案是明確告訴`cat`那`-l`實在是一個論點,不是一種選擇. 許多 Unix 命令行工具都遵循用`--`分隔選項和參數的約定. ``` # Example (continued) $ cat -- -l hello ``` 在 GitLab 代碼庫中,我們*總是*通過對支持它的命令使用`--`來避免選項/參數的歧義. ``` # Wrong system(*%W(#{Gitlab.config.git.bin_path} branch -d #{branch_name})) # Correct system(*%W(#{Gitlab.config.git.bin_path} branch -d -- #{branch_name})) ``` 這種編碼風格可能阻止了 CVE-2013-4582. ## Do not use the backticks[](#do-not-use-the-backticks "Permalink") 用反引號捕獲 shell 命令的輸出很不錯,但是您不得不將命令作為一個字符串傳遞給 shell. 上面我們解釋了這是不安全的. 在主要的 GitLab 代碼庫中,解決方案是改用`Gitlab::Popen.popen` . ``` # Wrong logs = `cd #{repo_dir} && #{Gitlab.config.git.bin_path} log` # Correct logs, exit_status = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} log), repo_dir) # Wrong user = `whoami` # Correct user, exit_status = Gitlab::Popen.popen(%W(whoami)) ``` 在其他存儲庫(如 GitLab Shell)中,您也可以使用`IO.popen` . ``` # Safe IO.popen example logs = IO.popen(%W(#{Gitlab.config.git.bin_path} log), chdir: repo_dir) { |p| p.read } ``` 請注意,與`Gitlab::Popen.popen`不同, `IO.popen`不會捕獲標準錯誤. ## Avoid user input at the start of path strings[](#avoid-user-input-at-the-start-of-path-strings "Permalink") 可以使用各種在 Ruby 中打開和讀取文件的方法來讀取進程的標準輸出而不是文件. 以下兩個命令大致相同: ``` `touch /tmp/pawned-by-backticks` File.read('|touch /tmp/pawned-by-file-read') ``` 關鍵是打開一個以" `|` "開頭的"文件" `|` . 受影響的方法包括 Kernel#open,File :: read,File :: open,IO :: open 和 IO :: read. 您可以通過確保攻擊者無法控制要打開的文件名字符串的開頭來防止"打開"和"讀取"這種行為. 例如,下面的內容足以防止意外地使用`|`啟動 shell 命令`|` : ``` # we assume repo_path is not controlled by the attacker (user) path = File.join(repo_path, user_input) # path cannot start with '|' now. File.read(path) ``` 如果必須使用用戶輸入的相對路徑,請在路徑前添加`./` . 前綴用戶提供的路徑還提供了針對以`-`開頭的路徑的額外保護(請參閱上面有關使用`--`的討論). ## Guard against path traversal[](#guard-against-path-traversal "Permalink") 路徑遍歷是一種安全措施,程序(GitLab)試圖限制用戶對磁盤上某個目錄的訪問,但用戶設法利用`../`路徑符號來打開該目錄之外的文件. ``` # Suppose the user gave us a path and they are trying to trick us user_input = '../other-repo.git/other-file' # We look up the repo path somewhere repo_path = 'repositories/user-repo.git' # The intention of the code below is to open a file under repo_path, but # because the user used '..' they can 'break out' into # 'repositories/other-repo.git' full_path = File.join(repo_path, user_input) File.open(full_path) do # Oops! ``` 防止這種情況發生的好方法是根據 Ruby 的`File.absolute_path`將完整路徑與其"絕對路徑"進行`File.absolute_path` . ``` full_path = File.join(repo_path, user_input) if full_path != File.absolute_path(full_path) raise "Invalid path: #{full_path.inspect}" end File.open(full_path) do # Etc. ``` 這樣的檢查可以避免 CVE-2013-4583. ## Properly anchor regular expressions to the start and end of strings[](#properly-anchor-regular-expressions-to-the-start-and-end-of-strings "Permalink") 當使用正則表達式來驗證作為參數傳遞給 shell 命令的用戶輸入時,請確保使用`\A`和`\z`定位符來指定字符串的開頭和結尾,而不是`^`和`$` ,或者不要使用定位符所有. 如果您不這樣做,攻擊者可能會使用它來執行具有潛在有害影響的命令. 例如,當如下所示驗證項目的`import_url`時,用戶可以誘使 GitLab 從本地文件系統上的 Git 存儲`import_url` . ``` validates :import_url, format: { with: URI.regexp(%w(ssh git http https)) } # URI.regexp(%w(ssh git http https)) roughly evaluates to /(ssh|git|http|https):(something_that_looks_like_a_url)/ ``` 假設用戶提交以下內容作為其導入 URL: ``` file://git:/tmp/lol ``` 由于使用的正則表達式中沒有錨,因此值中的`git:/tmp/lol`將匹配,并且驗證將通過. 導入時,GitLab 將執行以下命令,將`import_url`作為參數傳遞: ``` git clone file://git:/tmp/lol ``` Git 只會忽略`git:`部分,將路徑解釋為`file:///tmp/lol` ,然后將存儲庫導入到新項目中. 此操作可能使攻擊者可以訪問系統中的任何存儲庫(無論是否私有).
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看