Skip to content

Commit

Permalink
fix(sanitiseUrl): fix limitations with library (#1821)
Browse files Browse the repository at this point in the history
## Problem

The sanitize-url library does filters HTML entities, but it does not do so recursively. By nesting HTML entities, it is possible to create a URL which specifies the JavaScript protocol handler.

Closes GTA-24-006

## Solution

Handroll a quick url constructor and check that the protocols are adhered to. 

**Breaking Changes**

<!-- Does this PR contain any backward incompatible changes? If so, what are they and should there be special considerations for release? -->

- [ ] Yes - this PR contains breaking changes
  - Details ...
- [X] No - this PR is backwards compatible with ALL of the following feature flags in this [doc](https://www.notion.so/opengov/Existing-feature-flags-518ad2cdc325420893a105e88c432be5)

## Tests

<!-- What tests should be run to confirm functionality? -->
- [ ] Login via github and visit "http://localhost:3000/sites/kishore-test-dev-gh/contact-us" 
- [ ] when hovering over `[+65 6123 4589](tel:+6561234589)` verify that it links to `tel:+6561234589`
- [ ] when hovering over `[[email protected]](mailto:[email protected])` verify that it links to `[email protected]`
- [ ] when hovering over `[online form](https://www.form.gov.sg/)` verify that it links to `https://www.form.gov.sg/`

<img width="533" alt="Screenshot 2024-03-05 at 1 10 36 PM" src="https://github.com/isomerpages/isomercms-frontend/assets/42832651/87c5edbb-8744-47d1-8b9d-01f38893dc15">
  • Loading branch information
kishore03109 authored Mar 11, 2024
1 parent 7b05c74 commit fe6ca6c
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 8 deletions.
6 changes: 3 additions & 3 deletions src/templates/contact-us/ContactsSection.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { sanitizeUrl } from "@braintree/sanitize-url"
import DOMPurify from "dompurify"
import PropTypes from "prop-types"
import { forwardRef } from "react"

import editorStyles from "styles/isomer-cms/pages/Editor.module.scss"

import { sanitiseTemplateUrl } from "templates/utils/sanitiseTemplateUrl"
import { getClassNames } from "templates/utils/stylingUtils"

const Contact = forwardRef(({ contact }, ref) => (
Expand All @@ -30,7 +30,7 @@ const Contact = forwardRef(({ contact }, ref) => (
])}
>
<a
href={sanitizeUrl(`tel:${d[key].replace(/\s/g, "")}`)}
href={sanitiseTemplateUrl(`tel:${d[key].replace(/\s/g, "")}`)}
onClick={(event) => event.preventDefault()}
>
<u>{d[key]}</u>
Expand All @@ -47,7 +47,7 @@ const Contact = forwardRef(({ contact }, ref) => (
])}
>
<a
href={sanitizeUrl(`mailto:${d[key]}`)}
href={sanitiseTemplateUrl(`mailto:${d[key]}`)}
onClick={(event) => event.preventDefault()}
>
<u>{d[key]}</u>
Expand Down
4 changes: 2 additions & 2 deletions src/templates/contact-us/FeedbackSection.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { sanitizeUrl } from "@braintree/sanitize-url"
import PropTypes from "prop-types"
import { forwardRef } from "react"

import editorStyles from "styles/isomer-cms/pages/Editor.module.scss"

import { sanitiseTemplateUrl } from "templates/utils/sanitiseTemplateUrl"
import { getClassNames } from "templates/utils/stylingUtils"

const TemplateFeedbackSection = forwardRef(({ feedback }, ref) => (
Expand Down Expand Up @@ -38,7 +38,7 @@ const TemplateFeedbackSection = forwardRef(({ feedback }, ref) => (
If you have a query, feedback or wish to report a problem related to
this website, please fill in the{" "}
<a
href={sanitizeUrl(feedback)}
href={sanitiseTemplateUrl(feedback)}
rel="noopener noreferrer"
target="_blank"
onClick={(event) => event.preventDefault()}
Expand Down
6 changes: 3 additions & 3 deletions src/templates/contact-us/LocationsSection.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { sanitizeUrl } from "@braintree/sanitize-url"
import PropTypes from "prop-types"
import { forwardRef } from "react"

import editorStyles from "styles/isomer-cms/pages/Editor.module.scss"

import { sanitiseTemplateUrl } from "templates/utils/sanitiseTemplateUrl"
import { getClassNames } from "templates/utils/stylingUtils"

const LocationHours = ({ operatingHours }) => (
Expand Down Expand Up @@ -38,8 +38,8 @@ const LocationAddress = ({ location }) => (
<a
href={
location.maps_link
? sanitizeUrl(location.maps_link)
: sanitizeUrl(
? sanitiseTemplateUrl(location.maps_link)
: sanitiseTemplateUrl(
`https://maps.google.com/?q=${location.address
.join("+")
.replace(/\s/g, "+")}`
Expand Down
14 changes: 14 additions & 0 deletions src/templates/utils/sanitiseTemplateUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { sanitizeUrl } from "@braintree/sanitize-url"

export function sanitiseTemplateUrl(userUrl: string): string {
const allowedProtocols = ["mailto:", "https:", "tel:"]
try {
const url = new URL(userUrl)
if (allowedProtocols.includes(url.protocol)) {
return sanitizeUrl(url.href)
}
} catch (e) {
return "about:blank"
}
return "about:blank"
}

0 comments on commit fe6ca6c

Please sign in to comment.