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

[JENKINS-75370] Deprecate hudson.util.Scrambler #10377

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

daniel-beck
Copy link
Member

@daniel-beck daniel-beck commented Mar 5, 2025

See JENKINS-75370.

Scrambler does not really have a good reason to exist: To encode/decode Base64, use java.util.Base64 directly. To protect secrets, use Secret.

Removal of backward compatibility can easily be removed from this PR if a more focused PR is desired, as it's just Base64 decode. I just thought it was time and used the opportunity: 2011 and 2009 have been a while ago.

Testing done

None so far, waiting for autotests.

Proposed changelog entries

  • Remove support for loading user data from before Jenkins 1.283.
  • Remove support for loading proxy configuration from before Jenkins 1.415.
  • Developer: Deprecate hudson.util.Scrambler. Use java.util.Base64 instead.

Proposed changelog category

/label developer removed rfe

Proposed upgrade guidelines

N/A

Submitter checklist

  • The Jira issue, if it exists, is well-described.
  • The changelog entries and upgrade guidelines are appropriate for the audience affected by the change (users or developers, depending on the change) and are in the imperative mood (see examples). Fill in the Proposed upgrade guidelines section only if there are breaking changes or changes that may require extra steps from users during upgrade.
  • There is automated testing or an explanation as to why this change has no tests.
  • New public classes, fields, and methods are annotated with @Restricted or have @since TODO Javadocs, as appropriate.
  • New deprecations are annotated with @Deprecated(since = "TODO") or @Deprecated(forRemoval = true, since = "TODO"), if applicable.
  • New or substantially changed JavaScript is not defined inline and does not call eval to ease future introduction of Content Security Policy (CSP) directives (see documentation).
  • For dependency updates, there are links to external changelogs and, if possible, full differentials.
  • For new APIs and extension points, there is a link to at least one consumer.

Desired reviewers

@mention

Before the changes are marked as ready-for-merge:

Maintainer checklist

  • There are at least two (2) approvals for the pull request and no outstanding requests for change.
  • Conversations in the pull request are over, or it is explicit that a reviewer is not blocking the change.
  • Changelog entries in the pull request title and/or Proposed changelog entries are accurate, human-readable, and in the imperative mood.
  • Proper changelog labels are set so that the changelog can be generated automatically.
  • If the change needs additional upgrade steps from users, the upgrade-guide-needed label is set and there is a Proposed upgrade guidelines section in the pull request title (see example).
  • If it would make sense to backport the change to LTS, a Jira issue must exist, be a Bug or Improvement, and be labeled as lts-candidate to be considered (see query).

Copy link

I wasn't able to add the following labels: developer removed rfe

Check that the label exists and is spelt right then try again.

@StefanSpieker StefanSpieker added rfe For changelog: Minor enhancement. use `major-rfe` for changes to be highlighted developer Changes which impact plugin developers removed This PR removes a feature or a public API labels Mar 6, 2025
Copy link

I wasn't able to add the following labels: developer removed rfe

Check that the label exists and is spelt right then try again.

@daniel-beck daniel-beck marked this pull request as ready for review March 10, 2025 14:08
Copy link

I wasn't able to add the following labels: developer removed rfe

Check that the label exists and is spelt right then try again.

3 similar comments
Copy link

I wasn't able to add the following labels: developer removed rfe

Check that the label exists and is spelt right then try again.

Copy link

I wasn't able to add the following labels: developer removed rfe

Check that the label exists and is spelt right then try again.

Copy link

I wasn't able to add the following labels: developer removed rfe

Check that the label exists and is spelt right then try again.

Copy link
Contributor

@MarkEWaite MarkEWaite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Includes a question about a change of behavior when the authorization header contains invalid base64 data

@@ -127,7 +127,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
// authenticate the user
String username = null;
String password = null;
String uidpassword = Scrambler.descramble(authorization.substring(6));
String uidpassword = new String(Base64.getDecoder().decode(authorization.substring(6).getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it will change behavior in the case where the authorization.substring(6) is not a valid base64 encoded string. The previous Scrambler.descramble() call returns an empty string while the Base64.getDecoder() throws an illegal argument exception.

I experimented with this from the Jenkins script console with the following working code:

import java.util.Base64;
import hudson.util.Scrambler;
import java.nio.charset.StandardCharsets;

def password = 'Not a very good password';
def authorization = 'Basic:' + Scrambler.scramble(password);
println(authorization.substring(6));
println('Scrambled decodes to "' + Scrambler.descramble(authorization.substring(6)) + '"');
println('Base64 decodes to "' + new String(Base64.getDecoder().decode(authorization.substring(6).getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8) + '"');

That reports output:

Tm90IGEgdmVyeSBnb29kIHBhc3N3b3Jk
Scrambled decodes to "Not a very good password"
Base64 decodes to "Not a very good password"

The Jenkins script console with the following intentionally broken code shows the behavioral difference:

import java.util.Base64;
import hudson.util.Scrambler;
import java.nio.charset.StandardCharsets;

def password = 'Not a very good password';
def authorization = 'Basic:X' + Scrambler.scramble(password);
println(authorization.substring(6));
println('Scrambled decodes to "' + Scrambler.descramble(authorization.substring(6)) + '"');
println('Base64 decodes to "' + new String(Base64.getDecoder().decode(authorization.substring(6).getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8) + '"');

That results in the following output:

XTm90IGEgdmVyeSBnb29kIHBhc3N3b3Jk
Scrambled decodes to ""
java.lang.IllegalArgumentException: Last unit does not have enough valid bits
	at java.base/java.util.Base64$Decoder.decode0(Unknown Source)
	at java.base/java.util.Base64$Decoder.decode(Unknown Source)

Is that change of behavior OK?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
developer Changes which impact plugin developers removed This PR removes a feature or a public API rfe For changelog: Minor enhancement. use `major-rfe` for changes to be highlighted
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants