Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tooltip): fix tooltip XSS issue when legend name is HTML string #20045

Merged
merged 3 commits into from
Jun 19, 2024

Conversation

plainheart
Copy link
Member

@plainheart plainheart commented Jun 18, 2024

Brief Information

This pull request is in the type of:

  • bug fixing
  • new feature
  • others

What does this PR do?

Some components use graphic.setTooltipConfig to provide the tooltip ability and use its name as the default tooltip content. This causes potential XSS issues when the name (like legend) is an HTML string. This PR tries to fix it by escaping the raw name from HTML. If users hope to render HTML, they can use tooltip.formatter to do that.

Before

After

Fixed issues

Details

Before: What was the problem?

After: How does it behave after the fixing?

Document Info

One of the following should be checked.

  • This PR doesn't relate to document changes
  • The document should be updated later
  • The document changes have been made in apache/echarts-doc#xxx

Misc

ZRender Changes

  • This PR depends on ZRender changes (ecomfe/zrender#xxx).

Related test cases or examples to use the new APIs

Please refer to the last test case in test/tooltip.html.

Others

Merging options

  • Please squash the commits into a single one when merging.

Other information

Copy link

echarts-bot bot commented Jun 18, 2024

Thanks for your contribution!
The community will review it ASAP. In the meanwhile, please checkout the coding standard and Wiki about How to make a pull request.

The pull request is marked to be PR: author is committer because you are a committer of this project.

@plainheart plainheart added this to the 5.5.1 milestone Jun 18, 2024
Copy link
Contributor

github-actions bot commented Jun 18, 2024

The changes brought by this PR can be previewed at: https://echarts.apache.org/examples/editor?version=PR-20045@6221076

@100pah
Copy link
Member

100pah commented Jun 18, 2024

@plainheart If use tooltip.renderMode: 'richText', after the current modification we'll get as follows, which is probably not expected:

image

But in https://github.com/apache/echarts/pull/20045/files#diff-36702e9ce5f4d6cb00be763ce719953d6fd5384008ad5959e96502145ae344a5R608 we can not know the tooltip view renderMode yet to decide whether perform encodeHTML.

The only way I can think of right now is to add other internal property besides 'content' named maybe 'needEncode' to indicate that the 'content' (i.e., the default tooltip content) need to be encoded according to the different types of tooltip view.

/** @file echarts/src/util/graphic.ts */
    ecData.tooltipConfig = {
        name: itemName,
        option: defaults({
            contentNeedEncode: true,   // need to write as `__contentNeedEncode` like an internal option?
                                                            // or may be public in future?
            content: itemName,
            formatterParams: formatterParams
        }, itemTooltipOptionObj)
    };
/** @file echarts/echarts/src/util/types.ts */
export type ComponentItemTooltipOption<T> = CommonTooltipOption<T> & {
    // Default content HTML.
    content?: string;
    // Whether to encode content acorrdoing to `tooltip.renderMode`.
    //  e.g., renderMode 'html' need to encode but 'richText' do not.
    contentNeedEncode: boolean;
    formatterParams?: ComponentItemTooltipLabelFormatterParams;
};
/** @file echarts/src/component/tooltip/TooltipView.ts */
    private _getContentCascade(subTooltipModel: Model<TooltipOption & ComponentItemTooltipOption<unknown>>): string {
        let tmpModel = subTooltipModel;
        let defaultContent: string;
        while (tmpModel) {
            defaultContent = tmpModel.get('content', true);
            if (this._renderMode === 'html' && tmpModel.get('contentNeedEncode', true)) {
                defaultContent = encodeHTML(defaultContent);
            }
            tmpModel = tmpModel.parentModel;
        }
        return defaultContent;
    }


    private _showComponentItemTooltip(...) {
        // ...
        // const defaultHtml = subTooltipModel.get('content');
        const defaultHtml = this._getContentCascade(subTooltipModel);
        // ...
    }

I'm not sure whether it's a good idea

@plainheart
Copy link
Member Author

plainheart commented Jun 19, 2024

@100pah https://github.com/apache/echarts/blob/5.5.0/src/component/tooltip/TooltipView.ts#L747 passes the raw content of tooltipConfig option to formatter, this makes the encoded defaultHtml being overridden eventually and unused. https://github.com/apache/echarts/blob/5.5.0/src/component/tooltip/TooltipView.ts#L805-L827

@plainheart plainheart merged commit efa3e5a into release-dev Jun 19, 2024
2 checks passed
Copy link

echarts-bot bot commented Jun 19, 2024

Congratulations! Your PR has been merged. Thanks for your contribution! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] 图例的tooltip存在xss攻击
2 participants