@@ -45,7 +45,9 @@ function ChartContainer({
4545 > [ "children" ]
4646} ) {
4747 const uniqueId = useId ( )
48- const chartId = `chart-${ id || uniqueId . replace ( / : / g, "" ) } `
48+ // Sanitize ID to prevent XSS - only allow alphanumeric, hyphens, and underscores
49+ const baseId = ( id || uniqueId ) . replace ( / [ ^ a - z A - Z 0 - 9 - _ ] / g, '' )
50+ const chartId = `chart-${ baseId } `
4951
5052 return (
5153 < ChartContext . Provider value = { { config } } >
@@ -76,19 +78,26 @@ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
7678 return null
7779 }
7880
81+ // Sanitize id to prevent CSS injection - only allow alphanumeric, hyphens, and underscores
82+ const sanitizedId = id . replace ( / [ ^ a - z A - Z 0 - 9 - _ ] / g, '' )
83+
7984 return (
8085 < style
8186 dangerouslySetInnerHTML = { {
8287 __html : Object . entries ( THEMES )
8388 . map (
8489 ( [ theme , prefix ] ) => `
85- ${ prefix } [data-chart=${ id } ] {
90+ ${ prefix } [data-chart=${ sanitizedId } ] {
8691${ colorConfig
8792 . map ( ( [ key , itemConfig ] ) => {
93+ // Sanitize key to prevent CSS injection
94+ const sanitizedKey = key . replace ( / [ ^ a - z A - Z 0 - 9 - _ ] / g, '' )
8895 const color =
8996 itemConfig . theme ?. [ theme as keyof typeof itemConfig . theme ] ||
9097 itemConfig . color
91- return color ? ` --color-${ key } : ${ color } ;` : null
98+ // Sanitize color value to prevent CSS injection
99+ const sanitizedColor = color ?. replace ( / [ < > ' " ] / g, '' )
100+ return sanitizedColor ? ` --color-${ sanitizedKey } : ${ sanitizedColor } ;` : null
92101 } )
93102 . join ( "\n" ) }
94103}
0 commit comments