aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>2022-12-16 16:03:03 +0100
committersonartech <sonartech@sonarsource.com>2022-12-19 20:02:46 +0000
commit4a756e45451336c8142ca3dc83e31a1b318f2614 (patch)
tree1a27d413b2c75a1819a41fc2e46a2355dacb19e9
parent867a7b57aac83b83dd1e99942f6342389affa89d (diff)
downloadsonarqube-4a756e45451336c8142ca3dc83e31a1b318f2614.tar.gz
sonarqube-4a756e45451336c8142ca3dc83e31a1b318f2614.zip
SONAR-17579 UI changes to open external links from user input in a new tab
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsDescription.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/Login.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/inputs/InputForFormattedText.tsx4
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueCommentLine.tsx4
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/CommentTile.tsx4
-rw-r--r--server/sonar-web/src/main/js/helpers/sanitize.ts26
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'],
+ });
+}