aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/projectLinks
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2018-12-11 08:35:04 +0100
committersonartech <sonartech@sonarsource.com>2018-12-20 11:41:28 +0100
commit65e616ffa93f0e0029f792780ff8f3db0b830c2d (patch)
treea7495b271e05e44c328f19f1cc23689bfa6b3452 /server/sonar-web/src/main/js/apps/projectLinks
parent3a08c1730f3fe248414add8fa57a61c5670e04c9 (diff)
downloadsonarqube-65e616ffa93f0e0029f792780ff8f3db0b830c2d.tar.gz
sonarqube-65e616ffa93f0e0029f792780ff8f3db0b830c2d.zip
SONAR-11506, SSF-62 Handle XSS code in project links
Diffstat (limited to 'server/sonar-web/src/main/js/apps/projectLinks')
-rw-r--r--server/sonar-web/src/main/js/apps/projectLinks/LinkRow.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/projectLinks/__tests__/LinkRow-test.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/projectLinks/__tests__/__snapshots__/LinkRow-test.tsx.snap49
3 files changed, 66 insertions, 5 deletions
diff --git a/server/sonar-web/src/main/js/apps/projectLinks/LinkRow.tsx b/server/sonar-web/src/main/js/apps/projectLinks/LinkRow.tsx
index 9ca2a8f6906..c3f83b718f6 100644
--- a/server/sonar-web/src/main/js/apps/projectLinks/LinkRow.tsx
+++ b/server/sonar-web/src/main/js/apps/projectLinks/LinkRow.tsx
@@ -23,6 +23,7 @@ import ConfirmButton from '../../components/controls/ConfirmButton';
import ProjectLinkIcon from '../../components/icons-components/ProjectLinkIcon';
import { Button } from '../../components/ui/buttons';
import { translate, translateWithParameters } from '../../helpers/l10n';
+import isValidUri from '../../app/utils/isValidUri';
interface Props {
link: T.ProjectLink;
@@ -90,9 +91,13 @@ export default class LinkRow extends React.PureComponent<Props> {
<tr data-name={link.name}>
<td className="nowrap">{this.renderName(link)}</td>
<td className="nowrap js-url">
- <a href={link.url} rel="nofollow" target="_blank">
- {link.url}
- </a>
+ {isValidUri(link.url) ? (
+ <a href={link.url} rel="nofollow noreferrer noopener" target="_blank">
+ {link.url}
+ </a>
+ ) : (
+ link.url
+ )}
</td>
<td className="thin nowrap">{this.renderDeleteButton(link)}</td>
</tr>
diff --git a/server/sonar-web/src/main/js/apps/projectLinks/__tests__/LinkRow-test.tsx b/server/sonar-web/src/main/js/apps/projectLinks/__tests__/LinkRow-test.tsx
index 19cff23dd62..3c93017c8ae 100644
--- a/server/sonar-web/src/main/js/apps/projectLinks/__tests__/LinkRow-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projectLinks/__tests__/LinkRow-test.tsx
@@ -42,3 +42,14 @@ it('should render custom link', () => {
)
).toMatchSnapshot();
});
+
+it('should render dangerous code as plain text', () => {
+ expect(
+ shallow(
+ <LinkRow
+ link={{ id: '12', name: 'dangerous', type: 'dangerous', url: 'javascript:alert("Hello")' }}
+ onDelete={jest.fn()}
+ />
+ )
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/projectLinks/__tests__/__snapshots__/LinkRow-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectLinks/__tests__/__snapshots__/LinkRow-test.tsx.snap
index c76c3e13aef..e05b8f94f91 100644
--- a/server/sonar-web/src/main/js/apps/projectLinks/__tests__/__snapshots__/LinkRow-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projectLinks/__tests__/__snapshots__/LinkRow-test.tsx.snap
@@ -28,7 +28,7 @@ exports[`should render custom link 1`] = `
>
<a
href="http://example.com"
- rel="nofollow"
+ rel="nofollow noreferrer noopener"
target="_blank"
>
http://example.com
@@ -51,6 +51,51 @@ exports[`should render custom link 1`] = `
</tr>
`;
+exports[`should render dangerous code as plain text 1`] = `
+<tr
+ data-name="dangerous"
+>
+ <td
+ className="nowrap"
+ >
+ <div>
+ <ProjectLinkIcon
+ className="little-spacer-right"
+ type="dangerous"
+ />
+ <div
+ className="display-inline-block text-top"
+ >
+ <span
+ className="js-name"
+ >
+ dangerous
+ </span>
+ </div>
+ </div>
+ </td>
+ <td
+ className="nowrap js-url"
+ >
+ javascript:alert("Hello")
+ </td>
+ <td
+ className="thin nowrap"
+ >
+ <ConfirmButton
+ confirmButtonText="delete"
+ confirmData="12"
+ isDestructive={true}
+ modalBody="project_links.are_you_sure_to_delete_x_link.dangerous"
+ modalHeader="project_links.delete_project_link"
+ onConfirm={[MockFunction]}
+ >
+ <Component />
+ </ConfirmButton>
+ </td>
+</tr>
+`;
+
exports[`should render provided link 1`] = `
<tr>
<td
@@ -88,7 +133,7 @@ exports[`should render provided link 1`] = `
>
<a
href="http://example.com"
- rel="nofollow"
+ rel="nofollow noreferrer noopener"
target="_blank"
>
http://example.com