Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: Michael Banck <mba...@debian.org>
Please unblock package pydantic pydantic (1.7.4-1) unstable; urgency=medium * Team upload. * New upstream point release. - Fixes CVE-2021-29510: Date and datetime parsing could cause an infinite loop by passing either 'infinity' or float('inf') (Closes: #988480) * Update watch file to version 4 with current uscan(1) recommended regex. -- Stefano Rivera <stefa...@debian.org> Fri, 21 May 2021 16:05:17 -0400 [ Reason ] New upstream point release, with (only) a security fix (DoS). [ Impact ] Without this patch, pydantic can be DoSed with "infinity" as a timestamp. [ Tests ] Upstream unit test suite runs during the package build. There are unit tests for the changes in this release. [ Risks ] Upstream maintains support branches, and provided this point release. So we're not relying on any untested patches. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing unblock pydantic/1.7.4-1
diff -Nru pydantic-1.7.3/debian/changelog pydantic-1.7.4/debian/changelog --- pydantic-1.7.3/debian/changelog 2021-01-08 03:31:43.000000000 -0400 +++ pydantic-1.7.4/debian/changelog 2021-05-21 16:05:17.000000000 -0400 @@ -1,3 +1,13 @@ +pydantic (1.7.4-1) unstable; urgency=medium + + * Team upload. + * New upstream point release. + - Fixes CVE-2021-29510: Date and datetime parsing could cause an infinite + loop by passing either 'infinity' or float('inf') (Closes: #988480) + * Update watch file to version 4 with current uscan(1) recommended regex. + + -- Stefano Rivera <stefa...@debian.org> Fri, 21 May 2021 16:05:17 -0400 + pydantic (1.7.3-1) unstable; urgency=medium [ Sandro Tosi ] diff -Nru pydantic-1.7.3/debian/watch pydantic-1.7.4/debian/watch --- pydantic-1.7.3/debian/watch 2021-01-08 03:31:43.000000000 -0400 +++ pydantic-1.7.4/debian/watch 2021-05-21 16:05:17.000000000 -0400 @@ -1,2 +1,4 @@ -version=3 -https://github.com/samuelcolvin/pydantic/releases .*/archive/v([\d.]+)\.tar\.gz +version=4 +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \ + https://github.com/samuelcolvin/pydantic/releases \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz diff -Nru pydantic-1.7.3/.github/workflows/ci.yml pydantic-1.7.4/.github/workflows/ci.yml --- pydantic-1.7.3/.github/workflows/ci.yml 2020-11-30 19:33:24.000000000 -0400 +++ pydantic-1.7.4/.github/workflows/ci.yml 2021-05-11 15:04:58.000000000 -0400 @@ -80,20 +80,20 @@ COMPILED: yes DEPS: yes - - name: uninstall deps - run: pip uninstall -y cython email-validator typing-extensions devtools python-dotenv - - - name: test compiled without deps - run: make test - - - run: coverage xml - - uses: codecov/codecov-action@v1.0.14 - with: - file: ./coverage.xml - env_vars: COMPILED,DEPS,PYTHON,OS - env: - COMPILED: yes - DEPS: no +# - name: uninstall deps +# run: pip uninstall -y cython email-validator typing-extensions devtools python-dotenv +# +# - name: test compiled without deps +# run: make test +# +# - run: coverage xml +# - uses: codecov/codecov-action@v1.0.14 +# with: +# file: ./coverage.xml +# env_vars: COMPILED,DEPS,PYTHON,OS +# env: +# COMPILED: yes +# DEPS: no - name: remove compiled binaries run: | @@ -159,11 +159,12 @@ with: python-version: '3.7' - - name: install - run: make install-testing - - - name: test - run: make test-fastapi + - run: echo "skip fastapi for now" +# - name: install +# run: make install-testing +# +# - name: test +# run: make test-fastapi benchmark: name: run benchmarks diff -Nru pydantic-1.7.3/HISTORY.md pydantic-1.7.4/HISTORY.md --- pydantic-1.7.3/HISTORY.md 2020-11-30 19:33:24.000000000 -0400 +++ pydantic-1.7.4/HISTORY.md 2021-05-11 15:04:58.000000000 -0400 @@ -1,3 +1,9 @@ +## v1.7.4 (2021-05-11) + +* **Security fix:** Fix `date` and `datetime` parsing so passing either `'infinity'` or `float('inf')` + (or their negative values) does not cause an infinite loop, + See security advisory [CVE-2021-29510](https://github.com/samuelcolvin/pydantic/security/advisories/GHSA-5jqp-qgf6-3pvh) + ## v1.7.3 (2020-11-30) Thank you to pydantic's sponsors: diff -Nru pydantic-1.7.3/pydantic/datetime_parse.py pydantic-1.7.4/pydantic/datetime_parse.py --- pydantic-1.7.3/pydantic/datetime_parse.py 2020-11-30 19:33:24.000000000 -0400 +++ pydantic-1.7.4/pydantic/datetime_parse.py 2021-05-11 15:04:58.000000000 -0400 @@ -58,6 +58,8 @@ # if greater than this, the number is in ms, if less than or equal it's in seconds # (in seconds this is 11th October 2603, in ms it's 20th August 1970) MS_WATERSHED = int(2e10) +# slightly more than datetime.max in ns - (datetime.max - EPOCH).total_seconds() * 1e9 +MAX_NUMBER = int(3e20) StrBytesIntFloat = Union[str, bytes, int, float] @@ -73,6 +75,11 @@ def from_unix_seconds(seconds: Union[int, float]) -> datetime: + if seconds > MAX_NUMBER: + return datetime.max + elif seconds < -MAX_NUMBER: + return datetime.min + while abs(seconds) > MS_WATERSHED: seconds /= 1000 dt = EPOCH + timedelta(seconds=seconds) diff -Nru pydantic-1.7.3/pydantic/version.py pydantic-1.7.4/pydantic/version.py --- pydantic-1.7.3/pydantic/version.py 2020-11-30 19:33:24.000000000 -0400 +++ pydantic-1.7.4/pydantic/version.py 2021-05-11 15:04:58.000000000 -0400 @@ -1,6 +1,6 @@ __all__ = 'VERSION', 'version_info' -VERSION = '1.7.3' +VERSION = '1.7.4' def version_info() -> str: diff -Nru pydantic-1.7.3/tests/test_datetime_parse.py pydantic-1.7.4/tests/test_datetime_parse.py --- pydantic-1.7.3/tests/test_datetime_parse.py 2020-11-30 19:33:24.000000000 -0400 +++ pydantic-1.7.4/tests/test_datetime_parse.py 2021-05-11 15:04:58.000000000 -0400 @@ -42,11 +42,20 @@ (1_549_316_052_104, date(2019, 2, 4)), # nowish in ms (1_549_316_052_104_324, date(2019, 2, 4)), # nowish in μs (1_549_316_052_104_324_096, date(2019, 2, 4)), # nowish in ns + ('infinity', date(9999, 12, 31)), + ('inf', date(9999, 12, 31)), + (float('inf'), date(9999, 12, 31)), + ('infinity ', date(9999, 12, 31)), + (int('1' + '0' * 100), date(9999, 12, 31)), + (1e1000, date(9999, 12, 31)), + ('-infinity', date(1, 1, 1)), + ('-inf', date(1, 1, 1)), + ('nan', ValueError), ], ) def test_date_parsing(value, result): - if result == errors.DateError: - with pytest.raises(errors.DateError): + if type(result) == type and issubclass(result, Exception): + with pytest.raises(result): parse_date(value) else: assert parse_date(value) == result @@ -123,11 +132,19 @@ (1_549_316_052_104, datetime(2019, 2, 4, 21, 34, 12, 104_000, tzinfo=timezone.utc)), # nowish in ms (1_549_316_052_104_324, datetime(2019, 2, 4, 21, 34, 12, 104_324, tzinfo=timezone.utc)), # nowish in μs (1_549_316_052_104_324_096, datetime(2019, 2, 4, 21, 34, 12, 104_324, tzinfo=timezone.utc)), # nowish in ns + ('infinity', datetime(9999, 12, 31, 23, 59, 59, 999999)), + ('inf', datetime(9999, 12, 31, 23, 59, 59, 999999)), + ('inf ', datetime(9999, 12, 31, 23, 59, 59, 999999)), + (1e50, datetime(9999, 12, 31, 23, 59, 59, 999999)), + (float('inf'), datetime(9999, 12, 31, 23, 59, 59, 999999)), + ('-infinity', datetime(1, 1, 1, 0, 0)), + ('-inf', datetime(1, 1, 1, 0, 0)), + ('nan', ValueError), ], ) def test_datetime_parsing(value, result): - if result == errors.DateTimeError: - with pytest.raises(errors.DateTimeError): + if type(result) == type and issubclass(result, Exception): + with pytest.raises(result): parse_datetime(value) else: assert parse_datetime(value) == result @@ -251,3 +268,24 @@ 'type': 'value_error.unicodedecode', 'msg': "'utf-8' codec can't decode byte 0x81 in position 0: invalid start byte", } + + +def test_nan(): + class Model(BaseModel): + dt: datetime + d: date + + with pytest.raises(ValidationError) as exc_info: + Model(dt='nan', d='nan') + assert exc_info.value.errors() == [ + { + 'loc': ('dt',), + 'msg': 'cannot convert float NaN to integer', + 'type': 'value_error', + }, + { + 'loc': ('d',), + 'msg': 'cannot convert float NaN to integer', + 'type': 'value_error', + }, + ]