# 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](https://4276369325-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpuTw6o3ALq0J3Uf7ELc7%2Fuploads%2Fgit-blob-42f6d5aa14c85306182b4851749fed87c4d02f28%2FcrumbIssuer-enable.png?alt=media)

#### [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
```
