Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow_x00=False not affecting Headers and Cookies [BUG] #2220

Closed
3 tasks done
Harrison88 opened this issue May 30, 2024 · 4 comments · Fixed by #2222
Closed
3 tasks done

allow_x00=False not affecting Headers and Cookies [BUG] #2220

Harrison88 opened this issue May 30, 2024 · 4 comments · Fixed by #2222
Assignees
Labels
Difficulty: Beginner Ideal for newcomers Priority: High Important but not urgent Type: Bug Errors or unexpected behavior

Comments

@Harrison88
Copy link

Checklist

  • I checked the FAQ section of the documentation
  • I looked for similar issues in the issue tracker
  • I am using the latest version of Schemathesis

Describe the bug

When running Schemathesis tests, I get errors from Postgres about null bytes. Possibly related to #2072.

To Reproduce

  1. Install FastAPI and Schemathesis.

  2. Run this code:

import warnings
from typing import Annotated

import schemathesis
from fastapi import Cookie, FastAPI, Header
from hypothesis.errors import NonInteractiveExampleWarning
from schemathesis.generation import GenerationConfig

warnings.filterwarnings("ignore", category=NonInteractiveExampleWarning)

app = FastAPI()


@app.post("/test")
def test(x_test: Annotated[str, Header()], test_cookie: Annotated[str, Cookie()]):
    return x_test


schemathesis.experimental.OPEN_API_3_1.enable()
schema = schemathesis.from_asgi(
    "/openapi.json",
    app,
    generation_config=GenerationConfig(allow_x00=False),
)

operation = schema["/test"]["POST"]
strategy = operation.as_strategy()


while True:
    case = strategy.example()
    if "\x00" in case.headers["x-test"]:
        print("Found null byte in header")
        break

while True:
    case = strategy.example()
    if "\x00" in case.cookies["test_cookie"]:
        print("Found null byte in cookie")
        break
  1. After a few seconds, it should print that it found null bytes.

I also checked query parameters and form data, but those seemed to respect the configuration option.

Please include a minimal API schema causing this issue:
The API schema from the code above:

{'openapi': '3.1.0', 'info': {'title': 'FastAPI', 'version': '0.1.0'}, 'paths': {'/test': {'post': {'summary': 'Test', 'operationId': 'test_test_post', 'parameters': [{'name': 'x-test', 'in': 'header', 'required': True, 'schema': {'type': 'string', 'title': 'X-Test'}}, {'name': 'test_cookie', 'in': 'cookie', 'required': True, 'schema': {'type': 'string', 'title': 'Test Cookie'}}], 'responses': {'200': {'description': 'Successful Response', 'content': {'application/json': {'schema': {}}}}, '422': {'description': 'Validation Error', 'content': {'application/json': {'schema': {'$ref': '#/components/schemas/HTTPValidationError'}}}}}}}}, 'components': {'schemas': {'HTTPValidationError': {'properties': {'detail': {'items': {'$ref': '#/components/schemas/ValidationError'}, 'type': 'array', 'title': 'Detail'}}, 'type': 'object', 'title': 'HTTPValidationError'}, 'ValidationError': {'properties': {'loc': {'items': {'anyOf': [{'type': 'string'}, {'type': 'integer'}]}, 'type': 'array', 'title': 'Location'}, 'msg': {'type': 'string', 'title': 'Message'}, 'type': {'type': 'string', 'title': 'Error Type'}}, 'type': 'object', 'required': ['loc', 'msg', 'type'], 'title': 'ValidationError'}}}}

Expected behavior

Using the allow_x00 configuration option should prevent null bytes in all strings.

Environment

- OS: Linux
- Python version: 3.12
- Schemathesis version: 3.28.1
- Spec version: Open API 3.1.0
@Harrison88 Harrison88 added Status: Needs Triage Requires initial assessment to categorize and prioritize Type: Bug Errors or unexpected behavior labels May 30, 2024
@Stranger6667
Copy link
Member

Thanks for reporting, I can confirm the issue. It happens because if there is a custom format keyword, then allow_x00 is ignored. Schemathesis implicitly adds format: _header_value (if no format is already in place) to speed up data generation.

So, the fix would be to pass a bit different custom format when this config option is present.

if not generation_config.allow_x00:
    custom_formats[HEADER_FORMAT] = header_values(blacklist_characters="\n\r\x00")

@Stranger6667 Stranger6667 added Priority: High Important but not urgent Difficulty: Beginner Ideal for newcomers and removed Status: Needs Triage Requires initial assessment to categorize and prioritize labels May 30, 2024
@Stranger6667
Copy link
Member

P.S. Thank you for the detailed reproduction code. It helped me a lot

Stranger6667 added a commit that referenced this issue May 30, 2024
Ref: #2220

Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
Stranger6667 added a commit that referenced this issue May 30, 2024
Ref: #2220

Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
@Harrison88
Copy link
Author

@Stranger6667 Thanks for the quick response!

Stranger6667 added a commit that referenced this issue May 30, 2024
Ref: #2220

Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
@Stranger6667
Copy link
Member

The fix is released in 3.29.0 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Difficulty: Beginner Ideal for newcomers Priority: High Important but not urgent Type: Bug Errors or unexpected behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants