File tree Expand file tree Collapse file tree 4 files changed +38
-5
lines changed Expand file tree Collapse file tree 4 files changed +38
-5
lines changed Original file line number Diff line number Diff line change @@ -416,7 +416,10 @@ export class UserProfileBase extends React.Component<InternalProps> {
416
416
>
417
417
< div
418
418
// eslint-disable-next-line react/no-danger
419
- dangerouslySetInnerHTML = { sanitizeUserHTML ( user . biography ) }
419
+ dangerouslySetInnerHTML = { sanitizeUserHTML (
420
+ user . biography ,
421
+ { allowLinks : false } ,
422
+ ) }
420
423
/>
421
424
</ Definition >
422
425
) : null }
Original file line number Diff line number Diff line change @@ -220,9 +220,11 @@ export function nl2br(text: ?string): string {
220
220
* Developer Hub when you hover over the *Some HTML Supported* link under
221
221
* the textarea field.
222
222
*/
223
- export function sanitizeUserHTML ( text : ?string ) : { | __html : string | } {
224
- return sanitizeHTML ( nl2br ( text ) , [
225
- 'a' ,
223
+ export function sanitizeUserHTML (
224
+ text : ?string ,
225
+ { allowLinks = true } : { allowLinks : boolean } = { } ,
226
+ ) : { | __html : string | } {
227
+ const allowTags = [
226
228
'abbr' ,
227
229
'acronym' ,
228
230
'b' ,
@@ -235,7 +237,11 @@ export function sanitizeUserHTML(text: ?string): {| __html: string |} {
235
237
'ol' ,
236
238
'strong' ,
237
239
'ul' ,
238
- ] ) ;
240
+ ] ;
241
+ if ( allowLinks === true ) {
242
+ allowTags . unshift ( 'a' ) ;
243
+ }
244
+ return sanitizeHTML ( nl2br ( text ) , allowTags ) ;
239
245
}
240
246
241
247
export function isAddonAuthor ( {
Original file line number Diff line number Diff line change @@ -379,6 +379,22 @@ describe(__filename, () => {
379
379
) . toHaveTextContent ( biographyText ) ;
380
380
} ) ;
381
381
382
+ it ( 'does not render links in biography' , ( ) => {
383
+ const biographyText = 'Veni vidi vici' ;
384
+ const biography = `<a href="//example.com"><b>${ biographyText } </b></a>` ;
385
+ signInUserAndRenderUserProfile ( { biography } ) ;
386
+
387
+ expect ( screen . getByText ( 'Biography' ) ) . toBeInTheDocument ( ) ;
388
+ expect ( screen . getByClassName ( 'UserProfile-biography' ) ) . toHaveTextContent (
389
+ biographyText ,
390
+ ) ;
391
+ expect (
392
+ within ( screen . getByClassName ( 'UserProfile-biography' ) ) . queryByTagName (
393
+ 'a' ,
394
+ ) ,
395
+ ) . not . toBeInTheDocument ( ) ;
396
+ } ) ;
397
+
382
398
it ( 'omits a null biography' , ( ) => {
383
399
signInUserAndRenderUserProfile ( { biography : null } ) ;
384
400
Original file line number Diff line number Diff line change @@ -672,6 +672,14 @@ describe(__filename, () => {
672
672
expect ( sanitize ( customHtml ) ) . toEqual ( customHtml ) ;
673
673
} ) ;
674
674
675
+ it ( 'can disallow links' , ( ) => {
676
+ const customHtml =
677
+ '<b>check</b> <i>out</i> <a href="http://mysite">my site</a>' ;
678
+ expect ( sanitize ( customHtml , { allowLinks : false } ) ) . toEqual (
679
+ '<b>check</b> <i>out</i> my site' ,
680
+ ) ;
681
+ } ) ;
682
+
675
683
it ( 'does not allow certain tags' , ( ) => {
676
684
expect (
677
685
sanitize ( '<b>my add-on</b> <script>alert("does XSS")</script>' ) ,
You can’t perform that action at this time.
0 commit comments