VYPR
High severity7.5NVD Advisory· Published Jul 23, 2024· Updated Apr 15, 2026

CVE-2024-41655

CVE-2024-41655

Description

TF2 Item Format helps users format TF2 items to the community standards. Versions of tf2-item-format since at least 4.2.6 and prior to 5.9.14 are vulnerable to a Regular Expression Denial of Service (ReDoS) attack when parsing crafted user input. This vulnerability can be exploited by an attacker to perform DoS attacks on any service that uses any tf2-item-format to parse user input. Version 5.9.14 contains a fix for the issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
tf2-item-formatnpm
>= 4.2.6, < 5.9.145.9.14

Patches

2
5cffcc16a926

Merge pull request #371 from danocmx/fix/regex

10 files changed · +44 19
  • src/parseEconItem/ParsedEcon/getDescriptions/paint.ts+1 1 modified
    @@ -5,7 +5,7 @@ import { EconDescription } from '../../../types';
      */
     export function isPaint(description: EconDescription): boolean {
     	return (
    -		/^Paint Color: /.test(description.value) &&
    +		description.value.startsWith('Paint Color: ') &&
     		description.color === '756b5e'
     	);
     }
    
  • src/parseEconItem/ParsedEcon/getDescriptions/spell.ts+1 1 modified
    @@ -7,7 +7,7 @@ import { EconDescription } from '../../../types';
      */
     export function isSpell(description: EconDescription): boolean {
     	return (
    -		/^Halloween: .*/.test(description.value) &&
    +		description.value.startsWith('Halloween: ') &&
     		description.color === '7ea9d1'
     	);
     }
    
  • src/parseString/Attributes/getQuality/isHaunted.ts+12 3 modified
    @@ -6,8 +6,17 @@ export default function (name: string): boolean {
     	);
     }
     
    +const HAUNTED_EXCEPTIONS = [
    +	'Haunted Hat',
    +	'Haunted Ghosts',
    +	'Haunted Phantasm',
    +	'Haunted Metal Scrap',
    +	'Haunted Kraken',
    +	'Haunted Forever',
    +	'Haunted Wick',
    +	'Haunted Cremation',
    +];
    +
     function isHauntedException(name: string): boolean {
    -	return /(Haunted Hat)|(Haunted Ghosts)|(Haunted Phantasm)|(Haunted Metal Scrap)|(Haunted Kraken)|(Haunted Forever)|(Haunted Wick)|(Haunted Cremation)/.test(
    -		name
    -	);
    +	return HAUNTED_EXCEPTIONS.some((exception) => name.includes(exception));
     }
    
  • src/parseString/Attributes/getQuality/isStrange.ts+9 3 modified
    @@ -2,8 +2,14 @@ export default function (name: string): boolean {
     	return name.includes('Strange ') && !isStrangeException(name);
     }
     
    +const STRANGE_EXCEPTIONS = [
    +	'Strange Bacon Grease',
    +	'Strange Filter: ',
    +	'Strange Count Transfer Tool',
    +	'Strange Part: ',
    +	'Strange Cosmetic Part: ',
    +];
    +
     function isStrangeException(name: string): boolean {
    -	return /(Strange Bacon Grease|Strange Filter: |Strange Count Transfer Tool|Strange Part: |Strange Cosmetic Part: )/.test(
    -		name
    -	);
    +	return STRANGE_EXCEPTIONS.some((exception) => name.includes(exception));
     }
    
  • src/parseString/Attributes/getQuality/isVintage.ts+6 1 modified
    @@ -6,6 +6,11 @@ export default function (name: string): boolean {
     	);
     }
     
    +const VINTAGE_EXCEPTIONS = [
    +	'Vintage Merryweather',
    +	'Vintage Tyrolean',
    +];
    +
     function isVintageException(name: string): boolean {
    -	return /Vintage (Merryweather|Tyrolean)/.test(name);
    +	return VINTAGE_EXCEPTIONS.some((exception) => name.includes(exception));
     }
    
  • src/parseString/Attributes/getQuality/matchQuality.ts+1 1 modified
    @@ -4,7 +4,7 @@
      * @return {string} quality
      */
     export default function (name: string): string {
    -	// Does not include strangee and vintage for exception reasons.
    +	// Does not include strange and vintage for exception reasons.
     	const match =
     		name.match(/(Normal|Genuine|Unique|Unusual|Self-Made|Collector's) /) ||
     		[];
    
  • src/parseString/Attributes/getUsableItem.ts+9 3 modified
    @@ -48,17 +48,23 @@ export default function (name: string): Partial<TargetOutputItem> | null {
     }
     
     function isStrangifierChemistrySet(name: string): boolean {
    -	return / Strangifier Chemistry Set/.test(name);
    +	return name.includes(' Strangifier Chemistry Set');
     }
     
    +const TARGET_EXCEPTIONS = [
    +	"Killer's Kit",
    +	"Coffin Kit",
    +	"Summer Starter Kit"
    +];
    +
     function getItemIfTarget(name: string): string | void {
    -	if (/(Killer's Kit|Coffin Kit|Summer Starter Kit)/.test(name)) return;
    +	if (TARGET_EXCEPTIONS.some((exception) => name.includes(exception))) return;
     
     	// eslint-disable-next-line consistent-return
     	return (name.match(/ (Kit Fabricator|Kit|Strangifier|Unusualifier)/) ||
     		[])[1];
     }
     
     function isChemistrySet(name: string): boolean {
    -	return / Chemistry Set/.test(name);
    +	return name.includes(' Chemistry Set') ;
     }
    
  • src/shared/decomposeName.ts+3 4 modified
    @@ -51,10 +51,9 @@ export default function (
     		} else {
     			const toRemove = getUsableItemToRemove(attributes);
     
    -			itemName = itemName.replace(
    -				new RegExp(`(( ${toRemove})|(${toRemove} ))`),
    -				''
    -			);
    +			itemName = itemName
    +				.replace(` ${toRemove}`, '')
    +				.replace(`${toRemove} `, '');
     		}
     	} else if (killstreak) itemName = itemName.replace(`${killstreak} `, ''); // Killstreak stat is kept
     
    
  • src/shared/isUniqueHat.ts+1 1 modified
    @@ -46,7 +46,7 @@ const EXCEPTIONS = [
      * Only happens to hats with unique quality.
      */
     export default function (name: string, attributes?: Attributes): boolean {
    -	if (!/^The /.test(name)) {
    +	if (!name.startsWith('The ')) {
     		return false;
     	}
     
    
  • src/stringify.ts+1 1 modified
    @@ -189,7 +189,7 @@ function canAddKillstreak(
     }
     
     function isKillstreakKitOrFabricator(name: string, target?: string): boolean {
    -	return !!(target && (/ Kit/.test(name) || / Fabricator/.test(name))); // This checks for fabricator too.
    +	return !!(target && (name.includes(' Kit') || name.includes(' Fabricator'))); // This checks for fabricator too.
     }
     
     function isUniqueHat(
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.