JavaScriptMethod & 403 - No valid crumb was included in the request

44 views
Skip to first unread message

Shaun Thompson

unread,
Aug 28, 2020, 3:53:39 PM8/28/20
to Jenkins Developers
I'm developing a custom plugin that includes a class with a method annotated with 
@JavaScriptMethod.  

It was working until I updated to the latest version of Jenkins 2.250 which forces CSRF protection.

I can't find anything to indicate how to get/add the CSRF token when calling this method

@JavaScriptMethod
public void setUserId(final String value) {
        userId = value;
}

<st:bind var="instance" value="${it}"/>

instance.setUserId($('#userId')

Shaun Thompson

unread,
Aug 28, 2020, 4:06:03 PM8/28/20
to Jenkins Developers
After looking at it a bit - it appears that the crumb header is being issued with the request as `Crumb`.

The CrumbFilter is looking for `Jenkins-Crumb` or `.crumb`.

As such it fails.  Appears to be a bug to me?

Ullrich Hafner

unread,
Aug 28, 2020, 4:20:58 PM8/28/20
to Jenkins Developers
I’m on 2.254 and there everything looks good on the JS side.  

Can you see the JUnit or warnings trend charts? They use @JavaScriptMethod as well. 

--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/a279989d-ebdb-45df-ad72-7d50e2f61bd6n%40googlegroups.com.

Shaun Thompson

unread,
Aug 28, 2020, 4:33:15 PM8/28/20
to Jenkins Developers
At least for the JUnit plugin they are referencing an older version of Jenkins.

Looking at org/kohsuke/stapler/bind.js shows the following:

            if(window.jQuery === window.$) { //Is jQuery the active framework?
                $.ajax({
                    type: "POST",
                    url: url+methodName,
                    data: stringify(a),
                    contentType: 'application/x-stapler-method-invocation;charset=UTF-8',
                    headers: {'Crumb':crumb},
                    dataType: "json",
                    success: function(data, textStatus, jqXHR) {
                        if (callback!=null) {
                            var t = {};
                            t.responseObject = function() {
                                return data;
                            };
                            callback(t);
                        }
                    }
                });
            } else { //Assume prototype should work
                new Ajax.Request(url+methodName, {
                    method: 'post',
                    requestHeaders: {'Content-type':'application/x-stapler-method-invocation;charset=UTF-8','Crumb':crumb},
                    postBody: stringify(a),
                    onSuccess: function(t) {
                        if (callback!=null) {
                            t.responseObject = function() {
                                return eval('('+this.responseText+')');
                            };
                            callback(t);
                        }
                    }
                });
            }


Ullrich Hafner

unread,
Aug 28, 2020, 4:41:11 PM8/28/20
to Jenkins Developers

Am 28.08.2020 um 22:33 schrieb Shaun Thompson <sth...@gmail.com>:

At least for the JUnit plugin they are referencing an older version of Jenkins.


The compile time dependency is < 2.250, yes. But it will replaced with the version you actually installed in Jenkins. But can you see the chart? Can you upgrade to 2.254 and retry? 

Shaun Thompson

unread,
Aug 28, 2020, 5:28:13 PM8/28/20
to Jenkins Developers
Upgraded to 2.254 and now my plugin isn't loaded on startup but is shown as installed on the manage plugins page. 

The source posted above still appears to be the same for 2.254 so I assume the problem still persists.

Once I figure out why my plugin isn't loading I'll test again.

Shaun Thompson

unread,
Aug 28, 2020, 10:28:12 PM8/28/20
to Jenkins Developers
So the JUnit plugin JavaScript method works as it adds both `Crumb` and `Jenkins-Crumb` to the outgoing request headers.

This method is invoked through the echarts API but I haven't found any reference yet where it would append to the request headers.

Shaun Thompson

unread,
Aug 28, 2020, 10:58:29 PM8/28/20
to Jenkins Developers
So the difference between the JUnit @JavaScriptMethod and mine is that, I'm using jQuery.

bind.js in the JUnit scenario will use  Ajax.Request which has a patch in prototype.js that adds the additional header `Jenkins-Crumb` 

// KK patch -- handle crumb for POST automatically by adding a header
    if(this.options.method=="post") {
        if(this.options.requestHeaders==undefined)
            this.options.requestHeaders = {};
        crumb.wrap(this.options.requestHeaders);
    }
// KK patch until here

For now I'll use the startup param -Dhudson.security.csrf.requestfield=Crumb to work past this.

Ullrich Hafner

unread,
Aug 29, 2020, 3:58:20 AM8/29/20
to Jenkins Developers
I see. Then this is a bug indeed. 

Ullrich Hafner

unread,
Sep 2, 2020, 5:50:41 PM9/2/20
to Jenkins Developers

I can confirm the bug. It seems that actually something in the latest Jenkins versions changed that get Ajax calls blocked that worked before (latest LTS works fine). Ajax works on the job page (trend charts) but not on individual plugin views that use JS (and jQuery). E.g. my warnings plugin tables will now be blocked with the same error message (no valid crumb in request).

Has anybody an idea when such a change has been integrated? 
Reply all
Reply to author
Forward
0 new messages