@@ -201,6 +201,17 @@ <h5>Time Series Analysis</h5>
201201 let neighborFeatures = [ ] ;
202202 let timeSeriesChart = null ;
203203
204+ // Security: Escape HTML to prevent XSS attacks
205+ function escapeHtml ( unsafe ) {
206+ if ( unsafe == null || unsafe === undefined ) return '' ;
207+ return String ( unsafe )
208+ . replace ( / & / g, "&" )
209+ . replace ( / < / g, "<" )
210+ . replace ( / > / g, ">" )
211+ . replace ( / " / g, """ )
212+ . replace ( / ' / g, "'" ) ;
213+ }
214+
204215 // Atualizar as cores das classificações conforme o gabarito fornecido
205216 const classificationColors = {
206217 'no pattern detected' : 'lightgray' ,
@@ -526,8 +537,8 @@ <h5>Time Series Analysis</h5>
526537
527538 layer . bindTooltip ( `
528539 <div class="tooltip-custom">
529- <h6>Region: ${ regionId } </h6>
530- <p>Classification: ${ classification } </p>
540+ <h6>Region: ${ escapeHtml ( regionId ) } </h6>
541+ <p>Classification: ${ escapeHtml ( classification ) } </p>
531542 </div>
532543 ` , {
533544 sticky : true ,
@@ -659,11 +670,11 @@ <h6>Region: ${regionId}</h6>
659670 // Build an HTML table
660671 let cols = Object . keys ( parsedData [ 0 ] ) ;
661672 let html = '<div style="overflow-x:auto;"><table border="1" cellpadding="4" cellspacing="0" style="border-collapse:collapse;font-size:12px;width:100%"><thead><tr>' ;
662- cols . forEach ( col => { html += `<th>${ col } </th>` ; } ) ;
673+ cols . forEach ( col => { html += `<th>${ escapeHtml ( col ) } </th>` ; } ) ;
663674 html += '</tr></thead><tbody>' ;
664675 parsedData . forEach ( row => {
665676 html += '<tr>' ;
666- cols . forEach ( col => { html += `<td>${ row [ col ] !== null && row [ col ] !== undefined ? row [ col ] : '' } </td>` ; } ) ;
677+ cols . forEach ( col => { html += `<td>${ escapeHtml ( row [ col ] !== null && row [ col ] !== undefined ? row [ col ] : '' ) } </td>` ; } ) ;
667678 html += '</tr>' ;
668679 } ) ;
669680 html += '</tbody></table></div>' ;
@@ -682,7 +693,7 @@ <h6>Region: ${regionId}</h6>
682693 } else if ( typeof data === 'object' && data !== null ) {
683694 html += '<ul style="margin:0 0 0 1em;padding:0">' ;
684695 for ( const k in data ) {
685- html += `<li>${ pad } <strong>${ k } :</strong> ${ prettyPrintData ( data [ k ] , indent + 1 , k ) } </li>` ;
696+ html += `<li>${ pad } <strong>${ escapeHtml ( k ) } :</strong> ${ prettyPrintData ( data [ k ] , indent + 1 , k ) } </li>` ;
686697 }
687698 html += '</ul>' ;
688699 } else {
@@ -691,7 +702,7 @@ <h6>Region: ${regionId}</h6>
691702 if ( typeof parsedData === 'object' && parsedData !== null ) {
692703 return prettyPrintData ( parsedData , indent + 1 ) ;
693704 }
694- html += pad + String ( data ) ;
705+ html += pad + escapeHtml ( String ( data ) ) ;
695706 }
696707 return html ;
697708 }
@@ -703,10 +714,10 @@ <h6>Region: ${regionId}</h6>
703714 const classification = feature . properties . classification ;
704715
705716 let html = `
706- <h6>Region: ${ regionId } </h6>
707- <p><strong>Classification:</strong> ${ classification } </p>
708- <p><strong>Mann-Kendall Tau:</strong> ${ feature . properties . tau } </p>
709- <p><strong>p-value:</strong> ${ feature . properties . p_value } </p>
717+ <h6>Region: ${ escapeHtml ( regionId ) } </h6>
718+ <p><strong>Classification:</strong> ${ escapeHtml ( classification ) } </p>
719+ <p><strong>Mann-Kendall Tau:</strong> ${ escapeHtml ( feature . properties . tau ) } </p>
720+ <p><strong>p-value:</strong> ${ escapeHtml ( feature . properties . p_value ) } </p>
710721 ` ;
711722
712723 // Show all details recursively
@@ -996,7 +1007,7 @@ <h6>Region: ${regionId}</h6>
9961007 plugins : {
9971008 title : {
9981009 display : true ,
999- text : `Time Series for Region: ${ getRegionId ( feature . properties ) } `
1010+ text : `Time Series for Region: ${ escapeHtml ( getRegionId ( feature . properties ) ) } `
10001011 } ,
10011012 tooltip : {
10021013 callbacks : {
@@ -1030,11 +1041,11 @@ <h6>Region: ${regionId}</h6>
10301041 const tau = feature . properties . tau ;
10311042 const pValue = feature . properties . p_value ;
10321043 timeSeriesInfo . innerHTML = `
1033- <h5>Time Series Analysis for Region: ${ getRegionId ( feature . properties ) } </h5>
1034- <p><strong>Classification:</strong> ${ classification } </p>
1035- <p><strong>Mann-Kendall Tau:</strong> ${ tau } (p-value: ${ pValue } )</p>
1036- <p><strong>Number of Time Periods:</strong> ${ data . length } </p>
1037- <p><strong>Significant Periods:</strong> ${ data . filter ( d => d . is_significant ) . length } </p>
1044+ <h5>Time Series Analysis for Region: ${ escapeHtml ( getRegionId ( feature . properties ) ) } </h5>
1045+ <p><strong>Classification:</strong> ${ escapeHtml ( classification ) } </p>
1046+ <p><strong>Mann-Kendall Tau:</strong> ${ escapeHtml ( tau ) } (p-value: ${ escapeHtml ( pValue ) } )</p>
1047+ <p><strong>Number of Time Periods:</strong> ${ escapeHtml ( data . length ) } </p>
1048+ <p><strong>Significant Periods:</strong> ${ escapeHtml ( data . filter ( d => d . is_significant ) . length ) } </p>
10381049 ` ;
10391050 } ) ;
10401051
0 commit comments