Description
Bug summary
Hello Team,
Ben from Atlassian Networking.
We've been rolling out DDOS protection over the last few months.
We've become aware of some API clients sending body payloads in GET requests getting HTTP 403 from our DDOS provider (Cloudfront).
Unfortunately, this is not a rule we can adjust, even with help from AWS. It is a fundamental behavior of Cloudfront.
In our logs we are observing this library occasionally including a 2-byte payload in GET requests, which appears to be a {}
string.
We have walked your code and we are not 100% sure where the bug is, but we notice in https://github.com/pycontribs/jira/blob/main/jira/client.py that a {}
is occasionally used as a default for data
.
And in https://github.com/pycontribs/jira/blob/main/jira/resilientsession.py#L182-L186 these lines
data = original_kwargs.get("data", None)
if isinstance(data, dict):
# mypy ensures we don't do this,
# but for people subclassing we should preserve old behaviour
prepared_kwargs["data"] = json.dumps(data)
Do not seem to protect from the data kwarg persisting into the requests session with a {}
string.
>>> original_kwargs = {"data": {}}
>>> data = original_kwargs.get("data", None)
>>> isinstance(data, dict)
True
>>> json.dumps(data)
'{}'
It looks like there was an earlier attempt to fix this by @razziel89 in https://github.com/pycontribs/jira/pull/1471/files but this might be incomplete.
We're wondering if the code should be:
data = original_kwargs.get("data", None)
if isinstance(data, dict) and data:
# mypy ensures we don't do this,
# but for people subclassing we should preserve old behaviour
prepared_kwargs["data"] = json.dumps(data)
or
data = original_kwargs.get("data", None)
if isinstance(data, dict):
# mypy ensures we don't do this,
# but for people subclassing we should preserve old behaviour
if data:
prepared_kwargs["data"] = json.dumps(data)
else:
prepared_kwargs.pop("data", None)
or maybe
data = original_kwargs.get("data", None)
if isinstance(data, dict):
# mypy ensures we don't do this,
# but for people subclassing we should preserve old behaviour
if data:
prepared_kwargs["data"] = json.dumps(data)
else:
prepared_kwargs["data"] = None
One thing which gives us pause is we also see some hits on GET /rest/api/2/serverInfo carrying the 2-byte payload, and on code walk cannot see where data might be getting set.
For more information you can see https://developer.atlassian.com/cloud/jira/platform/changelog/#CHANGE-2328 and https://community.atlassian.com/t5/Atlassian-Platform-articles/Jira-Confluence-Cloud-APIs-return-403-Error-The-request-could/ba-p/2928153
Is there an existing issue for this?
- I have searched the existing issues
Jira Instance type
Jira Cloud (Hosted by Atlassian)
Jira instance version
No response
jira-python version
main
Python Interpreter version
3.9
Which operating systems have you used?
- Linux
- macOS
- Windows
Reproduction steps
-
Stack trace
-
Expected behaviour
Additional Context
No response