ansible.windows icon indicating copy to clipboard operation
ansible.windows copied to clipboard

win_powershell - add secure parameters

Open jborean93 opened this issue 2 months ago • 4 comments

SUMMARY

Added parameters_secure_string to the win_powershell module that allows users to provide a SecureString or PSCredential object that is set with no_log.

ISSUE TYPE
  • Feature Pull Request
COMPONENT NAME

win_powershell

jborean93 avatar Apr 10 '24 00:04 jborean93

Docs Build 📝

Thank you for contribution!✨

The docsite for this PR is available for download as an artifact from this run: https://github.com/ansible-collections/ansible.windows/actions/runs/8623862635

You can compare to the docs for the main branch here: https://ansible-collections.github.io/ansible.windows/branch/main

File changes:

  • M collections/ansible/windows/win_powershell_module.html
Click to see the diff comparison.

NOTE: only file modifications are shown here. New and deleted files are excluded. See the file list and check the published docs to see those files.

diff --git a/home/runner/work/ansible.windows/ansible.windows/docsbuild/base/collections/ansible/windows/win_powershell_module.html b/home/runner/work/ansible.windows/ansible.windows/docsbuild/head/collections/ansible/windows/win_powershell_module.html
index 37ec3b0..fb71235 100644
--- a/home/runner/work/ansible.windows/ansible.windows/docsbuild/base/collections/ansible/windows/win_powershell_module.html
+++ b/home/runner/work/ansible.windows/ansible.windows/docsbuild/head/collections/ansible/windows/win_powershell_module.html
@@ -237,13 +237,54 @@ To check whether it is installed, run <code class="code docutils literal notrans
 </div></td>
 </tr>
 <tr class="row-odd"><td><div class="ansible-option-cell">
+<div class="ansibleOptionAnchor" id="parameter-parameters_secure_string"></div><p class="ansible-option-title" id="ansible-collections-ansible-windows-win-powershell-module-parameter-parameters-secure-string"><strong>parameters_secure_string</strong></p>
+<a class="ansibleOptionLink" href="#parameter-parameters_secure_string" title="Permalink to this option"></a><p class="ansible-option-type-line"><span class="ansible-option-type">list</span> / <span class="ansible-option-elements">elements=dictionary</span></p>
+</div></td>
+<td><div class="ansible-option-cell"><p>Parameters to pass into the script as a SecureString or PSCredential.</p>
+<p>Each sensitive value will be marked with <code class="docutils literal notranslate"><span class="pre">no_log</span></code> to ensure they are not exposed in any logs.</p>
+<p>The <em>value</em> suboption can be used to create a SecureString value while <em>username</em> and <em>password</em> can be used to create a PSCredential value.</p>
+</div></td>
+</tr>
+<tr class="row-even"><td><div class="ansible-option-indent"></div><div class="ansible-option-cell">
+<div class="ansibleOptionAnchor" id="parameter-parameters_secure_string/name"></div><p class="ansible-option-title" id="ansible-collections-ansible-windows-win-powershell-module-parameter-parameters-secure-string-name"><strong>name</strong></p>
+<a class="ansibleOptionLink" href="#parameter-parameters_secure_string/name" title="Permalink to this option"></a><p class="ansible-option-type-line"><span class="ansible-option-type">string</span> / <span class="ansible-option-required">required</span></p>
+</div></td>
+<td><div class="ansible-option-indent-desc"></div><div class="ansible-option-cell"><p>The name of the parameter to pass this value to.</p>
+</div></td>
+</tr>
+<tr class="row-odd"><td><div class="ansible-option-indent"></div><div class="ansible-option-cell">
+<div class="ansibleOptionAnchor" id="parameter-parameters_secure_string/password"></div><p class="ansible-option-title" id="ansible-collections-ansible-windows-win-powershell-module-parameter-parameters-secure-string-password"><strong>password</strong></p>
+<a class="ansibleOptionLink" href="#parameter-parameters_secure_string/password" title="Permalink to this option"></a><p class="ansible-option-type-line"><span class="ansible-option-type">string</span></p>
+</div></td>
+<td><div class="ansible-option-indent-desc"></div><div class="ansible-option-cell"><p>The <code class="docutils literal notranslate"><span class="pre">Password</span></code> for the PSCredential value.</p>
+<p>This is mutually exclusive with <em>value</em> and must be set when <em>username</em> is provided.</p>
+</div></td>
+</tr>
+<tr class="row-even"><td><div class="ansible-option-indent"></div><div class="ansible-option-cell">
+<div class="ansibleOptionAnchor" id="parameter-parameters_secure_string/username"></div><p class="ansible-option-title" id="ansible-collections-ansible-windows-win-powershell-module-parameter-parameters-secure-string-username"><strong>username</strong></p>
+<a class="ansibleOptionLink" href="#parameter-parameters_secure_string/username" title="Permalink to this option"></a><p class="ansible-option-type-line"><span class="ansible-option-type">string</span></p>
+</div></td>
+<td><div class="ansible-option-indent-desc"></div><div class="ansible-option-cell"><p>The <code class="docutils literal notranslate"><span class="pre">UserName</span></code> for the PSCredential value.</p>
+<p>This is mutually exclusive with <em>value</em>.</p>
+<p>This value is <strong>NOT</strong> added to the <code class="docutils literal notranslate"><span class="pre">no_log</span></code> list.</p>
+</div></td>
+</tr>
+<tr class="row-odd"><td><div class="ansible-option-indent"></div><div class="ansible-option-cell">
+<div class="ansibleOptionAnchor" id="parameter-parameters_secure_string/value"></div><p class="ansible-option-title" id="ansible-collections-ansible-windows-win-powershell-module-parameter-parameters-secure-string-value"><strong>value</strong></p>
+<a class="ansibleOptionLink" href="#parameter-parameters_secure_string/value" title="Permalink to this option"></a><p class="ansible-option-type-line"><span class="ansible-option-type">string</span></p>
+</div></td>
+<td><div class="ansible-option-indent-desc"></div><div class="ansible-option-cell"><p>The string to pass as a SecureString of the parameter specified by <em>name</em>.</p>
+<p>This is mutually exclusive with <em>username</em> and <em>password</em>.</p>
+</div></td>
+</tr>
+<tr class="row-even"><td><div class="ansible-option-cell">
 <div class="ansibleOptionAnchor" id="parameter-removes"></div><p class="ansible-option-title" id="ansible-collections-ansible-windows-win-powershell-module-parameter-removes"><strong>removes</strong></p>
 <a class="ansibleOptionLink" href="#parameter-removes" title="Permalink to this option"></a><p class="ansible-option-type-line"><span class="ansible-option-type">string</span></p>
 </div></td>
 <td><div class="ansible-option-cell"><p>A path or path filter pattern; when the referenced path <strong>does not</strong> exist on the target host, the task will be skipped.</p>
 </div></td>
 </tr>
-<tr class="row-even"><td><div class="ansible-option-cell">
+<tr class="row-odd"><td><div class="ansible-option-cell">
 <div class="ansibleOptionAnchor" id="parameter-script"></div><p class="ansible-option-title" id="ansible-collections-ansible-windows-win-powershell-module-parameter-script"><strong>script</strong></p>
 <a class="ansibleOptionLink" href="#parameter-script" title="Permalink to this option"></a><p class="ansible-option-type-line"><span class="ansible-option-type">string</span> / <span class="ansible-option-required">required</span></p>
 </div></td>
@@ -386,6 +427,37 @@ To check whether it is installed, run <code class="code docutils literal notrans
 <span class="w">      </span><span class="no">Write-Output &quot;Hello World!&quot;</span>
 <span class="w">      </span><span class="no">Write-Verbose &quot;Hello World!&quot;</span>
 <span class="w">      </span><span class="no">Write-Debug &quot;Hello World!&quot;</span>
+
+<span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Set sensitive parameter value as SecureString parameter</span>
+<span class="w">  </span><span class="nt">ansible.windows.win_powershell</span><span class="p">:</span>
+<span class="w">    </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">|</span>
+<span class="w">      </span><span class="no">param(</span>
+<span class="w">          </span><span class="no">[string]$Uri,</span>
+<span class="w">          </span><span class="no">[SecureString]$Token</span>
+<span class="w">      </span><span class="no">)</span>
+
+<span class="w">      </span><span class="no">Invoke-WebRequest -Uri $Uri -Token $Token</span>
+<span class="w">    </span><span class="nt">parameters</span><span class="p">:</span>
+<span class="w">      </span><span class="nt">Uri</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">foo</span>
+<span class="w">    </span><span class="nt">parameters_secure_string</span><span class="p">:</span>
+<span class="w">    </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Token</span>
+<span class="w">      </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="s">&#39;</span><span class="cp">{{</span> <span class="nv">sensitive_value</span> <span class="cp">}}</span><span class="s">&#39;</span>
+
+<span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Set credential parameter</span>
+<span class="w">  </span><span class="nt">ansible.windows.win_powershell</span><span class="p">:</span>
+<span class="w">    </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">|</span>
+<span class="w">      </span><span class="no">param(</span>
+<span class="w">          </span><span class="no">[string]$Uri,</span>
+<span class="w">          </span><span class="no">[PSCredential]$Credential</span>
+<span class="w">      </span><span class="no">)</span>
+
+<span class="w">      </span><span class="no">Invoke-WebRequest -Uri $Uri -Credential $Credential</span>
+<span class="w">    </span><span class="nt">parameters</span><span class="p">:</span>
+<span class="w">      </span><span class="nt">Uri</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">foo</span>
+<span class="w">    </span><span class="nt">parameters_secure_string</span><span class="p">:</span>
+<span class="w">    </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Credential</span>
+<span class="w">      </span><span class="nt">username</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">CredUserName</span>
+<span class="w">      </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="s">&#39;</span><span class="cp">{{</span> <span class="nv">sensitive_value</span> <span class="cp">}}</span><span class="s">&#39;</span>
 </pre></div>
 </div>
 </section>

github-actions[bot] avatar Apr 10 '24 00:04 github-actions[bot]

I think I'm starting to get the reason for this, but it does feel kinda brittle at a glance, and since the cleartext still enters the module, I'm wondering if there's a different thing we should be looking at to more securely channel those bits into the module and/or over the wire...

nitzmahone avatar Apr 16 '24 16:04 nitzmahone

Without controller side argspec there isn't much we can do to achieve such a thing and it would also mean we need to implement some crypto mechanism on the Ansible side and the remote to achieve such a thing. The psrp connection plugin can provide a SecureString or PSCredential natively but any other connection plugin cannot which means rolling our own mechanism which means more round trips to negotiate the encryption used and probably sets us up for a CVE if we do it wrong.

The main reason for this PR is it adds the sensitive values to a parameter marked as no_log so users don't need to no_log: True the whole task invocation which makes things harder to debug as everything would be masked at runtime. Currently there is no real way of achieving this and even then things like win_shell/win_command are dangerous because of process auditing could log the sensitive values and with the existing parameters option scriptblock logging/transcription could expose the values if not passed in as a SecureString/PSCredential.

jborean93 avatar Apr 16 '24 18:04 jborean93

This pull request is stale because it has been open for 4 weeks with no activity. Remove stale label or comment or this will be closed in 2 weeks.

github-actions[bot] avatar May 15 '24 00:05 github-actions[bot]