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

POST API calls '403 No valid crumb was included in the request' #67

Closed
tbouffard opened this issue Oct 7, 2019 · 16 comments · Fixed by #70
Closed

POST API calls '403 No valid crumb was included in the request' #67

tbouffard opened this issue Oct 7, 2019 · 16 comments · Fixed by #70
Assignees
Labels

Comments

@tbouffard
Copy link
Contributor

Expected Behavior

Use the jenkins-rest lib with user/password credentials to perform GET or POST underlying Rest API calls

Current Behavior

All POST requests fail when running Jenkins 2.176.2+/2.186+ with error: HTTP/1.1 403 No valid crumb was included in the request

Context

This issue only occurs when running Jenkins 2.176.2+/2.186+ and seems related to security settings changes: https://jenkins.io/security/advisory/2019-07-17/#SECURITY-626
This link provides workarounds to make the calls work but they

  • require extra Jenkins configuration
  • reduce security protection

The security advisory suggests to now pass the session id retrieved when getting the crumb to all authenticated requests.
I currently don't know this session id is the X-Jenkins-Session header or the JSESSIONID cookie.

Steps to Reproduce (for bugs)

Base commit: master branch b3e01c0 (latest 0.0.19 release is also affected)

  • Start a Jenkins 2.176.2+/2.186+ local instance (I used a Jenkins Docker container)
  • Jenkins configuration: activate the CSRF Protection and use the Default Crumb Issuer (see https://wiki.jenkins.io/display/JENKINS/CSRF+Protection)
  • Run integration tests: ./gradlew clean build integTest
  • All http POST requests to Jenkins API receive a HTTP 403 status response
Debug http traces generated by integration tests

11:02:13.914 [Test worker] DEBUG org.jclouds.rest.internal.InvokeHttpMethod - >> invoking jobs:build
11:02:13.934 [Test worker] DEBUG org.jclouds.rest.internal.InvokeHttpMethod - >> invoking crumb-issuer:crumb
11:02:13.936 [Test worker] DEBUG org.jclouds.http.internal.JavaUrlHttpCommandExecutorService - Sending request 559347004: GET http://127.0.0.1:8080/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29 HTTP/1.1
11:02:13.936 [Test worker] DEBUG jclouds.headers - >> GET http://127.0.0.1:8080/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29 HTTP/1.1
11:02:13.937 [Test worker] DEBUG jclouds.headers - >> Accept: text/plain
11:02:13.937 [Test worker] DEBUG jclouds.headers - >> Authorization: Basic YWRtaW46YWRtaW4=
11:02:14.470 [Test worker] DEBUG org.jclouds.http.internal.JavaUrlHttpCommandExecutorService - Receiving response 559347004: HTTP/1.1 200 OK
11:02:14.471 [Test worker] DEBUG jclouds.headers - << HTTP/1.1 200 OK
11:02:14.471 [Test worker] DEBUG jclouds.headers - << X-Jenkins-Session: 0ae78274
11:02:14.471 [Test worker] DEBUG jclouds.headers - << X-Jenkins: 2.190.1
11:02:14.471 [Test worker] DEBUG jclouds.headers - << Server: Jetty(9.4.z-SNAPSHOT)
11:02:14.471 [Test worker] DEBUG jclouds.headers - << X-Content-Type-Options: nosniff
11:02:14.472 [Test worker] DEBUG jclouds.headers - << Set-Cookie: JSESSIONID.1af1c15a=node01gqw35ypjb5i9gnfzuer6qf60.node0;Path=/;HttpOnly
11:02:14.472 [Test worker] DEBUG jclouds.headers - << Date: Thu, 03 Oct 2019 09:02:14 GMT
11:02:14.472 [Test worker] DEBUG jclouds.headers - << Content-Type: text/plain;charset=utf-8
11:02:14.472 [Test worker] DEBUG jclouds.headers - << Content-Length: 78
11:02:14.475 [Test worker] DEBUG jclouds.headers - << Expires: Thu Jan 01 01:00:00 CET 1970
11:02:14.480 [Test worker] DEBUG jclouds.wire - << "Jenkins-Crumb:57de4a3074e2bee0231bdfab6bd63e33c9200501497fe83b3390c68dfe7edbb5"
11:02:14.484 [Test worker] DEBUG org.jclouds.http.internal.JavaUrlHttpCommandExecutorService - Sending request -134656407: POST http://127.0.0.1:8080/job/a0571fd6b9d8443ba593add116bae8a4/build HTTP/1.1
11:02:14.484 [Test worker] DEBUG jclouds.headers - >> POST http://127.0.0.1:8080/job/a0571fd6b9d8443ba593add116bae8a4/build HTTP/1.1
11:02:14.485 [Test worker] DEBUG jclouds.headers - >> Accept: application/unknown
11:02:14.485 [Test worker] DEBUG jclouds.headers - >> Authorization: Basic YWRtaW46YWRtaW4=
11:02:14.485 [Test worker] DEBUG jclouds.headers - >> Jenkins-Crumb: 57de4a3074e2bee0231bdfab6bd63e33c9200501497fe83b3390c68dfe7edbb5
11:02:14.502 [Test worker] DEBUG org.jclouds.http.internal.JavaUrlHttpCommandExecutorService - Receiving response -134656407: HTTP/1.1 403 No valid crumb was included in the request
11:02:14.502 [Test worker] DEBUG jclouds.headers - << HTTP/1.1 403 No valid crumb was included in the request
11:02:14.502 [Test worker] DEBUG jclouds.headers - << Server: Jetty(9.4.z-SNAPSHOT)
11:02:14.502 [Test worker] DEBUG jclouds.headers - << X-Content-Type-Options: nosniff
11:02:14.502 [Test worker] DEBUG jclouds.headers - << Set-Cookie: JSESSIONID.1af1c15a=node01ilzetxztr6rbbhspkddjs2fw1.node0;Path=/;HttpOnly
11:02:14.502 [Test worker] DEBUG jclouds.headers - << Date: Thu, 03 Oct 2019 09:02:14 GMT

Your Environment

JVM: 1.8.0_212 ( 25.212-b04)
OS: Windows 10 10.0 amd64

@tbouffard
Copy link
Contributor Author

@cdancy If you reproduce the problem and consider this as valid, I can start working on a PR

@choweiyuan
Copy link
Contributor

@tbouffard I faced the same issue, workaround it by using user/apitoken instead. See if that works for you?

@cdancy cdancy self-assigned this Oct 7, 2019
@cdancy cdancy added the question label Oct 7, 2019
@cdancy
Copy link
Owner

cdancy commented Oct 7, 2019

@tbouffard yeah send in a PR if you have the time as the "valid crumb" setting should be handled behind the scenes in this client without the user having to specify anything.

And as @choweiyuan noted: you can always use a token but this is still a new bug of sorts.

@tbouffard
Copy link
Contributor Author

@choweiyuan yep, I am aware of this and this works pretty well.
My main concern is that the lib stops working on Jenkins upgrade, and as the example provided in the README uses user/password as credentials, it is disturbing as an end-user point of view.
In addition, the Jenkins official documentation advertises the jenkins-rest lib a lot, so it is better to have it to work out of the box 😃
See

@cdancy I plan to work on it on Thursday

tbouffard added a commit to tbouffard/jenkins-rest that referenced this issue Oct 10, 2019
@daverod24
Copy link

daverod24 commented Oct 29, 2019

Good estimates

I have this problem activating CSRF Protection in the latest LTS version
Centos 7.7
Jenkins version. 2,190.1 (installed by yum, not in container)
 
I get the crumb

crumb = $ (curl -u "admin: admin" -s 'http://192.168.10.2:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')

and then I pass it with the operation that I want to perform

curl -u "admin: admin" -H "$ crumb" -X POST 'http://192.168.10.2:8080/job/ENV/build?delay=0sec'

this is the way out

<meta http-equiv = "Content-Type" content = "text / html; charset = utf-8" />
<title> Error 403 No valid crumb was included in the request </title>
</head>
<body> <h2> HTTP ERROR 403 </h2>
<p> Problem accessing / job / ENV / build. Reason:
<pre> No valid crumb was included in the request </pre> 

I would like to know what state this is or what is the new way of working with the API to launch groovy scripts

Thanks in advance
Regards

@tbouffard
Copy link
Contributor Author

@d3adp007 when retrieving the crumb, you have to also retrieve the JSESSIONID cookie and pass it to subsquent API call (see #70)

@thiagoalves
Copy link

After a couple of hours of struggling, I was able to make it work with curl:

export JENKINS_URL=http://localhost
export JENKINS_USER=user
export JENKINS_TOKEN=mytoken
export COOKIE_JAR=/tmp/cookies

JENKINS_CRUMB=$(curl --silent --cookie-jar $COOKIE_JAR $JENKINS_URL'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)' -u $JENKINS_USER:$JENKINS_TOKEN)

echo $JENKINS_CRUMB

curl -I --cookie $COOKIE_JAR $JENKINS_URL/createItem?name=yourJob --data-binary @jenkins/config.xml -H $JENKINS_CRUMB -H "Content-Type:text/xml" -u $JENKINS_USER:$JENKINS_TOKEN -v

tbouffard added a commit to tbouffard/jenkins-rest that referenced this issue Dec 13, 2019
@maniankara
Copy link

Or, if you do not want to pass the crumb as header and for deleting a build $BUILD_NUMBER for a job $JOB_NAME,
curl -XPOST -I --cookie $COOKIE_JAR $JENKINS_URL/job/$JOB_NAME/$BUILD_NUMBER/doDelete?${JENKINS_CRUMB/:/=} -u $JENKINS_USER:$JENKINS_TOKEN -v

@satishpatro44
Copy link

I faced this issue where disable/enable project by non admin user. or continuous disable/ enable by admin user

@MimoJSRepo
Copy link

is there any solutiion for this '403 No valid crumb was included in the request', I set up log in in Jenkins using Okta and SAML but I am getting this message everytime I login :(

I was trying for many days, and no solutions seem to be working

@tbouffard
Copy link
Contributor Author

@satishpatro44 @MimoJSRepo are you facing an issue when you are using the jenkins-rest library or when you are using something else?
For jenkins-rest, this is fixed as of version 0.0.22, see https://github.com/cdancy/jenkins-rest/blob/master/RELEASE_NOTES.md#version-0022-december-16-2019

@satishpatro44
Copy link

satishpatro44 commented Apr 21, 2020

my mistake. It's not jenkins-rest. Sorry. It is direct Jenkins UI. I though Jenkin Rest API is part of official Jenkins

@tbouffard
Copy link
Contributor Author

my mistake. It's not jenkins-rest. Sorry. It is direct Jenkins UI. I though Jenkin Rest API is part of official Jenkins

Yes, the Jenkins REST API is part of official Jenkins, see https://wiki.jenkins.io/display/JENKINS/Remote+access+API
jenkins-rest is a java client implementation of the Jenkins REST API

@martinda
Copy link
Collaborator

@tbouffard No, jenkins-rest is NOT part of official Jenkins. I am the person who put the link there along with other links to external REST API libraries. To be part of Jenkins, this project would have to be hosted under the https://github.com/jenkinsci organization.

@tbouffard
Copy link
Contributor Author

@martinda that is exactly what I had in mind, but probably, I wasn't clear enough 😉, so let me rephrase

Jenkins officially provides REST API for machine interactions, see https://wiki.jenkins.io/display/JENKINS/Remote+access+API

Jenkins provides machine-consumable remote access API to its functionalities.
Remote access API is offered in a REST-like style.

jenkins-rest is a java client for working with Jenkins REST API
Other Jenkins REST API java clients exist, for instance jenkinsci java-client-api (which is under the umbrella of the Jenkins GitHub Organization) but this one currently suffers from the 403 No valid crumb was included in the request bug, see jenkinsci/java-client-api#429

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

Successfully merging a pull request may close this issue.

10 participants