# crumbIssuer

* [enables proxy compatibility on startup](#enables-proxy-compatibility-on-startup)
* [Improved CSRF protection](#improved-csrf-protection)
* [working with session after `2.176.2` since SECURITY-626](#working-with-session-after-21762-since-security-626)

#### [enables proxy compatibility on startup](https://issues.jenkins.io/browse/JENKINS-50767?focusedCommentId=336011\&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-336011)

```bash
-Djenkins.model.Jenkins.crumbIssuerProxyCompatibility=true
```

* temporary settings in Script:

  ```groovy
  System.setProperty('jenkins.model.Jenkins.crumbIssuerProxyCompatibility', 'true')
  System.getProperty('jenkins.model.Jenkins.crumbIssuerProxyCompatibility')
  ```

**change in `Configure Global Security`**

![enable/disable crumb compatibility](/files/DedlISJuwnbAYMo6tC6P)

#### [Improved CSRF protection](https://www.jenkins.io/doc/upgrade-guide/2.176/#SECURITY-626)

> Upgrading to Jenkins 2.176.2
>
> * [SECURITY-626](https://www.jenkins.io/security/advisory/2019-07-17/#SECURITY-626)
> * [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
>
> /
>
> tokens (crumbs) are now only valid for the web session they were created in to limit the impact of attackers obtaining them. Scripts that obtain a crumb using the \`/crumbIssuer/api\` URL will now fail to perform actions protected from CSRF unless the scripts retain the web session ID in subsequent requests. - \[CSRF Protection Explained]\(<https://support.cloudbees.com/hc/en-us/articles/219257077-CSRF-Protection-Explained>)

{% hint style="info" %}
Scripts could instead use an API token, which has not required a CSRF token (crumb)\
since Jenkins [2.96](https://www.jenkins.io/changelog/#v2.96).
{% endhint %}

#### working with session after [`2.176.2` since SECURITY-626](https://www.jenkins.io/security/advisory/2019-07-17/#SECURITY-626)

> references:
>
> * [via `curl`](https://support.cloudbees.com/hc/en-us/articles/219257077-CSRF-Protection-Explained#usingcurl)
> * [via `wget`](https://support.cloudbees.com/hc/en-us/articles/219257077-CSRF-Protection-Explained#usingwget)

**via `curl`**

> \[!TIP] check cookie
>
> ```bash
> $ cat ${COOKIEJAR}
> # Netscape HTTP Cookie File
> # https://curl.se/docs/http-cookies.html
> # This file was generated by libcurl! Edit at your own risk.
> #HttpOnly_jenkins.marslo.com.com  FALSE / TRUE  0 JSESSIONID.a054fd7a node015xsx4fybmo2k1oxpjg5f2dzw4265.node0
> ```

```bash
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
```

**via `wget`**

```bash
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
```

**example**

* with crumb only

  > will get issue `403: No valid crumb was included in the request`

  ```bash
  $ curl -H ${crumb} \
         -X POST \
         https://jenkins.marslo.com/safeRestart
  <html>
  <head>
  <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 No valid crumb was included in the request</h2>
  <table>
  <tr><th>URI:</th><td>/safeRestart</td></tr>
  <tr><th>STATUS:</th><td>403</td></tr>
  <tr><th>MESSAGE:</th><td>No valid crumb was included in the request</td></tr>
  <tr><th>SERVLET:</th><td>Stapler</td></tr>
  </table>
  <hr><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.39.v20210325</a><hr/>

  </body>
  </html>
  ```
* with crumb and cookie

  ```bash
  $ COOKIEJAR="$(mktemp)"
  $ CRUMB="$(curl -s \
                --cookie-jar "${COOKIEJAR}" \
                "https://jenkins.marslo.com/crumbIssuer/api/json" |
                jq -r '.crumbRequestField + ":" + .crumb'
           )"
  $ curl -v \
         -X POST \
         --cookie "${COOKIEJAR}" \
         -H "${CRUMB}" \
         https://jenkins.marslo.com/safeRestart
  ...
  * Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
  < HTTP/2 302
  < date: Wed, 09 Jun 2021 15:25:14 GMT
  < location: https://jenkins.marslo.com/
  < server: Jetty(9.4.39.v20210325)
  < vary: Accept-Encoding
  < x-content-type-options: nosniff
  < content-length: 0
  <
  * Connection #0 to host jenkins.marslo.com left intact
  ```

**To disable this improvement you can set the system property**

* via `JAVA_OPTS`

  ```bash
  -Dhudson.security.csrf.DefaultCrumbIssuer.EXCLUDE_SESSION_ID=true
  ```

  * temporary settings in Script:

    > * example for [SECURITY-626](https://www.jenkins.io/doc/upgrade-guide/2.176/#upgrading-to-jenkins-lts-2-176-3)

    ```groovy
    System.setProperty('hudson.security.csrf.DefaultCrumbIssuer.EXCLUDE_SESSION_ID', 'true')
    System.getProperty('hudson.security.csrf.DefaultCrumbIssuer.EXCLUDE_SESSION_ID')
    ```
* via plugin [Strict Crumb Issuer](https://plugins.jenkins.io/strict-crumb-issuer)

**get crumberIssuer with script**

```groovy
import org.jenkinsci.plugins.strictcrumbissuer.StrictCrumbIssuer

StrictCrumbIssuer issuer = jenkins.model.Jenkins.instance.crumbIssuer
String jenkinsCrumb = "${issuer.crumbRequestField}:${issuer.crumb}"
println jenkinsCrumb
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://imarslo.gitbook.io/book/jenkins/plugins/crumbissuer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
