You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Limiting the maximum number of tags on Tag.parse_tag() #1220
Would it be worth adding a limit to the maximum number of tags parsed in Tag.parse_tag()?. It builds the cartesian product of compressed tag components:
The spec does warn about it, but doesn't actually specify a limit for them
This compression scheme can generate large numbers of unsupported tags and “impossible” tags that are supported by no Python implementation e.g. “cp33-cp31u-win64”, so use it sparingly.
Are you worried about some attack that will exhaust memory?
Not realistically, if we assume we're parsing a maliciously crafted wheel, it'd be limited by the filesystem limits on filename length (usually 255 bytes). You could craft a filename such that it expands to about ~40k tags:
I opened the issue to ask if it makes sense to limit it more from the "there's no good reason to allow it" side than the "this is definitely exploitable" side.
Mm thinking about it further, it could be that parse_tag() is called with a tag extracted from a string that does not correspond to an actual file in a filesystem (like the URL for a wheel inside a requirements.txt file). So in that case there's no upper limit for the length of the filename.
Ultimately this isn't an issue for packaging, it's callers of packaging processing untrusted data. They would be best processing such data in some kind of time limited and memory limited sandbox.
To help such users out I think we should add a key word only argument like "maximum_tags”, with either a default of None (unbounded) or some sufficiently large number that is likely to meet all realistic use cases.
To help such users out I think we should add a key word only argument like "maximum_tags”, with either a default of None (unbounded) or some sufficiently large number that is likely to meet all realistic use cases.
I was thinking of something similar: a limit keyword-only argument that defaults to None and if set would raise an exception if the limit is hit before completing.
I know I'm commenting on an already closed issue, but I think a reasonable limit here might protect many application that uses this. For example pip calls parse_wheel_filename in their Wheel.__init__ and there is currently no way to use this limit for protection. And as @facutuesca pointed out, we are not limited to what filesystems allow us because a crafted requirements.txt file might cause pip to consume hundreds of MBs of memory even before it tries to touch an actual file.
Activity
[-]Limiting the maximum tags on `Tag.parse_tag()`[/-][+]Limiting the maximum number of tags on `Tag.parse_tag()`[/+]brettcannon commentedon Jun 3, 2026
Are you worried about some attack that will exhaust memory?
facutuesca commentedon Jun 3, 2026
Not realistically, if we assume we're parsing a maliciously crafted wheel, it'd be limited by the filesystem limits on filename length (usually 255 bytes). You could craft a filename such that it expands to about ~40k tags:
which shouldn't be huge memory-wise.
I opened the issue to ask if it makes sense to limit it more from the "there's no good reason to allow it" side than the "this is definitely exploitable" side.
facutuesca commentedon Jun 3, 2026
Mm thinking about it further, it could be that
parse_tag()is called with a tag extracted from a string that does not correspond to an actual file in a filesystem (like the URL for a wheel inside arequirements.txtfile). So in that case there's no upper limit for the length of the filename.notatallshaw commentedon Jun 3, 2026
Ultimately this isn't an issue for packaging, it's callers of packaging processing untrusted data. They would be best processing such data in some kind of time limited and memory limited sandbox.
To help such users out I think we should add a key word only argument like "maximum_tags”, with either a default of
None(unbounded) or some sufficiently large number that is likely to meet all realistic use cases.brettcannon commentedon Jun 4, 2026
I was thinking of something similar: a
limitkeyword-only argument that defaults toNoneand if set would raise an exception if the limit is hit before completing.facutuesca commentedon Jun 4, 2026
Makes sense to me, I created a PR for it here: #1224
notatallshaw commentedon Jun 11, 2026
Do we call parse_tag under the hood in any of our other objects or helper utilities?
It may change how we need to expose the limit option.
frenzymadness commentedon Jul 28, 2026
I know I'm commenting on an already closed issue, but I think a reasonable limit here might protect many application that uses this. For example pip calls
parse_wheel_filenamein theirWheel.__init__and there is currently no way to use this limit for protection. And as @facutuesca pointed out, we are not limited to what filesystems allow us because a crafted requirements.txt file might cause pip to consume hundreds of MBs of memory even before it tries to touch an actual file.