skip to Main Content

I am attempting to add a security token to all my AJAX $.post calls.

I set up the security token to be automatically added using the following code

$.ajaxSetup({
     beforeSend: function (jqXHR, settings) {
        settings.data += "&sessionID="+v_sessionID;
  }
});

and then code such as the following, will have the security token automatically appended

$.post("ajax/p_getOnePosition.jsp", {
    positionNo: positionNo,
}, function(response2) {

The code works well, but not for functions with no parameters such as

$.post("ajax/p_clearFilters.jsp", {

}, function(response2) {

Any idea why this should be?

I can fix it by simply adding a dummy parameter dummy:1 to the code

 $.post("ajax/p_clearFilters.jsp", {
       dummy:1
    }, function(response2) {

So I tried to do

 $.ajaxSetup({
     beforeSend: function (jqXHR, settings) {
        var noParameters=(settings.data==null || settings.data==undefined || settings.data=='');
        settings.data += (noParameters?"dummy=1":"") +"&sessionID="+v_sessionID;
  }
});

but this did not mimic having the dummy=1 manually added, and the security token was not available in the request.

UPDATE

I realize in retrospect (after @Rory McCrossan’s comment and @Louys Patrice Bessette’s answer) that my question was incomplete. I should have also included in my question the JSP code that I use to retrieve the parameter.

<%
String csrfSessionID = SecurityIssues.StringToAlphaNumericStr(request.getParameter("sessionID"));
%>

2

Answers


  1. Chosen as BEST ANSWER

    After working through @Rory McCrossan's comment and @Louys Patrice Bessette's answer - thank you very much - I see that when beforeSend adds to an empty parameter list, then the SESSIONID is sent as part of the Request Payload, and when beforeSend adds to pre-existing parameter list, then SESSIONID is sent as part of the Form Data. This makes a difference in retrieving the parameters.

    For data as part of the Form Data then it can be retrieved by the following:

    String csrfSessionID = SecurityIssues.StringToAlphaNumericStr(request.getParameter("sessionID"));
    

    For data as part of the request Payload it can be retrieved by the following: See @Fizer Khan's answer in Getting request payload from POST request in Java servlet

    StringBuilder buffer = new StringBuilder();
    java.io.BufferedReader reader = request.getReader();
    String line;
    while ((line = reader.readLine()) != null) {
        buffer.append(line);
        buffer.append(System.lineSeparator());
    }
    String data = buffer.toString();
    System.out.println("data:"+data);
    

    These two code snippets are mutually exclusive. The first code cannot retrieve from the Request Payload, and the second code cannot retrieve from the Form Data

    Note that probably a better answer would force the beforeSend to send the SessionID in the Form Data in all cases, but this is a good workaround for now!


  2. You have three data cases:

    • undefined
    • empty
    • not empty

    Try that beforeSend function:

    $.ajaxSetup({
      beforeSend: function (jqXHR, settings) {
        
        // Undefined data
        settings.data = settings.data === undefined ? "" : settings.data;
    
        // Add the & or not in front of the sessionID
        settings.data +=
          (settings.data.length > 0 ? "&" : "") + "sessionID=SESSION_ID";
        console.log("before send:", settings.data);
        
      }
    });
    

    The below snippet always ends up in an error because the request url is https://example.com. 😉

    $.ajaxSetup({
      beforeSend: function (jqXHR, settings) {
        
        // Undefined data
        settings.data = settings.data === undefined ? "" : settings.data;
    
        // Add the & or not in front of the sessionID
        settings.data +=
          (settings.data.length > 0 ? "&" : "") + "sessionID=SESSION_ID";
        console.log("before send:", settings.data);
        
      }
    });
    
    $(".test").on("submit", function (e) {
      console.clear();
      e.preventDefault();
    
      let formId = $(this)[0].id;
      console.log( `You are trying the ${formId}`);
    
      let formValues;
      switch (formId) {
        
        case "test_1":
          // Do not set formValues on purpose...
          break;
        
        case "test_2":
          formValues = {};
          break;
    
        case "test_3":
          formValues = { firstName: "John", lastName: "Doh" };
          break;
    
      }
    
      console.log("on submit:", formValues);
    
      $.post("https://example.com", formValues)
        .done(function () {
          console.log("DONE");
        })
        .fail(function () {
          console.error("ERROR - (obviously!) - Check the Network tab-> example.com -> Headers -> Form Data");
        });
    });
    button{
      margin: 1em;
      width: 20em;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <form class="test" id="test_1">
      <button>Test #1 - Send an undefined object</button>
    </form>
    
    <form class="test" id="test_2">
      <button>Test #2 - Send an empty object</button>
    </form>
    
    <form class="test" id="test_3">
      <button>Test #3 - Send an object</button>
    </form>

    Also on CodePen

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search