Skip to content
This repository has been archived by the owner on Dec 31, 2023. It is now read-only.

Produce a better error in case of malformed JSON #319

Merged
merged 2 commits into from
May 29, 2022

Conversation

oakkitten
Copy link
Contributor

@oakkitten oakkitten commented May 12, 2022

This solves the same issue that #317 solves, albeit slightly differently. I was hoping that the author would reopen the issue... There's a few differences;

  • If origin is not allowed, 403 is returned in case of malformed JSON, and
  • In case of JSON error, error string is returned to user.

I also noticed this bit: params['params'] = params.get('params', {}). It's a tad dangerous since this part of code can be run when not allowed, and params can be present but not be a dictionary. In this case the plugin would “crash”, and while this only amounts to showing a window with an error, it can be theoretically triggered by a malicious website, so I opted for verifying request schema. (Anki comes with jsonschema which is used to verify addon configurations.) This is not ideal, but I wanted to touch as little code as possible.

I added a few tests that test behavior around the change.

@nvlled Could you please look at this and tell if I did something stupid? 😬

$ curl localhost:8777 -X POST -i -d '{"action": "version", "version": 6},' && echo ␄
HTTP/1.1 200 OK
Content-Type: text/json
Access-Control-Allow-Origin: http://localhost
Access-Control-Allow-Headers: *
Content-Length: 67

{"result": null, "error": "Extra data: line 1 column 36 (char 35)"}␄

$ curl localhost:8777 -X POST -i -d '{"action": "version", "version": 6},' -H "Origin: foo" && echo ␄
HTTP/1.1 403 Forbidden
Access-Control-Allow-Origin: http://localhost
Access-Control-Allow-Headers: *

␄
@FooSoft
Copy link
Owner

FooSoft commented May 15, 2022

Looks great to me :)

@oakkitten
Copy link
Contributor Author

I really wish @nvlled said something, it now feels like I stole their PR :<

@nvlled
Copy link

nvlled commented May 17, 2022

Sorry, I couldn't find the time to give a thorough review. But I do one nit: explicity initialize params outside of the try block. Something like:

params = {}
try:
    params = json.loads(req.body.decode('utf-8'))

The bug I encountered was specifically caused by an uninitialized params variable. It would be nice to prevent this from happening when changes are made in the future.

@oakkitten
Copy link
Contributor Author

Ah, that should be solved in this PR! In the except part of the of the block, if continuing, the params variable is set. I suppose one could also set it before like in your example. It's just that I use PyCharm and I'm accustomed to it warning me if I forget to set a variable in one of the execution branches.

anki-connect/plugin/web.py

Lines 179 to 192 in 9c3310a

try:
params = json.loads(req.body.decode('utf-8'))
jsonschema.validate(params, request_schema)
except (ValueError, jsonschema.ValidationError) as e:
if allowed:
if len(req.body) == 0:
body = f"AnkiConnect v.{util.setting('apiVersion')}".encode()
else:
reply = format_exception_reply(util.setting('apiVersion'), e)
body = json.dumps(reply).encode('utf-8')
headers = self.buildHeaders(corsOrigin, body)
return self.buildResponse(headers, body)
else:
params = {} # trigger the 403 response below

I'd still appreciate the review! Anyway, I guess I better make this not a draft since, well, the button says “Ready for review” :p

@oakkitten oakkitten marked this pull request as ready for review May 17, 2022 15:39
@FooSoft
Copy link
Owner

FooSoft commented May 29, 2022

Looks good to me!

@FooSoft FooSoft merged commit 23c25dd into FooSoft:master May 29, 2022
@oakkitten
Copy link
Contributor Author

P.S. the tests are failing now due to protobuf update (packages anki/aqt don't pin dependencies), I'll have a fix shortly

@FooSoft
Copy link
Owner

FooSoft commented May 30, 2022

Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants