View Issue Details

IDProjectCategoryView StatusLast Update
0008341Talerlibeufin-bankpublic2024-03-07 20:53
ReporterFlorian Dold Assigned ToAntoine A  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Target Version0.9.4Fixed in Version0.9.4 
Summary0008341: libeufin-bank does not properly read the body of some HTTP POST requests
DescriptionThis happened with wallet-core running under qtart, which internally uses libcurl to make HTTP requests.

Instead of properly reading the request body, libeufin-bank only *partially* reads the request body.

That behavior is rather dependent on the timing. I've only seen it with chunked encoding and when the client uses "Expect: 100-continue".
Steps To ReproduceGood case:

$ ( cat req-http.txt; cat req2-http.txt; cat req3-http.txt; sleep 5 ) | ncat --ssl bank.taler.fdold.eu 443

HTTP/1.1 200 OK
Alt-Svc: h3=":443"; ma=2592000
Content-Length: 98
Content-Type: application/json
Server: Caddy
Vary: Origin
Www-Authenticate: Basic
Date: Tue, 06 Feb 2024 22:15:39 GMT

{"internal_payto_uri":"payto://iban/SANDBOXX/DE9316061713904?receiver-name=user-hpmjr59818reqhtj"}

-----------------------------------------------------------------------------------------------------------------------------------------

Bad case (notice the extra sleeps):

$ ( cat req-http.txt; sleep 1; cat req2-http.txt; sleep 1; cat req3-http.txt; sleep 5 ) | ncat --ssl bank.taler.fdold.eu 443

HTTP/1.1 400 Bad Request
Alt-Svc: h3=":443"; ma=2592000
Content-Length: 337
Content-Type: application/json
Server: Caddy
Vary: Origin
Www-Authenticate: Basic
Date: Tue, 06 Feb 2024 22:14:50 GMT

{"code":22,"hint":"Failed to convert request body to class tech.libeufin.bank.RegisterAccountRequest","detail":"Unexpected JSON token at offset 97: Expected end of the object '}', but had 'j' instead at path: $\nJSON input: {\"username\":\"user-hpmjr59818reqhtj\",\"password\":\"pw-ekkv26633taymzys\",\"name\":\"user-hpmjr59818reqhtj\""}
TagsNo tags attached.
Attached Files
req3-http.txt (5 bytes)   
0

req3-http.txt (5 bytes)   
req-http.txt (181 bytes)   
POST /accounts HTTP/1.1
Host: bank.taler.fdold.eu
User-Agent: qtart
Transfer-Encoding: chunked
Content-Type: application/json
Accept: application/json
Expect: 100-continue

req-http.txt (181 bytes)   
req2-http.txt (106 bytes)   
64
{"username":"user-hpmjr59818reqhtj","password":"pw-ekkv26633taymzys","name":"user-hpmjr59818reqhtj"}
req2-http.txt (106 bytes)   

Relationships

child of 0008273 closedFlorian Dold package and upload libeufin 0.9.4 to ftp and stable Debian/Ubuntu server 

Activities

Florian Dold

2024-02-06 23:18

manager   ~0021181

Here's the request (that gets the 400 response) as dumped by curl:

=> Send header, 0000000181 bytes (0x000000b5)
0000: 50 4f 53 54 20 2f 61 63 63 6f 75 6e 74 73 20 48 POST /accounts H
0010: 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 62 TTP/1.1..Host: b
0020: 61 6e 6b 2e 74 61 6c 65 72 2e 66 64 6f 6c 64 2e ank.taler.fdold.
0030: 65 75 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 eu..User-Agent:
0040: 71 74 61 72 74 0d 0a 54 72 61 6e 73 66 65 72 2d qtart..Transfer-
0050: 45 6e 63 6f 64 69 6e 67 3a 20 63 68 75 6e 6b 65 Encoding: chunke
0060: 64 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a d..Content-Type:
0070: 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f application/jso
0080: 6e 0d 0a 41 63 63 65 70 74 3a 20 61 70 70 6c 69 n..Accept: appli
0090: 63 61 74 69 6f 6e 2f 6a 73 6f 6e 0d 0a 45 78 70 cation/json..Exp
00a0: 65 63 74 3a 20 31 30 30 2d 63 6f 6e 74 69 6e 75 ect: 100-continu
00b0: 65 0d 0a 0d 0a e....
== Info: Mark bundle as not supporting multiuse
<= Recv header, 0000000023 bytes (0x00000017)
0000: 48 54 54 50 2f 31 2e 31 20 31 30 30 20 43 6f 6e HTTP/1.1 100 Con
0010: 74 69 6e 75 65 0d 0a tinue..
== Info: Mark bundle as not supporting multiuse
<= Recv header, 0000000023 bytes (0x00000017)
0000: 48 54 54 50 2f 31 2e 31 20 31 30 30 20 43 6f 6e HTTP/1.1 100 Con
0010: 74 69 6e 75 65 0d 0a tinue..
<= Recv header, 0000000032 bytes (0x00000020)
0000: 41 6c 74 2d 53 76 63 3a 20 68 33 3d 22 3a 34 34 Alt-Svc: h3=":44
0010: 33 22 3b 20 6d 61 3d 32 35 39 32 30 30 30 0d 0a 3"; ma=2592000..
<= Recv header, 0000000015 bytes (0x0000000f)
0000: 53 65 72 76 65 72 3a 20 43 61 64 64 79 0d 0a Server: Caddy..
=> Send data, 0000000106 bytes (0x0000006a)
0000: 36 34 0d 0a 7b 22 75 73 65 72 6e 61 6d 65 22 3a 64..{"username":
0010: 22 75 73 65 72 2d 68 70 6d 6a 72 35 39 38 31 38 "user-hpmjr59818
0020: 72 65 71 68 74 6a 22 2c 22 70 61 73 73 77 6f 72 reqhtj","passwor
0030: 64 22 3a 22 70 77 2d 65 6b 6b 76 32 36 36 33 33 d":"pw-ekkv26633
0040: 74 61 79 6d 7a 79 73 22 2c 22 6e 61 6d 65 22 3a taymzys","name":
0050: 22 75 73 65 72 2d 68 70 6d 6a 72 35 39 38 31 38 "user-hpmjr59818
0060: 72 65 71 68 74 6a 22 7d 0d 0a reqhtj"}..
== Info: Signaling end of chunked upload via terminating chunk.
=> Send data, 0000000005 bytes (0x00000005)
0000: 30 0d 0a 0d 0a 0....

Florian Dold

2024-02-06 23:36

manager   ~0021183

Another interesting thing is: I can't actually reproduce this on demo/test.taler.net.

The main difference is that taler.fdold.eu uses Caddy (instead of nginx) as the TLS-terminating reverse proxy.

Florian Dold

2024-02-06 23:50

manager   ~0021185

Last edited: 2024-02-06 23:52

However, what's interesting is that if I modify the request (req-http.txt) to make a request against the exchange running against the same reverse proxy, it *doesn't* complain about malformed JSON. It just points to missing fields in the body *after* parsing the body successfully.

Or in other words:
* NGINX + taler-exchange-httpd => fine
* NGINX + libeufin-bank => fine
* Caddy + taler-exchange-httpd => fine
* Caddy + libeufin-bank => bad!

Antoine A

2024-02-07 02:42

developer   ~0021186

The crazy thing is that the error message prints the whole body!

Florian Dold

2024-02-07 12:51

manager   ~0021189

No, I think in the error message, the body that is printed is actually missing the terminating "}". It's just a bit confusing that there is a "}" present, but that's part of the outer JSON for the error message.

Antoine A

2024-02-12 16:19

developer   ~0021253

Fixed in ea95cfc772adc4a919c097c9f4847a64f3b6df37

Issue History

Date Modified Username Field Change
2024-02-06 23:17 Florian Dold New Issue
2024-02-06 23:17 Florian Dold Status new => assigned
2024-02-06 23:17 Florian Dold Assigned To => Antoine A
2024-02-06 23:17 Florian Dold File Added: req3-http.txt
2024-02-06 23:17 Florian Dold File Added: req-http.txt
2024-02-06 23:17 Florian Dold File Added: req2-http.txt
2024-02-06 23:18 Florian Dold Note Added: 0021181
2024-02-06 23:36 Florian Dold Note Added: 0021183
2024-02-06 23:50 Florian Dold Note Added: 0021185
2024-02-06 23:52 Florian Dold Note Edited: 0021185
2024-02-07 02:42 Antoine A Note Added: 0021186
2024-02-07 12:51 Florian Dold Note Added: 0021189
2024-02-09 00:51 Christian Grothoff Relationship added child of 0008273
2024-02-12 16:19 Antoine A Status assigned => resolved
2024-02-12 16:19 Antoine A Resolution open => fixed
2024-02-12 16:19 Antoine A Note Added: 0021253
2024-03-07 20:53 Christian Grothoff Fixed in Version => 0.9.4
2024-03-07 20:53 Christian Grothoff Status resolved => closed