Environment
- CloudBees CI (CloudBees Core)
- CloudBees CI (CloudBees Core) on modern cloud platforms - Managed Master
- CloudBees CI (CloudBees Core) on modern cloud platforms - Operations Center
- CloudBees CI (CloudBees Core) on traditional platforms - Client Master
- CloudBees CI (CloudBees Core) on traditional platforms - Operations Center
- CloudBees Jenkins Enterprise
- CloudBees Jenkins Enterprise - Managed Master
- CloudBees Jenkins Enterprise - Operations Center
- CloudBees Jenkins Platform - Client Master
- CloudBees Jenkins Platform - Operations Center
- CloudBees Jenkins Distribution
- Jenkins LTS
Issue
How do I enable CSRF protection?
Resolution
GOTO: Jenkins > Manage Jenkins > Configure Global Security
and enable Prevent Cross Site Request Forgery exploits
.
Select Default Crumb Issuer
from Crumb Algorithm
and save to apply changes and enable.
See the CSRF Protection Wiki page for more.
Issue
Do I need a CSRF crumb?
Resolution
If you authenticate your API calls with a username and password, a valid crumb is required. Starting from Jenkins LTS 2.176.2 a valid Web Session for which the crumb was issued is also required unless configured otherwise.
If you authenticate your API calls with a username and a user API token then a crumb is not required from Jenkins 2.96 weekly / 2.107 LTS. For more information please refer to CSRF crumb no longer required when authenticating using API token or JENKINS-22474.
Note that the API Token system was improved in Jenkins LTS 2.138.1
Issue
How do I generate a crumb?
Resolution
Using wget
wget --user=admin --password=admin --auth-no-challenge -q --output-document - 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
The output is the crumb.
Parameters:
--user=<USERNAME>
--password=<PASSWORD_OR_API_TOKEN>
Replace http://localhost:8080
with your Jenkins URL.
Using cURL
curl -u "admin:admin" 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
The output is the crumb.
Parameters:
-u "<USERNAME>:<PASSWORD_OR_API_TOKEN>"
Replace http://localhost:8080
with your Jenkins URL.
Debugging Issues
I’m seeing the following response:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 404 Not Found</title>
</head>
<body><h2>HTTP ERROR 404</h2>
<p>Problem accessing /crumbIssuer/api/xml. Reason:
<pre> Not Found</pre></p><hr /><i><small>Powered by Jetty://</small></i><br/>
...
...
CSRF Protection is not enabled. GOTO: Jenkins > Manage Jenkins > Configure Global Security
and enable Prevent Cross Site Request Forgery exploits
.
Issue
How do I use an issued crumb in an API call.
Resolution
Using wget
The following example retrieves a crumb and uses it to build a job called someJob
.
Before 2.176.2, no session required:
# Replace with your Jenkins URL and admin credentials
SERVER="http://localhost:8080"
CRUMB=$(wget --user=admin --password=admin --auth-no-challenge -q --output-document - "$SERVER"/crumbIssuer/api/xml?xpath=concat\(//crumbRequestField,%22:%22,//crumb\))
wget --user=admin --password=admin --auth-no-challenge --header="$CRUMB" --post-data="" -q "$SERVER"/job/someJob/build
After 2.176.2, session is required:
# Replace with your Jenkins URL and admin credentials
SERVER="http://localhost:8080"
# File where web session cookie is saved
COOKIEJAR="$(mktemp)"
CRUMB="$(wget --user=admin --password=admin --auth-no-challenge --save-cookies "$COOKIEJAR" --keep-session-cookies -q --output-document - "$SERVER/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)")"
wget --user=admin --password=admin --auth-no-challenge --load-cookies "$COOKIEJAR" --header="$CRUMB" --post-data="" -q "$SERVER"/job/someJob/build
Parameters:
--user=<USERNAME>
--password=<PASSWORD_OR_API_TOKEN>
--header="<ISSUED_CRUMB_FOR_USER>"
Using cURL
The following example retrieves a crumb and uses it to build a job called someJob
.
Before 2.176.2, no session required:
# Replace with your Jenkins URL and admin credentials
SERVER="http://localhost:8080"
CRUMB=$(curl -u "admin:admin" "$SERVER"/crumbIssuer/api/xml?xpath=concat\(//crumbRequestField,%22:%22,//crumb\))
curl -X POST -u "admin:admin" -H "$CRUMB" "$SERVER"/job/someJob/build
After 2.176.2, session is required:
# Replace with your Jenkins URL and admin credentials
SERVER="http://localhost:8080"
# File where web session cookie is saved
COOKIEJAR="$(mktemp)"
CRUMB=$(curl -u "admin:admin" --cookie-jar "$COOKIEJAR" "$SERVER/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)")
curl -X POST -u "admin:admin" --cookie "$COOKIEJAR" -H "$CRUMB" "$SERVER"/job/someJob/build
Parameters:
-u "<USERNAME>:<PASSWORD_OR_API_TOKEN>"
-H "<ISSUED_CRUMB_FOR_USER>"
Debugging Issues
I’m seeing the following response:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error 403 No valid crumb was included in the request</title>
</head>
<body><h2>HTTP ERROR 403</h2>
<p>Problem accessing /job/someJob/build. Reason:
<pre> No valid crumb was included in the request</pre></p><hr /><i><small>Powered by Jetty://</small></i><br/>
...
...
This is caused by an invalid crumb being used.
Issue
Does the crumb expire?
Resolution
Once an user has received a crumb, it can be re-used for all subsequent requests as long as this user stays in the same session. At code level, this dependency can be seen here.
Note :
- Session may expire on its own depending on Jenkins settings.
- Session might be aborted due to unexpected reasons, such as Failover of HA in CJP or SSO expiration
- So generally keeping the same crumb is safe for short command sequences, but not for scripts running for several hours
Issue
How is the crumb generated?
Resolution
Using MD5. The crumb is a combination of user authentication (if authentication is applied), originating IP address and the crumb salt.
Issue
Is the crumb salt configurable?
Resolution
Currently no. It is hard-coded.
1 Comments