website: Documentation of how provisioners upload files

We recently made a change to how provisioners upload files in order to
address an unintended remote code execution vector when using SSH, which
revealed that we had not previously documented well enough the expected
contract for how provisioners upload files to remote systems, and so some
users were depending on unintended consequences of the the bug now fixed.

We are retaining the fix on security-related grounds, but this is a good
prompt to be clearer in the docs about what exactly Terraform is doing
when asked to upload files over SSH and WinRM, so users can understand
what is supported and write their configurations accordingly.

This also includes an additional section to the v1.1 upgrade guide, since
we apparently neglected to document this intentional breaking change in
the first draft of that page.

Of course, provisioners as a whole remain a last resort, and so we're
documenting this as hopefully a helpful aid to those who have no other
option, and not meaning in any way to recommend their use for any new
use-cases.
This commit is contained in:
Martin Atkins
2022-01-05 12:27:09 -08:00
parent 6ef9cf652e
commit 087c2f06ee
3 changed files with 209 additions and 31 deletions

View File

@@ -23,6 +23,7 @@ small number of users, described in the following sections.
* [Terraform requires macOS 10.13 High Sierra or later](#terraform-requires-macos-1013-high-sierra-or-later)
* [Preparation for removing Azure AD Graph support in the AzureRM Backend](#preparation-for-removing-azure-ad-graph-support-in-the-azurerm-backend)
* [Interpretation of remote file paths in the `remote-exec` and `file` provisioners](#interpretation-of-remote-file-paths-in-the-remote-exec-and-file-provisioners)
* [Changes to `terraform graph`](#changes-to-terraform-graph)
* [Changes to `terraform state mv`](#changes-to-terraform-state-mv)
* [Provider checksum verification in `terraform apply`](#provider-checksum-verification-in-terraform-apply)
@@ -54,6 +55,66 @@ in the near future to prepare for the final removal of Azure AD Graph support
in a later Terraform release. However, no immediate change is required before
upgrading to Terraform v1.1.
## Interpretation of remote file paths in the `remote-exec` and `file` provisioners
When using Terraform's built-in `remote-exec` and `file` provisioners, there
are two situations where Terraform internally uses
[Secure Copy Protocol](https://en.wikipedia.org/wiki/Secure_copy_protocol)
(SCP) to upload files to the remote system at a configuration-specified
location:
* For [the `file` provisioner](/language/resources/provisioners/file),
the primary functionality is to upload a file using SCP, and the
`destination` argument specifies the remote path where the file is to be
written.
* For [the `remote-exec` provisioner](/language/resources/provisioners/remote-exec),
internally the provisioner works by uploading the given scripts to files
on the remote system and then executing them. By default the provisioner
selects a temporary filename automatically, but a module author can
potentially override that location using the `script_path` argument in the
associated [`connection` block](https://www.terraform.io/language/resources/provisioners/connection).
If you are not using either of the specific arguments mentioned above, no
configuration changes will be required to upgrade to Terraform v1.1.
These provisioners both passing the specified remote paths to the `scp` service
program on the remote system. In Terraform v1.0 and earlier, the provisioners
were passing the paths to `scp` in a way that was inadvertently subject to
_shell expansion_. That inadvertently allowed for convenient shorthands
such as `~/example` and `$HOME/example` to write into the target user's
home directory, but also offered an undesirable opportunity for accidental
remote code execution, such as `$(arbitrary-program)`.
In Terraform v1.1 both of the above remote path arguments are passed _verbatim_
to the remote `scp` service, without any prior shell expansion. For that reason,
shell-defined expansion tokens such as `~` and environment variable references
will no longer be evaluated.
By default, the OpenSSH server and the program `scp` together already interpret
relative paths as relative to the target user's home directory, and so
module authors can specify relative paths without any special metacharacters
in order to request uploading into that default location:
```hcl
provisioner "file" {
source = "local.txt"
destination = "remote.txt"
}
```
If you maintain a module that was depending on expansion of `~/`, `$HOME/`,
`${HOME}`/ or similar, remove that prefix so that your module instead specifies
just a relative path.
This is an intentional compatibility regression which we accepted after due
consideration of
[the pragmatic exceptions to our compatibility promises](/language/v1-compatibility-promises#pragmatic-exceptions).
Specifically, this behavior offered an unintended and non-obvious avenue for
arbitrary code execution on the remote system if either of the above arguments
were populated from outside input, and an alternative approach is available
which doesn't have that drawback, and this is therefore justified on security
grounds.
## Changes to `terraform graph`
The `terraform graph` command exists to help with debugging and so it