Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust credentials masking tests for base64 masking improvement #296

Merged
merged 4 commits into from
Sep 18, 2023

Conversation

MarkEWaite
Copy link
Contributor

@MarkEWaite MarkEWaite commented Sep 16, 2023

Adjust credentials masking tests for base64 masking improvement

Credentials masking now includes masking of base64 credentials. The tests were using a very short user name, "bot". The base64 encoding of that short user name matches with other log content and causes the tests to fail.

Use a longer user name and a longer password in the test so that spurious matches are much less likely.

Testing done

Confirmed the test fails when I run without b36d0a7

mvn clean -Dtest=MavenSettingsConfigTest verify

Confirmed that tests pass when I include b36d0a7

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

The existing plugins that depend on the config file provider plugin
have a wide range of Jenkins minimum versions.  As far as I can tell,
increasing the Jenkins minimum required version from 2.361.4 to 2.387.3
will not create a problem for most users of the plugin.

Users that are running recent versions of the plugin are already using
Jenkins 2.387.3 or newer.

Users that are running much older versions are not upgrading the plugin
version so won't be affected by an increase of minimum Jenkins version
because they probably won't install the new plugin release.

https://stats.jenkins.io/pluginversions/config-file-provider.html shows

* 34% of all installations of the config file provider plugin are already
  running Jenkins 2.387.3 or newer.  Those users will be able to upgade
  to the version that requires Jenkins 2.387.3 without changing their
  Jenkins core version

* 94% of the 11900 installations of the most recent release (953.xxx)
  are already running Jenkins 2.387.3 or newer.

* 93% of the 11700 installations of the next most recent release (952.xxx)
  are already running Jenkins 2.387.3 or newer.

Plugins that depend on the config file provider plugin include:

* Artifactory - requires 2.235.5 or newer, no additional problems when
  requiring 2.387.3 or newer

* Ivy - requires 2.361.4 or newer, with open security vulnerability and
  up for adoption

* JClouds - requires 2.332.1 or newer, no additional problems when
  requiring 2.387.3 or newer

* Managed Scripts - requires 2.319.3 or newer, no additional problems when
  requiring 2.387.3 or newer

* NodeJS - already requires 2.387.3 or newer

* OpenStack Cloud 0 requires 2.289.1 or newer, no additional problems when
  requiring 2.387.3 or newer

* Pipeline Dependency Walker - requires 1.642.4 or newer, no additional problems when
  requiring 2.387.3 or newer

* Pipeline Maven Integration - requires 2.361.4 or newer

* Pipeline NPM Integration - already requires 2.387.3 or newer

* Pipeline: Multibranch with defaults - requires Jenkin 2.130 or newer, no additional problems when
  requiring 2.387.3 or newer
@MarkEWaite MarkEWaite changed the title Show base64 masking failure Show base64 masking test failure Sep 16, 2023
@jglick
Copy link
Member

jglick commented Sep 18, 2023

Sorry, accidentally clicked Re-run! FTR https://github.com/jenkinsci/config-file-provider-plugin/pull/296/checks?check_run_id=16858023665

java.io.IOException: Illegal base64 character 0x2a
	at java.base/java.util.Base64$DecInputStream.read(Base64.java:1160)
	at java.base/java.io.DataInputStream.read(DataInputStream.java:151)
	at java.base/java.io.DataInputStream.readFully(DataInputStream.java:201)
	at hudson.util.IOUtils.skip(IOUtils.java:90)
	at hudson.console.ConsoleNote.skip(ConsoleNote.java:311)
	at hudson.console.PlainTextConsoleOutputStream.eol(PlainTextConsoleOutputStream.java:67)
	at hudson.console.LineTransformationOutputStream.eol(LineTransformationOutputStream.java:61)
	at hudson.console.LineTransformationOutputStream.write(LineTransformationOutputStream.java:57)
	at hudson.console.LineTransformationOutputStream.write(LineTransformationOutputStream.java:75)
	at org.apache.commons.io.output.ProxyOutputStream.write(ProxyOutputStream.java:92)
	at org.kohsuke.stapler.framework.io.LargeText.writeLogTo(LargeText.java:233)
	at hudson.console.AnnotatedLargeText.writeLogTo(AnnotatedLargeText.java:164)
	at org.jvnet.hudson.test.JenkinsRule.getLog(JenkinsRule.java:1536)
	at org.jvnet.hudson.test.JenkinsRule.assertLogNotContains(JenkinsRule.java:1525)
	at org.jenkinsci.plugins.configfiles.maven.MavenSettingsConfigTest.freestyleWithCredentials(MavenSettingsConfigTest.java:157)

Regardless of whether the regression is caused by jenkinsci/credentials-binding-plugin#269, I think the error is also fixed by jenkinsci/jenkins#8378.

@MarkEWaite
Copy link
Contributor Author

Regardless of whether the regression is caused by jenkinsci/credentials-binding-plugin#269, I think the error is also fixed by jenkinsci/jenkins#8378.

That explains why the failure is not visible in the weekly release line and is only visible in the LTS release line. Thanks very much for pointing to that change. I've confirmed that this pull request passes when built with:

mvn -Djenkins.version=2.420 -Dtest=MavenSettingsConfigTest verify

It fails when built with:

mvn -Djenkins.version=2.419 -Dtest=MavenSettingsConfigTest verify

Jenkins 2.420 is the first weekly release that includes the fix in jenkinsci/jenkins#8378.

I think that the next baseline Jenkins version for the config-file-provider plugin should be 2.387.3 so that it does not use too new a version. If the next baseline Jenkins version for the config-file-provider plugin is anything less than Jenkins 2.420, then I think we will want some change to the config-file-provider tests so that they pass on the LTS baselines. That change could be as simple as "skip the test if the Jenkins version is too old", but I think that we need the tests to pass.

Does that make sense to you @jglick or is there a better way to handle the failing config-file-provider tests when they run with the current credentials binding plugin in an older Jenkins release?

@jglick
Copy link
Member

jglick commented Sep 18, 2023

jenkinsci/jenkins#8378 merely prevents a corrupted console note from breaking log streaming. Why the note became corrupted to begin with is another question; it sounds like jenkinsci/credentials-binding-plugin#269 introduced a genuine regression to production code, by accidentally masking some snippet of serialized ConsoleNote that was unrelated to any secrets in scope. Perhaps the secret was very short and its Base64 form happens to appear in other unrelated contexts by coincidence, in which case there should be some minimum length requirement perhaps. Someone will need to debug the test to see exactly what is getting masked and why.

@Kevin-CB
Copy link

Kevin-CB commented Sep 18, 2023

accidentally masking some snippet of serialized ConsoleNote that was unrelated to any secrets in scope. Perhaps the secret was very short and its Base64 form happens to appear in other unrelated contexts by coincidence

That's exactly it! In this test, one of the secrets is bot, which in one of its base64 forms without padding is b3.
As a result, it gets masked in the console output, leading to corrupted base64:

Building remotely on �[8mha:////4DoiLVFH0[...]SjKDWzX****RdlLBUSYG[...]eFxQAAAA==�[0mslave0 in workspace 

@Kevin-CB
Copy link

Does that make sense to you @jglick or is there a better way to handle the failing config-file-provider tests when they run with the current credentials binding plugin in an older Jenkins release?

Using a longer secret for bot should fix this issue; something like bot123 works fine for me.

The base64 credential masking was detecting the "bot" user name earlier
in the log and replacing it.  A longer user name that is not a substring
of other text in the log file prevents that.

Also extends the bot password text to a longer string to match the longer
user name string.
@MarkEWaite
Copy link
Contributor Author

I've modified the tests as suggested by @Kevin-CB and confirmed that it now passes with Jenkins 2.419. Changes are in b36d0a7

@MarkEWaite MarkEWaite changed the title Show base64 masking test failure Adjust credentials masking tests for base64 masking improvement Sep 18, 2023
@MarkEWaite
Copy link
Contributor Author

Does that make sense to you @jglick or is there a better way to handle the failing config-file-provider tests when they run with the current credentials binding plugin in an older Jenkins release?

Using a longer secret for bot should fix this issue; something like bot123 works fine for me.

@Kevin-CB do you also want to consider the addition of a minimum length criteria to the base64 masking in the credentials binding plugin? I think that the suggestion from @jglick may help avoid user complaints when they use a very short user name or a very short password.

@MarkEWaite MarkEWaite marked this pull request as ready for review September 18, 2023 13:04
@MarkEWaite MarkEWaite requested a review from a team as a code owner September 18, 2023 13:04
@MarkEWaite
Copy link
Contributor Author

MarkEWaite commented Sep 18, 2023

@alecharp if you'd be willing to label this as developer, review it, and if approved, merge it, that will allow me to remove the plugin bill of materials workaround that I inserted in:

You're welcome to squash merge this change (once it has been reviewed and approved) so that the git history remains tidy.

@alecharp
Copy link
Member

Looks simple enough. Thank you @MarkEWaite.

@alecharp alecharp added this pull request to the merge queue Sep 18, 2023
Merged via the queue into jenkinsci:master with commit cff671a Sep 18, 2023
14 checks passed
MarkEWaite added a commit to jenkinsci/bom that referenced this pull request Sep 18, 2023
)"

The config-file-provider plugin 959.vcff671a_4518b_ release resolves
the test failure on LTS lines.

jenkinsci/config-file-provider-plugin#296 is
the pull request to config-file-provider that resolved the issue.

https://github.com/jenkinsci/config-file-provider-plugin/releases/tag/959.vcff671a_4518b_
is the changelog for the config-file-provider release.

This reverts commit c111cf5.
github-actions bot pushed a commit to jenkinsci/bom that referenced this pull request Sep 18, 2023
…4d2 to 959.vcff671a_4518b_ in /bom-weekly (#2517)

* Bump org.jenkins-ci.plugins:config-file-provider in /bom-weekly

Bumps [org.jenkins-ci.plugins:config-file-provider](https://github.com/jenkinsci/config-file-provider-plugin) from 953.v0432a_802e4d2 to 959.vcff671a_4518b_.
- [Release notes](https://github.com/jenkinsci/config-file-provider-plugin/releases)
- [Commits](https://github.com/jenkinsci/config-file-provider-plugin/commits)

---
updated-dependencies:
- dependency-name: org.jenkins-ci.plugins:config-file-provider
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Revert "Pin previous credentials-binding release for LTS profiles (#2514)"

The config-file-provider plugin 959.vcff671a_4518b_ release resolves
the test failure on LTS lines.

jenkinsci/config-file-provider-plugin#296 is
the pull request to config-file-provider that resolved the issue.

https://github.com/jenkinsci/config-file-provider-plugin/releases/tag/959.vcff671a_4518b_
is the changelog for the config-file-provider release.

This reverts commit c111cf5.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mark Waite <mark.earl.waite@gmail.com>
@jglick
Copy link
Member

jglick commented Sep 18, 2023

do you also want to consider the addition of a minimum length criteria to the base64 masking

This might be prudent, though you also have to ask why you are trying to mask such short secrets to begin with—clearly they would not be secure. For usernames, we guide users to disable username masking for newly created credentials, but continue to mask older credentials unless and until the user ops out.

The particular issue could I think also be addressed by disabling the Base64 masker on lines containing the magic header sequence for ConsoleNote, since we would never expect a user secret to occur (much less in Base64-encoded form) in a line that contains a note. That would prevent notes from becoming corrupted. You could still have spurious masking of short sequences in other parts of the log which would be annoying; of course this could also occur with the literal pattern factory, if you just happened to have a “password” like 123 that winds up occurring in all sorts of unrelated places.

@MarkEWaite MarkEWaite deleted the show-base64-masking-failure branch September 18, 2023 15:02
@Kevin-CB
Copy link

I'm tracking this issue under JENKINS-72035.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants