Ovilia commented on code in PR #148:
URL: https://github.com/apache/echarts-handbook/pull/148#discussion_r2446556071


##########
contents/en/best-practices/security.md:
##########
@@ -0,0 +1,97 @@
+# Security
+
+## Overview
+
+ECharts aims to provide rich and flexible visualization capabilities. Although 
the vast majority of its APIs do not require special security considerations, 
sereval APIs are exceptions. For example, the option `tooltip.formatter` 
accepts a raw HTML string, allowing full control over the component's content 
and layout; the option `title.link` uses the provided URL string directly 
without automatic sanitization. While this flexibility is powerful, security 
risks may arise if the input comes from untrusted sources. These APIs are 
listed below, along with suggestions on how to use these features safely.
+
+Any security issues can be reported to 
[[email protected]](mailto:[email protected]) .
+
+
+## Security Boundaries and Checklist [[[#security_boundaries_and_checklist]]]
+
+ECharts focuses on visualization logic. It assumes that inputs are trusted, 
and does not automatically sanitize them. In fact, ECharts itself can not 
properly sanitize inputs, as there are no universal sanitization rules that 
applies to all use cases. However, ECharts should clearly identify which APIs 
(especially ECharts options) require security-related preprocessing or 
considerations in specific use cases. Given the large number of ECharts 
options, preprocess all inputs in every case would be impractical and 
unnecessary.

Review Comment:
   `applies` -> `apply`



##########
contents/en/best-practices/security.md:
##########
@@ -0,0 +1,97 @@
+# Security
+
+## Overview
+
+ECharts aims to provide rich and flexible visualization capabilities. Although 
the vast majority of its APIs do not require special security considerations, 
sereval APIs are exceptions. For example, the option `tooltip.formatter` 
accepts a raw HTML string, allowing full control over the component's content 
and layout; the option `title.link` uses the provided URL string directly 
without automatic sanitization. While this flexibility is powerful, security 
risks may arise if the input comes from untrusted sources. These APIs are 
listed below, along with suggestions on how to use these features safely.
+
+Any security issues can be reported to 
[[email protected]](mailto:[email protected]) .
+
+
+## Security Boundaries and Checklist [[[#security_boundaries_and_checklist]]]
+
+ECharts focuses on visualization logic. It assumes that inputs are trusted, 
and does not automatically sanitize them. In fact, ECharts itself can not 
properly sanitize inputs, as there are no universal sanitization rules that 
applies to all use cases. However, ECharts should clearly identify which APIs 
(especially ECharts options) require security-related preprocessing or 
considerations in specific use cases. Given the large number of ECharts 
options, preprocess all inputs in every case would be impractical and 
unnecessary.
+
+ECharts renders using Canvas or SVG, except for several special components 
that allow HTML rendering (e.g., [toolip](${optionPath}tooltip), 
[dataView](${optionPath}toolbox.feature.dataView)). ECharts APIs accept 
Non-JS-function inputs and JS-function inputs. JS-function inputs are intended 
to be execute. Most non-JS-function inputs (e.g., plain text provided to be 
rendered) are treated as data only, and are inherently prevented from code 
evaluation and execution. Therefore, they generally do not require sanitization 
from malicious code. However, several APIs allow embeding potential unsafe 
content (for example, raw HTML or raw URLs) into the page. These APIs are 
powerful but vulnerable to Cross-Site Scripting (XSS) and related attacks if 
the inputs originate from untrusted sources.
+
+**Generally speaking, if no untrusted content is involved, these injection 
vulnerabilities will not arise.** Untrusted content refers to content that 
originates from a source that can not be fully controlled, or that can be 
modified or injected by users or external systems. Developers must assume it 
unsafe to use directly in HTML, CSS and JS. For example, content is untrusted 
if it is produced by users or received from a client. However, handling 
user-provided content is often unavoidable. For example, when rendering user 
data fetched from a database inside an HTML-based `tooltip` through a 
customized formatter, additional processing is required to ensure correctness 
(typically by HTML escaping) and to prevent XSS and related attacks (typically 
by sanitizing any untrusted parts if they can not be unescaped to plain text).
+
+Before deploying charts, please review this **checklist** to ensure your usage 
is safe:
+
+| APIs | Potential Risks and Suggestions |
+| ------|------------------ |
+| **option [tooltip.formatter](${optionPath}tooltip.formatter)**<br>· 
`formatter` allows HTML string or DOM elements input, which are later rendered 
directly inside the tooltip, where XSS risks need to be 
considered.<br>(exceptions): A string directly set to the `formatter` is 
treated as a simple template for later combining with data internally. 
[tooltip.renderMode: 'richText'](${optionPath}tooltip.renderMode) is another 
level of templating syntax for styling. Both of them are internally implemented 
and safe from injection.<br><br>**option 
[toolbox.feature.dataView.optionToContent](${optionPath}toolbox.feature.dataView.optionToContent)**<br>**option
 
[toolbox.feature.dataView.title](${optionPath}toolbox.feature.dataView.title)**<br>**option
 
[toolbox.feature.dataView.lang](${optionPath}toolbox.feature.dataView.lang)**<br>·
 The `tooltip.dataView` panel is fully rendered in HTML. Certain parts of the 
HTML string are allowed to be customized via these APIs. | XSS risks should be 
consi
 dered. In most cases, HTML escaping alone is sufficient. But if any unescaped 
parts originate from untrusted sources, more measures are required (e.g., 
sanitization, sandboxing).<br><br>See section ["Passing Raw HTML 
Safely"](best-practices/security#passing_raw_html_safely) for safe usage 
recommendations. |
+| **option [tooltip.extraCssText](${optionPath}tooltip.extraCssText)**<br>· 
`extraCssText` accepts a raw CSS style string for later directly appending to 
`tooltipEl.style.cssText`(via the DOM API).<br>(exceptions): this option is not 
applicable when [tooltip.renderMode: 
'richText'](${optionPath}tooltip.renderMode).<br> | Safe if the input comes 
from trusted sources; otherwise, a careful assessment is required.<br><br>See 
section ["Passing inline CSS 
Safely"](best-practices/security#passing_inline_css_safely) for details. |
+| **option [title.link](${optionPath}title.link)**<br>**option 
[title.sublink](${optionPath}title.sublink)**<br>**option 
[series-treemap.data.link](${optionPath}series-treemap.data.link)**<br>**option 
[series-sunburst.data.link](${optionPath}series-sunburst.data.link)**<br>· They 
accept raw URLs directly for these links. | Safe if the input comes from 
trusted sources; otherwise, XSS risks should be considered.<br><br>See section 
["Passing Raw URLs Safely"](best-practices/security#passing_raw_urls_safely) 
for safe usage recommendations.
+**option 
[toolbox.feature.saveAsImage.name](${optionPath}toolbox.feature.saveAsImage.name)**<br>**option
 
[toolbox.feature.saveAsImage.type](${optionPath}toolbox.feature.saveAsImage.type)**<br>**option
 [title[0].text](${optionPath}title.text)**<br>· The download filename is 
assembled by `{name}.{type}` without validation or sanitization. If `name` is 
not provided, `title[0].text` (if any) has historically been used instead, 
although this usage is not recommended. | See section ["Passing Download 
Filename Safely"](best-practices/security#passing_download_filename_safely) for 
safe usage recommendations. |
+| All JS-function inputs (callbacks) | This is generally not a concern, unless 
special requirements involve untrusted code.<br><br>See section ["Passing JS 
Function Safely"](best-practices/security#passing_js_function_safely) for 
details. |
+
+
+## Passing Raw HTML Safely [[[#passing_raw_html_safely]]]
+
+Section ["Security Boundaries and 
Checklist"](best-practices/security#security_boundaries_and_checklist) have 
listed the APIs that accept raw HTML directly. Untrusted HTML may lead to XSS 
and related attacks, so additional processing is required before passing 
content to ECharts. Several commonly used mitigation approaches -- "HTML 
Escaping", "Sanitization", "Sandboxing" are described below. In most cases, 
"HTML Escaping" is sufficient, except when unescaped content comes from 
untrusted sources.
+
+### HTML Escaping [[[#passing_raw_html_safely_html_escaping]]]
+HTML escaping is always necessary for data before assembling it to an HTML 
string -- not only for security, but also for the basic correctness of display.
+
+A typical and simplest HTML escaping implementation is these character 
conversions:
+```
+'&' => '&amp;'
+'<' => '&lt;'
+'>' => '&gt;'
+'"' => '&quot;'
+"'" => '&#39;
+```
+It removes the functionality from the markup characters, thereby closing the 
attack vector for code injection (e.g., `<script>...</script>`), regardless of 
whether the content is trusted or untrusted.
+
+Other approaches, like using DOM API `.textContent = `, can also escape HTML.
+
+In most use cases, untrusted content (e.g., user-provided text) is only used 
for display as plain text, while markup tokens (i.e., parts not meant to be 
escaped, such as HTML tags or attributes) are fully controlled by the 
application owner and therefore trusted. In this scenario, HTML escaping alone 
is an effective and simple way to prevent from XSS, as lone as all untrusted 
content is properly escaped.
+
+### Sanitization [[[#passing_raw_html_safely_sanitization]]]
+
+Some use cases require untrusted markup tokens to be interpreted as actual 
markup. For example, text from a database may include styling or functional 
tags (e.g., `<em>`, `<a href="...">`) that are meant to be interpreted rather 
than displayed as plain text. Another example is that users or untrusted 
sources are allowed to provide HTML templates that define structures and 
styles, which are later combined with data content to produce the final 
renderable HTML and passed to ECharts.
+
+In these cases, the security risks are heightened. Sanitization can be applied 
to mitigate those risks, provided that no embedded JS and CSS code is allowed 
to execute. A sanitizer filters HTML content based on predefined whitelists -- 
for example, removing `<script>` and `<style>` blocks, `<link>` elements, 
inline CSS, event handler attributes such as `onclick`, and URLs using 
`javascript:` protocol. It's recommended to use a well-maintained and widely 
adopted sanitizer rather than writing your own regex or manual string 
manipulations.
+
+Sanitization may be enforced on the client-side, on the server-side, or both, 
depending on the product requirements and threat model. For example, concerning 
content that originates from client (e.g., submitted by users), relying only on 
client-side sanitization is insufficient because an attacker can bypass the 
client and submit crafted payloads directly to the server. For instance, an 
online visual editor lets users compose posts in a WYSIWYG fashion, where users 
can choose from several built-in HTML snippets/templates or JS-functions (e.g., 
for [tooltip.formatter](${optionPath}#tooltip.formatter) or 
[label.formatter](${optionPath}#series-scatter.label.formatter)). If the 
selected or generated HTML text or JS-function text are sent from client to 
server and persisted to the database without any additional handling, an 
attacker can simulate a network request to inject malicious code. Later, when 
those options are retrieved and passed to 
[chart.setOption()](${apiPath}echartsInstance
 .setOption), the malicious code will execute. There are some recommended 
mitigations for this case:
++ Persist only reference (IDs) to this built-in snippets/tempates or 
JS-functions, not raw code supplied by client.
++ If user-provided snippets are allowed for expressiveness (beyond built-in 
selections), some third-party string templating libraries may be introduced to 
preventing injection.
++ If user-provided snippets must allow HTML (beyond the approaches above), 
enforce strict server-side sanitization or validation before persisting. This 
should include removing all JS, CSS, and other potentially unsafe content. 
Additionally, consider using a sandboxed iframe to limit the potential impact 
of any remaining security issues.
+
+Achieving sufficient security through sanitization is sometimes not easy. It 
requires proper configurations, must be kept up to date with browers changes, 
and often needs to be combined with other defense mechanisms to be "safe 
enough" for most real-world use cases. HTML is extremely complex -- the more 
features are allowed in untrusted content, the more potential attack vectors 
are introduced.
+
+### Sandboxing [[[#passing_raw_html_sandboxing]]]
+
+If executing untrusted code is required, or other measures are considered 
insufficient, a sandboxed iframe can provide a higher level of security, as 
used by services like JSFiddle and CodePen.
+
+
+## Passing inline CSS Safely [[[#passing_inline_css_safely]]]
+
+Although CSS safety issues is covered by the discussion about HTML safety (see 
section ["Passing Raw HTML 
Safely"](best-practices/security#passing_raw_html_safely)), this section 
focuses especially the APIs that only accept inline CSS strings (those that 
modify `style` attribute via the DOM API `.style.cssText =`), which are listed 
in section ["Security Boundaries and 
Checklist"](best-practices/security#security_boundaries_and_checklist).

Review Comment:
   `focuses` should add `on`?



##########
contents/en/best-practices/security.md:
##########
@@ -0,0 +1,97 @@
+# Security
+
+## Overview
+
+ECharts aims to provide rich and flexible visualization capabilities. Although 
the vast majority of its APIs do not require special security considerations, 
sereval APIs are exceptions. For example, the option `tooltip.formatter` 
accepts a raw HTML string, allowing full control over the component's content 
and layout; the option `title.link` uses the provided URL string directly 
without automatic sanitization. While this flexibility is powerful, security 
risks may arise if the input comes from untrusted sources. These APIs are 
listed below, along with suggestions on how to use these features safely.
+
+Any security issues can be reported to 
[[email protected]](mailto:[email protected]) .
+
+
+## Security Boundaries and Checklist [[[#security_boundaries_and_checklist]]]
+
+ECharts focuses on visualization logic. It assumes that inputs are trusted, 
and does not automatically sanitize them. In fact, ECharts itself can not 
properly sanitize inputs, as there are no universal sanitization rules that 
applies to all use cases. However, ECharts should clearly identify which APIs 
(especially ECharts options) require security-related preprocessing or 
considerations in specific use cases. Given the large number of ECharts 
options, preprocess all inputs in every case would be impractical and 
unnecessary.
+
+ECharts renders using Canvas or SVG, except for several special components 
that allow HTML rendering (e.g., [toolip](${optionPath}tooltip), 
[dataView](${optionPath}toolbox.feature.dataView)). ECharts APIs accept 
Non-JS-function inputs and JS-function inputs. JS-function inputs are intended 
to be execute. Most non-JS-function inputs (e.g., plain text provided to be 
rendered) are treated as data only, and are inherently prevented from code 
evaluation and execution. Therefore, they generally do not require sanitization 
from malicious code. However, several APIs allow embeding potential unsafe 
content (for example, raw HTML or raw URLs) into the page. These APIs are 
powerful but vulnerable to Cross-Site Scripting (XSS) and related attacks if 
the inputs originate from untrusted sources.
+
+**Generally speaking, if no untrusted content is involved, these injection 
vulnerabilities will not arise.** Untrusted content refers to content that 
originates from a source that can not be fully controlled, or that can be 
modified or injected by users or external systems. Developers must assume it 
unsafe to use directly in HTML, CSS and JS. For example, content is untrusted 
if it is produced by users or received from a client. However, handling 
user-provided content is often unavoidable. For example, when rendering user 
data fetched from a database inside an HTML-based `tooltip` through a 
customized formatter, additional processing is required to ensure correctness 
(typically by HTML escaping) and to prevent XSS and related attacks (typically 
by sanitizing any untrusted parts if they can not be unescaped to plain text).
+
+Before deploying charts, please review this **checklist** to ensure your usage 
is safe:
+
+| APIs | Potential Risks and Suggestions |
+| ------|------------------ |
+| **option [tooltip.formatter](${optionPath}tooltip.formatter)**<br>· 
`formatter` allows HTML string or DOM elements input, which are later rendered 
directly inside the tooltip, where XSS risks need to be 
considered.<br>(exceptions): A string directly set to the `formatter` is 
treated as a simple template for later combining with data internally. 
[tooltip.renderMode: 'richText'](${optionPath}tooltip.renderMode) is another 
level of templating syntax for styling. Both of them are internally implemented 
and safe from injection.<br><br>**option 
[toolbox.feature.dataView.optionToContent](${optionPath}toolbox.feature.dataView.optionToContent)**<br>**option
 
[toolbox.feature.dataView.title](${optionPath}toolbox.feature.dataView.title)**<br>**option
 
[toolbox.feature.dataView.lang](${optionPath}toolbox.feature.dataView.lang)**<br>·
 The `tooltip.dataView` panel is fully rendered in HTML. Certain parts of the 
HTML string are allowed to be customized via these APIs. | XSS risks should be 
consi
 dered. In most cases, HTML escaping alone is sufficient. But if any unescaped 
parts originate from untrusted sources, more measures are required (e.g., 
sanitization, sandboxing).<br><br>See section ["Passing Raw HTML 
Safely"](best-practices/security#passing_raw_html_safely) for safe usage 
recommendations. |
+| **option [tooltip.extraCssText](${optionPath}tooltip.extraCssText)**<br>· 
`extraCssText` accepts a raw CSS style string for later directly appending to 
`tooltipEl.style.cssText`(via the DOM API).<br>(exceptions): this option is not 
applicable when [tooltip.renderMode: 
'richText'](${optionPath}tooltip.renderMode).<br> | Safe if the input comes 
from trusted sources; otherwise, a careful assessment is required.<br><br>See 
section ["Passing inline CSS 
Safely"](best-practices/security#passing_inline_css_safely) for details. |
+| **option [title.link](${optionPath}title.link)**<br>**option 
[title.sublink](${optionPath}title.sublink)**<br>**option 
[series-treemap.data.link](${optionPath}series-treemap.data.link)**<br>**option 
[series-sunburst.data.link](${optionPath}series-sunburst.data.link)**<br>· They 
accept raw URLs directly for these links. | Safe if the input comes from 
trusted sources; otherwise, XSS risks should be considered.<br><br>See section 
["Passing Raw URLs Safely"](best-practices/security#passing_raw_urls_safely) 
for safe usage recommendations.
+**option 
[toolbox.feature.saveAsImage.name](${optionPath}toolbox.feature.saveAsImage.name)**<br>**option
 
[toolbox.feature.saveAsImage.type](${optionPath}toolbox.feature.saveAsImage.type)**<br>**option
 [title[0].text](${optionPath}title.text)**<br>· The download filename is 
assembled by `{name}.{type}` without validation or sanitization. If `name` is 
not provided, `title[0].text` (if any) has historically been used instead, 
although this usage is not recommended. | See section ["Passing Download 
Filename Safely"](best-practices/security#passing_download_filename_safely) for 
safe usage recommendations. |
+| All JS-function inputs (callbacks) | This is generally not a concern, unless 
special requirements involve untrusted code.<br><br>See section ["Passing JS 
Function Safely"](best-practices/security#passing_js_function_safely) for 
details. |
+
+
+## Passing Raw HTML Safely [[[#passing_raw_html_safely]]]
+
+Section ["Security Boundaries and 
Checklist"](best-practices/security#security_boundaries_and_checklist) have 
listed the APIs that accept raw HTML directly. Untrusted HTML may lead to XSS 
and related attacks, so additional processing is required before passing 
content to ECharts. Several commonly used mitigation approaches -- "HTML 
Escaping", "Sanitization", "Sandboxing" are described below. In most cases, 
"HTML Escaping" is sufficient, except when unescaped content comes from 
untrusted sources.
+
+### HTML Escaping [[[#passing_raw_html_safely_html_escaping]]]
+HTML escaping is always necessary for data before assembling it to an HTML 
string -- not only for security, but also for the basic correctness of display.
+
+A typical and simplest HTML escaping implementation is these character 
conversions:
+```
+'&' => '&amp;'
+'<' => '&lt;'
+'>' => '&gt;'
+'"' => '&quot;'
+"'" => '&#39;
+```
+It removes the functionality from the markup characters, thereby closing the 
attack vector for code injection (e.g., `<script>...</script>`), regardless of 
whether the content is trusted or untrusted.
+
+Other approaches, like using DOM API `.textContent = `, can also escape HTML.
+
+In most use cases, untrusted content (e.g., user-provided text) is only used 
for display as plain text, while markup tokens (i.e., parts not meant to be 
escaped, such as HTML tags or attributes) are fully controlled by the 
application owner and therefore trusted. In this scenario, HTML escaping alone 
is an effective and simple way to prevent from XSS, as lone as all untrusted 
content is properly escaped.
+
+### Sanitization [[[#passing_raw_html_safely_sanitization]]]
+
+Some use cases require untrusted markup tokens to be interpreted as actual 
markup. For example, text from a database may include styling or functional 
tags (e.g., `<em>`, `<a href="...">`) that are meant to be interpreted rather 
than displayed as plain text. Another example is that users or untrusted 
sources are allowed to provide HTML templates that define structures and 
styles, which are later combined with data content to produce the final 
renderable HTML and passed to ECharts.
+
+In these cases, the security risks are heightened. Sanitization can be applied 
to mitigate those risks, provided that no embedded JS and CSS code is allowed 
to execute. A sanitizer filters HTML content based on predefined whitelists -- 
for example, removing `<script>` and `<style>` blocks, `<link>` elements, 
inline CSS, event handler attributes such as `onclick`, and URLs using 
`javascript:` protocol. It's recommended to use a well-maintained and widely 
adopted sanitizer rather than writing your own regex or manual string 
manipulations.
+
+Sanitization may be enforced on the client-side, on the server-side, or both, 
depending on the product requirements and threat model. For example, concerning 
content that originates from client (e.g., submitted by users), relying only on 
client-side sanitization is insufficient because an attacker can bypass the 
client and submit crafted payloads directly to the server. For instance, an 
online visual editor lets users compose posts in a WYSIWYG fashion, where users 
can choose from several built-in HTML snippets/templates or JS-functions (e.g., 
for [tooltip.formatter](${optionPath}#tooltip.formatter) or 
[label.formatter](${optionPath}#series-scatter.label.formatter)). If the 
selected or generated HTML text or JS-function text are sent from client to 
server and persisted to the database without any additional handling, an 
attacker can simulate a network request to inject malicious code. Later, when 
those options are retrieved and passed to 
[chart.setOption()](${apiPath}echartsInstance
 .setOption), the malicious code will execute. There are some recommended 
mitigations for this case:
++ Persist only reference (IDs) to this built-in snippets/tempates or 
JS-functions, not raw code supplied by client.
++ If user-provided snippets are allowed for expressiveness (beyond built-in 
selections), some third-party string templating libraries may be introduced to 
preventing injection.
++ If user-provided snippets must allow HTML (beyond the approaches above), 
enforce strict server-side sanitization or validation before persisting. This 
should include removing all JS, CSS, and other potentially unsafe content. 
Additionally, consider using a sandboxed iframe to limit the potential impact 
of any remaining security issues.
+
+Achieving sufficient security through sanitization is sometimes not easy. It 
requires proper configurations, must be kept up to date with browers changes, 
and often needs to be combined with other defense mechanisms to be "safe 
enough" for most real-world use cases. HTML is extremely complex -- the more 
features are allowed in untrusted content, the more potential attack vectors 
are introduced.
+
+### Sandboxing [[[#passing_raw_html_sandboxing]]]
+
+If executing untrusted code is required, or other measures are considered 
insufficient, a sandboxed iframe can provide a higher level of security, as 
used by services like JSFiddle and CodePen.
+
+
+## Passing inline CSS Safely [[[#passing_inline_css_safely]]]
+
+Although CSS safety issues is covered by the discussion about HTML safety (see 
section ["Passing Raw HTML 
Safely"](best-practices/security#passing_raw_html_safely)), this section 
focuses especially the APIs that only accept inline CSS strings (those that 
modify `style` attribute via the DOM API `.style.cssText =`), which are listed 
in section ["Security Boundaries and 
Checklist"](best-practices/security#security_boundaries_and_checklist).

Review Comment:
   `Although CSS safety issues is` -> `are`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to