Skip to content

Commit

Permalink
[JEP-237] Disable usage stats in fips mode (jenkinsci#8483)
Browse files Browse the repository at this point in the history
* [JEP-237] disable UsageStats in FIPS mode

UsageStatistics is so close to being FIPS-140 compliant but fails at the
last hurdle.

We can not encrypt with RSA but we can perform key wrap.  The output does
separate the key and data, by creating a new Key for encrypting the data
and that key is encrypted with RSA.  If only the RSA cipher was created with
Cipher.WRAP_MODE (or Cipher.UNWRAP_MODE) instead of CIPHER.ENCRYPT_MODE (or
CIPHER.DECRYPT_MODE) we would be fine, alas it is not and changing this
would mean a change on the backend and to be able to continue to support
both whilst older versions are in the wild.

The goal of JEP-237 is not to fix all non compliant issues, so here we
just ensure that in FIPS mode the usage statistics are disabled.

Updates the UI in the global config page to adapt to usagestats being fully disabled by system property or partially disabled by the FIPS property

Co-authored-by: Daniel Beck <[email protected]>
  • Loading branch information
jtnord and daniel-beck authored Oct 5, 2023
1 parent 81af975 commit c4d6fa2
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 20 deletions.
13 changes: 10 additions & 3 deletions core/src/main/java/hudson/model/UsageStatistics.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import jenkins.model.Jenkins;
import jenkins.security.FIPS140;
import jenkins.util.SystemProperties;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;
Expand Down Expand Up @@ -102,8 +103,10 @@ public UsageStatistics(String keyImage) {
* Returns true if it's time for us to check for new version.
*/
public boolean isDue() {
// user opted out. no data collection.
if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED) return false;
// user opted out (explicitly or FIPS is requested). no data collection
if (!Jenkins.get().isUsageStatisticsCollected() || DISABLED || FIPS140.useCompliantAlgorithms()) {
return false;
}

long now = System.currentTimeMillis();
if (now - lastAttempt > DAY) {
Expand Down Expand Up @@ -212,7 +215,11 @@ public Permission getRequiredGlobalConfigPagePermission() {
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
try {
// for backward compatibility reasons, this configuration is stored in Jenkins
Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") ? null : true);
if (DISABLED) {
Jenkins.get().setNoUsageStatistics(Boolean.TRUE);
} else {
Jenkins.get().setNoUsageStatistics(json.has("usageStatisticsCollected") ? null : Boolean.TRUE);
}
return true;
} catch (IOException e) {
throw new FormException(e, "usageStatisticsCollected");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package hudson.model.UsageStatistics

import hudson.model.UsageStatistics
import jenkins.security.FIPS140
import hudson.Functions

def f=namespace(lib.FormTagLib)

f.section(title: _("Usage Statistics")) {
f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb"))
if (UsageStatistics.DISABLED) {
span(class: "jenkins-not-applicable") {
raw(_("disabledBySystemProperty"))
}
} else if (FIPS140.useCompliantAlgorithms()) {
f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurbFIPS"))
} else {
f.optionalBlock(field: "usageStatisticsCollected", checked: app.usageStatisticsCollected, title: _("statsBlurb"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@

statsBlurb=\
Help make Jenkins better by sending anonymous usage statistics and crash reports to the Jenkins project
statsBlurbFIPS=\
Help make Jenkins better by sending telemetry to the Jenkins project
disabledBySystemProperty=\
The option to send anonymous usage statistics, crash reports and telemetry to the Jenkins project is disabled by a <a href="https://www.jenkins.io/doc/book/managing/system-properties/#hudson-model-usagestatistics-disabled">System Property</a>.

Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,35 @@
When enabled, Jenkins periodically sends information to the Jenkins project.
The Jenkins project uses this information to set development priorities.
</div>
<h1>General usage statistics</h1>
<div>
<p>Jenkins reports the following general usage statistics:</p>
<ul>
<li>Your Jenkins version</li>
<li>For your controller and each agent, the OS type and number of executors</li>
<li>Installed plugins and their versions</li>
<li>Number of items (like jobs) of each item type</li>
</ul>
<p>
This <b>does not</b> report any personally identifiable information. The only information reported by Jenkins is information inherently revealed by the HTTP protocol, such as the IP address.

These usage statistics are aggregated, updated monthly, and published to <a href="https://stats.jenkins.io">stats.jenkins.io</a>
</p>
</div>
<j:invokeStatic className="jenkins.security.FIPS140" method="useCompliantAlgorithms" var="fips"/>
<j:if test="${!fips}">
<h1>General usage statistics</h1>
<div>
<p>Jenkins reports the following general usage statistics:</p>
<ul>
<li>Your Jenkins version</li>
<li>For your controller and each agent, the OS type and number of executors</li>
<li>Installed plugins and their versions</li>
<li>Number of items (like jobs) of each item type</li>
</ul>
<p>
This <b>does not</b> report any personally identifiable information.
The only information reported by Jenkins is information inherently revealed by the HTTP protocol, such as the IP address.
These usage statistics are aggregated, updated monthly, and published to <a href="https://stats.jenkins.io">stats.jenkins.io</a>
</p>
</div>
</j:if>
<h1>Telemetry collection</h1>
<div>
<p>
In addition to the general usage statistics listed above, the Jenkins project collects telemetry data from specific trials to inform future development.
<j:choose>
<j:when test="${fips}">
The Jenkins project collects telemetry data from specific trials to inform future development.
</j:when>
<j:otherwise>
In addition to the general usage statistics listed above, the Jenkins project collects telemetry data from specific trials to inform future development.
</j:otherwise>
</j:choose>
Each trial has a specific purpose and a defined end date, after which collection stops, independent of the installed versions of Jenkins or plugins.
Once a trial is complete, the trial results may be aggregated and shared with the developer community.
</p>
Expand Down

0 comments on commit c4d6fa2

Please sign in to comment.