diff options
author | Revanshu Paliwal <revanshu.paliwal@sonarsource.com> | 2022-12-16 16:03:03 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-12-19 20:02:46 +0000 |
commit | 4a756e45451336c8142ca3dc83e31a1b318f2614 (patch) | |
tree | 1a27d413b2c75a1819a41fc2e46a2355dacb19e9 | |
parent | 867a7b57aac83b83dd1e99942f6342389affa89d (diff) | |
download | sonarqube-4a756e45451336c8142ca3dc83e31a1b318f2614.tar.gz sonarqube-4a756e45451336c8142ca3dc83e31a1b318f2614.zip |
SONAR-17579 UI changes to open external links from user input in a new tab
7 files changed, 40 insertions, 12 deletions
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx index 795a6b0e6c3..724ebbaceb0 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx @@ -23,7 +23,7 @@ import FormattingTips from '../../../components/common/FormattingTips'; import { Button, ResetButtonLink } from '../../../components/controls/buttons'; import RuleTabViewer from '../../../components/rules/RuleTabViewer'; import { translate, translateWithParameters } from '../../../helpers/l10n'; -import { sanitizeString } from '../../../helpers/sanitize'; +import { sanitizeString, sanitizeUserInput } from '../../../helpers/sanitize'; import { RuleDetails } from '../../../types/types'; import { RuleDescriptionSections } from '../rule'; import RemoveExtendedDescriptionModal from './RemoveExtendedDescriptionModal'; @@ -115,7 +115,9 @@ export default class RuleDetailsDescription extends React.PureComponent<Props, S <div className="rule-desc spacer-bottom markdown" // eslint-disable-next-line react/no-danger - dangerouslySetInnerHTML={{ __html: sanitizeString(this.props.ruleDetails.htmlNote) }} + dangerouslySetInnerHTML={{ + __html: sanitizeUserInput(this.props.ruleDetails.htmlNote), + }} /> )} {this.props.canWrite && ( diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx index 87a55a8b372..6f9754d44b1 100644 --- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx +++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx @@ -27,7 +27,7 @@ import IssueChangelogDiff from '../../../components/issue/components/IssueChange import Avatar from '../../../components/ui/Avatar'; import { PopupPlacement } from '../../../components/ui/popups'; import { translate, translateWithParameters } from '../../../helpers/l10n'; -import { sanitizeString } from '../../../helpers/sanitize'; +import { sanitizeUserInput } from '../../../helpers/sanitize'; import { Hotspot, ReviewHistoryType } from '../../../types/security-hotspots'; import { getHotspotReviewHistory } from '../utils'; import HotspotCommentPopup from './HotspotCommentPopup'; @@ -106,7 +106,7 @@ export default function HotspotReviewHistory(props: HotspotReviewHistoryProps) { <div className="markdown" // eslint-disable-next-line react/no-danger - dangerouslySetInnerHTML={{ __html: sanitizeString(html) }} + dangerouslySetInnerHTML={{ __html: sanitizeUserInput(html) }} /> {updatable && ( <div> diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx b/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx index 107dc765de7..80a6e83c515 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx @@ -22,7 +22,7 @@ import { Location } from '../../../components/hoc/withRouter'; import { Alert } from '../../../components/ui/Alert'; import DeferredSpinner from '../../../components/ui/DeferredSpinner'; import { translate } from '../../../helpers/l10n'; -import { sanitizeString } from '../../../helpers/sanitize'; +import { sanitizeUserInput } from '../../../helpers/sanitize'; import { getReturnUrl } from '../../../helpers/urls'; import { IdentityProvider } from '../../../types/types'; import './Login.css'; @@ -62,7 +62,7 @@ export default function Login(props: LoginProps) { <div className="login-message markdown big-padded spacer-top huge-spacer-bottom" // eslint-disable-next-line react/no-danger - dangerouslySetInnerHTML={{ __html: sanitizeString(message) }} + dangerouslySetInnerHTML={{ __html: sanitizeUserInput(message) }} /> )} diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx index 6af35c4f0b2..0acda77c787 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx @@ -22,7 +22,7 @@ import FormattingTipsWithLink from '../../../../components/common/FormattingTips import { Button } from '../../../../components/controls/buttons'; import EditIcon from '../../../../components/icons/EditIcon'; import { translate } from '../../../../helpers/l10n'; -import { sanitizeString } from '../../../../helpers/sanitize'; +import { sanitizeUserInput } from '../../../../helpers/sanitize'; import { DefaultSpecializedInputProps } from '../../utils'; export default function InputForFormattedText(props: DefaultSpecializedInputProps) { @@ -54,7 +54,7 @@ export default function InputForFormattedText(props: DefaultSpecializedInputProp <div className="markdown-preview markdown" // eslint-disable-next-line react/no-danger - dangerouslySetInnerHTML={{ __html: sanitizeString(formattedValue ?? '') }} + dangerouslySetInnerHTML={{ __html: sanitizeUserInput(formattedValue ?? '') }} /> <Button className="spacer-top" onClick={props.onEditing}> <EditIcon className="spacer-right" /> diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.tsx b/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.tsx index 8cd3cd98ad5..ae6ed0d32dc 100644 --- a/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.tsx +++ b/server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.tsx @@ -22,7 +22,7 @@ import { DeleteButton, EditButton } from '../../../components/controls/buttons'; import Toggler from '../../../components/controls/Toggler'; import { PopupPlacement } from '../../../components/ui/popups'; import { translate, translateWithParameters } from '../../../helpers/l10n'; -import { sanitizeString } from '../../../helpers/sanitize'; +import { sanitizeUserInput } from '../../../helpers/sanitize'; import { IssueComment } from '../../../types/types'; import DateFromNow from '../../intl/DateFromNow'; import Avatar from '../../ui/Avatar'; @@ -98,7 +98,7 @@ export default class IssueCommentLine extends React.PureComponent<Props, State> <div className="issue-comment-text markdown" // eslint-disable-next-line react/no-danger - dangerouslySetInnerHTML={{ __html: sanitizeString(comment.htmlText) }} + dangerouslySetInnerHTML={{ __html: sanitizeUserInput(comment.htmlText) }} /> <div className="issue-comment-age"> <span className="a11y-hidden">{translate('issue.comment.posted_on')}</span> diff --git a/server/sonar-web/src/main/js/components/issue/popups/CommentTile.tsx b/server/sonar-web/src/main/js/components/issue/popups/CommentTile.tsx index 6388aca9d64..8c02f495b41 100644 --- a/server/sonar-web/src/main/js/components/issue/popups/CommentTile.tsx +++ b/server/sonar-web/src/main/js/components/issue/popups/CommentTile.tsx @@ -19,7 +19,7 @@ */ import * as React from 'react'; import { translate, translateWithParameters } from '../../../helpers/l10n'; -import { sanitizeString } from '../../../helpers/sanitize'; +import { sanitizeUserInput } from '../../../helpers/sanitize'; import { IssueComment } from '../../../types/types'; import { DeleteButton, EditButton } from '../../controls/buttons'; import DateTimeFormatter from '../../intl/DateTimeFormatter'; @@ -84,7 +84,7 @@ export default class CommentTile extends React.PureComponent<CommentTileProps, C <div className="flex-1 markdown" // eslint-disable-next-line react/no-danger - dangerouslySetInnerHTML={{ __html: sanitizeString(comment.htmlText) }} + dangerouslySetInnerHTML={{ __html: sanitizeUserInput(comment.htmlText) }} /> )} {showEditArea && ( diff --git a/server/sonar-web/src/main/js/helpers/sanitize.ts b/server/sonar-web/src/main/js/helpers/sanitize.ts index 75cb96e84f5..007104385bc 100644 --- a/server/sonar-web/src/main/js/helpers/sanitize.ts +++ b/server/sonar-web/src/main/js/helpers/sanitize.ts @@ -29,3 +29,29 @@ export function sanitizeStringRestricted(html: string) { export function sanitizeString(html: string) { return sanitize(html, { USE_PROFILES: { html: true } }); } + +export function sanitizeUserInput(html: string) { + return sanitize(html, { + ALLOWED_TAGS: [ + 'b', + 'br', + 'code', + 'i', + 'li', + 'p', + 'strong', + 'ul', + 'ol', + 'a', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'blockquote', + 'pre', + ], + ALLOWED_ATTR: ['target', 'href'], + }); +} |