0

I make a POST request to REST API to upload a file. In Postman everything works fine. I add Basic authorization and custom CSRF (XSRF) token which I get from the server.

I want to make the same using cURL. I copied the code from Postman, and it does not seem to work. I believe that the error is related to CSRF because if I turn off CSRF on server and make the same cURL call without CSRF token, everything works fine.

Now some more details: That's what the command for cURL which Postman gives:

curl -X POST -H "XSRF: 79f51981-8e85-4e26-be1b-bf63aed92a42" -H "Authorization: Basic bbhjbjb=" -H "Cache-Control: no-cache" -H "Postman-Token: 76a7a43b-f407-15a2-aaff-5242b44d0f47" -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "package=@C:\Downloads\hello-world.zip" "http://host:port/api/import"

And that's the reply I get with --verbose

  • timeout on name lookup is not supported
  • Trying ::1...
  • Connected to localhost (::1) port 7777 (#0)
  • POST /api/import HTTP/1.1
  • Host: localhost:7777
  • User-Agent: curl/7.47.1
  • Accept: /
  • XSRF: 79f51981-8e85-4e26-be1b-bf63aed92a42
  • Authorization: Basic bbhjbjb=
  • Cache-Control: no-cache
  • Postman-Token: 76a7a43b-f407-15a2-aaff-5242b44d0f47
  • Content-Length: 31281
  • Expect: 100-continue
  • Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW; boundary=------------------------742d3475ac5f6aba
  • < HTTP/1.1 302 Found
  • < Set-Cookie: JSESSIONID=1qfjmbntrthxll;Path=/api < Expires: Thu, 01 Jan 1970 00:00:00 GMT
  • < Set-Cookie: XSRF=b29bd143-cc80-49ad-b495-711125678o;Path=/;Expires=Thu, 15-Dec-2016 10:28:46 GMT
  • < XSRF: b29bd143-cc80-49ad-b495-711125678o < Location:
  • http://localhost:7777/api/login/error.jsp?errorMessage=Access Denied
  • < Content-Length: 0
  • < Server: Jetty(9.2.17.v20160517)
  • HTTP error before end of send, stop sending
  • Closing connection 0

I am probably missing something very obvious here, but don't know what yet. Looks like I am redirected to login page, not being authenticated correctly, but do not know why (I do send XSRF in cURL). I tried also adding sessionid in cURL - also didn't work.

Any ideas and directions about where to search would be very appreciated!!!

lenach87
  • 949
  • 3
  • 11
  • 18
  • Have you tried using `-L` option (because of 302 found return from the server) ? – hlscalon Dec 14 '16 at 11:23
  • Thank you for the comment! I tried with -L got similar result around 50 times: "* Connection #1 to host localhost left intact * Issue another request to this URL: 'http://localhost:7777/api/login/error.jsp?errorMessage=Access+Denied' * Found bundle for host localhost: 0x285 [can pipeline] * Re-using existing connection! (#1) with host localhost * Connected to localhost (::1) port 7777 (#1)" – lenach87 Dec 14 '16 at 11:59
  • best guess, the XSRF token is a 1-time token, and you're using it first at postman, and it works great, then you use the same token at curl, not refreshing it, and it fails. how do you get the XSRF tokens? anyway, get 1, without using it at postman first, check if that works – hanshenrik Dec 15 '16 at 00:25
  • Thank you for the comment! I think the token is not a one-time - at least I can make many calls with the same token with Postman. I make a get request to one end-point and copy the XSRF token from there - I do the same for Postman and for curl, but for some reason with curl it does not work :( – lenach87 Dec 15 '16 at 09:16
  • Did you notice any different behavior on the server's end? For example, if I were to try to debug this, I would make my server `console.log` some info every time it was hit w/ a request, including its `url`, `method`, and `headers` properties, then check how the request from Postman vs curl are actually different. – therobinkim Dec 25 '16 at 07:14

4 Answers4

1

As mentioned in this post, add following option

--cookie "csrftoken=XXXXXX;sessionid=YYYYYYY"

along with

-H "X-CSRFToken: XXXXX" 
Community
  • 1
  • 1
csghone
  • 51
  • 4
0

It is unclear how your server side code is implemented. One visible difference can be seen here is the UserAgent string in request header User-Agent: curl/7.47.1. You may try with adding -A "Mozilla/5.0" with your curl request.

About the comment above regarding XSRF 1-time token; Your server is returning Set-Cookie header in response. It can happen that the postman is using that as cookie for second time request, and that's why it works for it over and over. You can try adding -H "Cookie: XSRF=b29bd143-cc80-49ad-b495-711125678o" at the end of your curl and see if that makes any difference.

Those are all wild guess. Better you add some code at your server side that can print the request-headers. Then make two requests, one from curl and other one from postman. After that check the difference between the request headers. That will give you some clue.

Sabuj Hassan
  • 38,281
  • 14
  • 75
  • 85
  • Thank you for the suggestions! I'll try them tomorrow and reply if it helps – lenach87 Dec 20 '16 at 22:42
  • Unfortunatelly these two headers did not help :(But I'll try as you suggested with adding code and then checking the difference in request headers – lenach87 Dec 21 '16 at 11:34
0

In the end it turned out that the session id was required (adding JSESSIONID in cURL solved the problem).

lenach87
  • 949
  • 3
  • 11
  • 18
-1

Without more info on the server side code, I'm not sure either. If you're making your call from cURL, and not Postman, do you really need the Postman-Token header? Maybe it will work if you remove -H "Postman-Token: 76a7a43b-f407-15a2-aaff-5242b44d0f47" from the code.

curl -X POST \
    -H "XSRF: 79f51981-8e85-4e26-be1b-bf63aed92a42" \
    -H "Authorization: Basic bbhjbjb=" \
    -H "Cache-Control: no-cache" \
    -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" \
    -F "package=@C:\Downloads\hello-world.zip" \
    "http://host:port/api/import"
amra
  • 16,125
  • 7
  • 50
  • 47
Shel
  • 64
  • 5