Skip to content

Commit 157745e

Browse files
committed
Additional properties policy
1 parent 0bc28fa commit 157745e

File tree

17 files changed

+97
-114
lines changed

17 files changed

+97
-114
lines changed

docs/configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ result = openapi.unmarshal_response(request, response)
136136

137137
By default, OpenAPI follows JSON Schema behavior: when an object schema omits `additionalProperties`, extra keys are allowed.
138138

139-
If you want stricter behavior, enable `strict_additional_properties`. In this mode, omitted `additionalProperties` is treated as `false`.
139+
If you want stricter behavior, change `additional_properties_default_policy` to `forbid`. In this mode, omitted `additionalProperties` is treated as `false`.
140140

141141
This mode is particularly useful for:
142142
- **Preventing data leaks**: Ensuring your API doesn't accidentally expose internal or sensitive fields in responses that aren't explicitly documented.
@@ -148,7 +148,7 @@ from openapi_core import Config
148148
from openapi_core import OpenAPI
149149

150150
config = Config(
151-
strict_additional_properties=True,
151+
additional_properties_default_policy="forbid",
152152
)
153153
openapi = OpenAPI.from_file_path('openapi.json', config=config)
154154
```

openapi_core/app.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def request_validator(self) -> RequestValidator:
427427
spec_validator_cls=self.config.spec_validator_cls,
428428
extra_format_validators=self.config.extra_format_validators,
429429
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
430-
strict_additional_properties=self.config.strict_additional_properties,
430+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
431431
security_provider_factory=self.config.security_provider_factory,
432432
)
433433

@@ -446,7 +446,7 @@ def response_validator(self) -> ResponseValidator:
446446
spec_validator_cls=self.config.spec_validator_cls,
447447
extra_format_validators=self.config.extra_format_validators,
448448
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
449-
strict_additional_properties=self.config.strict_additional_properties,
449+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
450450
enforce_properties_required=self.config.response_properties_default_policy
451451
== "required",
452452
)
@@ -466,7 +466,7 @@ def webhook_request_validator(self) -> WebhookRequestValidator:
466466
spec_validator_cls=self.config.spec_validator_cls,
467467
extra_format_validators=self.config.extra_format_validators,
468468
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
469-
strict_additional_properties=self.config.strict_additional_properties,
469+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
470470
security_provider_factory=self.config.security_provider_factory,
471471
)
472472

@@ -485,7 +485,7 @@ def webhook_response_validator(self) -> WebhookResponseValidator:
485485
spec_validator_cls=self.config.spec_validator_cls,
486486
extra_format_validators=self.config.extra_format_validators,
487487
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
488-
strict_additional_properties=self.config.strict_additional_properties,
488+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
489489
enforce_properties_required=self.config.response_properties_default_policy
490490
== "required",
491491
)
@@ -505,7 +505,7 @@ def request_unmarshaller(self) -> RequestUnmarshaller:
505505
spec_validator_cls=self.config.spec_validator_cls,
506506
extra_format_validators=self.config.extra_format_validators,
507507
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
508-
strict_additional_properties=self.config.strict_additional_properties,
508+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
509509
security_provider_factory=self.config.security_provider_factory,
510510
schema_unmarshallers_factory=self.config.schema_unmarshallers_factory,
511511
extra_format_unmarshallers=self.config.extra_format_unmarshallers,
@@ -526,7 +526,7 @@ def response_unmarshaller(self) -> ResponseUnmarshaller:
526526
spec_validator_cls=self.config.spec_validator_cls,
527527
extra_format_validators=self.config.extra_format_validators,
528528
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
529-
strict_additional_properties=self.config.strict_additional_properties,
529+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
530530
enforce_properties_required=self.config.response_properties_default_policy
531531
== "required",
532532
schema_unmarshallers_factory=self.config.schema_unmarshallers_factory,
@@ -548,7 +548,7 @@ def webhook_request_unmarshaller(self) -> WebhookRequestUnmarshaller:
548548
spec_validator_cls=self.config.spec_validator_cls,
549549
extra_format_validators=self.config.extra_format_validators,
550550
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
551-
strict_additional_properties=self.config.strict_additional_properties,
551+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
552552
security_provider_factory=self.config.security_provider_factory,
553553
schema_unmarshallers_factory=self.config.schema_unmarshallers_factory,
554554
extra_format_unmarshallers=self.config.extra_format_unmarshallers,
@@ -569,7 +569,7 @@ def webhook_response_unmarshaller(self) -> WebhookResponseUnmarshaller:
569569
spec_validator_cls=self.config.spec_validator_cls,
570570
extra_format_validators=self.config.extra_format_validators,
571571
extra_media_type_deserializers=self.config.extra_media_type_deserializers,
572-
strict_additional_properties=self.config.strict_additional_properties,
572+
forbid_unspecified_additional_properties=self.config.additional_properties_default_policy == "forbid",
573573
enforce_properties_required=self.config.response_properties_default_policy
574574
== "required",
575575
schema_unmarshallers_factory=self.config.schema_unmarshallers_factory,

openapi_core/unmarshalling/request/protocols.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def __init__(
5555
MediaTypeDeserializersDict
5656
] = None,
5757
security_provider_factory: SecurityProviderFactory = security_provider_factory,
58-
strict_additional_properties: bool = False,
58+
forbid_unspecified_additional_properties: bool = False,
5959
schema_unmarshallers_factory: Optional[
6060
SchemaUnmarshallersFactory
6161
] = None,
@@ -91,7 +91,7 @@ def __init__(
9191
MediaTypeDeserializersDict
9292
] = None,
9393
security_provider_factory: SecurityProviderFactory = security_provider_factory,
94-
strict_additional_properties: bool = False,
94+
forbid_unspecified_additional_properties: bool = False,
9595
schema_unmarshallers_factory: Optional[
9696
SchemaUnmarshallersFactory
9797
] = None,

openapi_core/unmarshalling/request/unmarshallers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def __init__(
120120
MediaTypeDeserializersDict
121121
] = None,
122122
security_provider_factory: SecurityProviderFactory = security_provider_factory,
123-
strict_additional_properties: bool = False,
123+
forbid_unspecified_additional_properties: bool = False,
124124
schema_unmarshallers_factory: Optional[
125125
SchemaUnmarshallersFactory
126126
] = None,
@@ -140,7 +140,7 @@ def __init__(
140140
format_validators=format_validators,
141141
extra_format_validators=extra_format_validators,
142142
extra_media_type_deserializers=extra_media_type_deserializers,
143-
strict_additional_properties=strict_additional_properties,
143+
forbid_unspecified_additional_properties=forbid_unspecified_additional_properties,
144144
schema_unmarshallers_factory=schema_unmarshallers_factory,
145145
format_unmarshallers=format_unmarshallers,
146146
extra_format_unmarshallers=extra_format_unmarshallers,
@@ -159,7 +159,7 @@ def __init__(
159159
extra_format_validators=extra_format_validators,
160160
extra_media_type_deserializers=extra_media_type_deserializers,
161161
security_provider_factory=security_provider_factory,
162-
strict_additional_properties=strict_additional_properties,
162+
forbid_unspecified_additional_properties=forbid_unspecified_additional_properties,
163163
)
164164

165165
def _unmarshal(

openapi_core/unmarshalling/response/protocols.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def __init__(
5555
extra_media_type_deserializers: Optional[
5656
MediaTypeDeserializersDict
5757
] = None,
58-
strict_additional_properties: bool = False,
58+
forbid_unspecified_additional_properties: bool = False,
5959
enforce_properties_required: bool = False,
6060
schema_unmarshallers_factory: Optional[
6161
SchemaUnmarshallersFactory
@@ -92,7 +92,7 @@ def __init__(
9292
extra_media_type_deserializers: Optional[
9393
MediaTypeDeserializersDict
9494
] = None,
95-
strict_additional_properties: bool = False,
95+
forbid_unspecified_additional_properties: bool = False,
9696
enforce_properties_required: bool = False,
9797
schema_unmarshallers_factory: Optional[
9898
SchemaUnmarshallersFactory

openapi_core/unmarshalling/schemas/factories.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def create(
3838
format_unmarshallers: Optional[FormatUnmarshallersDict] = None,
3939
extra_format_validators: Optional[FormatValidatorsDict] = None,
4040
extra_format_unmarshallers: Optional[FormatUnmarshallersDict] = None,
41-
strict_additional_properties: bool = False,
41+
forbid_unspecified_additional_properties: bool = False,
4242
enforce_properties_required: bool = False,
4343
) -> SchemaUnmarshaller:
4444
"""Create unmarshaller from the schema."""
@@ -54,7 +54,7 @@ def create(
5454
schema,
5555
format_validators=format_validators,
5656
extra_format_validators=extra_format_validators,
57-
strict_additional_properties=strict_additional_properties,
57+
forbid_unspecified_additional_properties=forbid_unspecified_additional_properties,
5858
enforce_properties_required=enforce_properties_required,
5959
)
6060

openapi_core/unmarshalling/unmarshallers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def __init__(
5050
extra_media_type_deserializers: Optional[
5151
MediaTypeDeserializersDict
5252
] = None,
53-
strict_additional_properties: bool = False,
53+
forbid_unspecified_additional_properties: bool = False,
5454
enforce_properties_required: bool = False,
5555
schema_unmarshallers_factory: Optional[
5656
SchemaUnmarshallersFactory
@@ -75,7 +75,7 @@ def __init__(
7575
format_validators=format_validators,
7676
extra_format_validators=extra_format_validators,
7777
extra_media_type_deserializers=extra_media_type_deserializers,
78-
strict_additional_properties=strict_additional_properties,
78+
forbid_unspecified_additional_properties=forbid_unspecified_additional_properties,
7979
enforce_properties_required=enforce_properties_required,
8080
)
8181
self.schema_unmarshallers_factory = (
@@ -93,7 +93,7 @@ def _unmarshal_schema(self, schema: SchemaPath, value: Any) -> Any:
9393
schema,
9494
format_validators=self.format_validators,
9595
extra_format_validators=self.extra_format_validators,
96-
strict_additional_properties=self.strict_additional_properties,
96+
forbid_unspecified_additional_properties=self.forbid_unspecified_additional_properties,
9797
enforce_properties_required=self.enforce_properties_required,
9898
format_unmarshallers=self.format_unmarshallers,
9999
extra_format_unmarshallers=self.extra_format_unmarshallers,

openapi_core/validation/configurations.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class ValidatorConfig:
4444
Extra media type deserializers.
4545
security_provider_factory
4646
Security providers factory.
47-
strict_additional_properties
48-
If true, treat schemas that omit additionalProperties as if
47+
additional_properties_default_policy
48+
If forbid, treat schemas that omit additionalProperties as if
4949
additionalProperties: false.
5050
response_properties_default_policy
5151
If true, response schema properties are treated as required during
@@ -70,7 +70,7 @@ class ValidatorConfig:
7070
security_provider_factory: SecurityProviderFactory = (
7171
security_provider_factory
7272
)
73-
strict_additional_properties: bool = False
73+
additional_properties_default_policy: Literal["allow", "forbid"] = "allow"
7474
response_properties_default_policy: Literal["optional", "required"] = (
7575
"optional"
7676
)

openapi_core/validation/request/protocols.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def __init__(
4949
MediaTypeDeserializersDict
5050
] = None,
5151
security_provider_factory: SecurityProviderFactory = security_provider_factory,
52-
strict_additional_properties: bool = False,
52+
forbid_unspecified_additional_properties: bool = False,
5353
): ...
5454

5555
def iter_errors(
@@ -85,7 +85,7 @@ def __init__(
8585
MediaTypeDeserializersDict
8686
] = None,
8787
security_provider_factory: SecurityProviderFactory = security_provider_factory,
88-
strict_additional_properties: bool = False,
88+
forbid_unspecified_additional_properties: bool = False,
8989
): ...
9090

9191
def iter_errors(

openapi_core/validation/request/validators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def __init__(
8585
MediaTypeDeserializersDict
8686
] = None,
8787
security_provider_factory: SecurityProviderFactory = security_provider_factory,
88-
strict_additional_properties: bool = False,
88+
forbid_unspecified_additional_properties: bool = False,
8989
):
9090

9191
BaseValidator.__init__(
@@ -101,7 +101,7 @@ def __init__(
101101
format_validators=format_validators,
102102
extra_format_validators=extra_format_validators,
103103
extra_media_type_deserializers=extra_media_type_deserializers,
104-
strict_additional_properties=strict_additional_properties,
104+
forbid_unspecified_additional_properties=forbid_unspecified_additional_properties,
105105
)
106106
self.security_provider_factory = security_provider_factory
107107

0 commit comments

Comments
 (0)