Created
March 5, 2024 03:30
-
-
Save mywaiting/8fb5374dbcf5c414950518c4f50180a8 to your computer and use it in GitHub Desktop.
Python GZIP 安全实现,抄袭自 Python 官方 xmlrpc.client 能通过限制解压大小限制 GZIP bomb 的实现
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# THIS FORM python.stdlib xmlrpc.client | |
# this avoid gzip bomb vulnerability | |
try: | |
import gzip | |
except ImportError: | |
gzip = None #python can be built without zlib/gzip support | |
## | |
# Encode a string using the gzip content encoding such as specified by the | |
# Content-Encoding: gzip | |
# in the HTTP header, as described in RFC 1952 | |
# | |
# @param data the unencoded data | |
# @return the encoded data | |
def gzip_encode(data): | |
"""data -> gzip encoded data | |
Encode data using the gzip content encoding as described in RFC 1952 | |
""" | |
if not gzip: | |
raise NotImplementedError | |
f = BytesIO() | |
with gzip.GzipFile(mode="wb", fileobj=f, compresslevel=1) as gzf: | |
gzf.write(data) | |
return f.getvalue() | |
## | |
# Decode a string using the gzip content encoding such as specified by the | |
# Content-Encoding: gzip | |
# in the HTTP header, as described in RFC 1952 | |
# | |
# @param data The encoded data | |
# @keyparam max_decode Maximum bytes to decode (20 MiB default), use negative | |
# values for unlimited decoding | |
# @return the unencoded data | |
# @raises ValueError if data is not correctly coded. | |
# @raises ValueError if max gzipped payload length exceeded | |
def gzip_decode(data, max_decode=20971520): | |
"""gzip encoded data -> unencoded data | |
Decode data using the gzip content encoding as described in RFC 1952 | |
""" | |
if not gzip: | |
raise NotImplementedError | |
with gzip.GzipFile(mode="rb", fileobj=BytesIO(data)) as gzf: | |
try: | |
if max_decode < 0: # no limit | |
decoded = gzf.read() | |
else: | |
decoded = gzf.read(max_decode + 1) | |
except OSError: | |
raise ValueError("invalid data") | |
if max_decode >= 0 and len(decoded) > max_decode: | |
raise ValueError("max gzipped payload length exceeded") | |
return decoded | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment