mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-12-01 19:55:12 -05:00
Disallow data and javascript URIs (#1186)
* Disallow data and javascript URIs Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
parent
031e37325c
commit
7a21a26166
2 changed files with 100 additions and 1 deletions
93
cypress/integration/linkSchemes.ts
Normal file
93
cypress/integration/linkSchemes.ts
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
describe('markdown formatted links to', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.loadConfig()
|
||||||
|
cy.visitTestEditor()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('external domains render as external link', () => {
|
||||||
|
cy.codemirrorFill('[external](https://hedgedoc.org/)')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'https://hedgedoc.org/')
|
||||||
|
.should('have.attr', 'rel', 'noreferer noopener')
|
||||||
|
.should('have.attr', 'target', '_blank')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('note anchor references render as anchor link', () => {
|
||||||
|
cy.codemirrorFill('[anchor](#anchor)')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'http://127.0.0.1:3001/n/test#anchor')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('internal pages render as internal link', () => {
|
||||||
|
cy.codemirrorFill('[internal](other-note)')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'http://127.0.0.1:3001/n/other-note')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('data URIs do not render', () => {
|
||||||
|
cy.codemirrorFill('[data](data:text/plain,evil)')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('javascript URIs do not render', () => {
|
||||||
|
cy.codemirrorFill('[js](javascript:alert("evil"))')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('HTML anchor element links to', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.loadConfig()
|
||||||
|
cy.visitTestEditor()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('external domains render as external link', () => {
|
||||||
|
cy.codemirrorFill('<a href="https://hedgedoc.org/">external</a>')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'https://hedgedoc.org/')
|
||||||
|
.should('have.attr', 'rel', 'noreferer noopener')
|
||||||
|
.should('have.attr', 'target', '_blank')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('note anchor references render as anchor link', () => {
|
||||||
|
cy.codemirrorFill('<a href="#anchor">anchor</a>')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'http://127.0.0.1:3001/n/test#anchor')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('internal pages render as internal link', () => {
|
||||||
|
cy.codemirrorFill('<a href="other-note">internal</a>')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href', 'http://127.0.0.1:3001/n/other-note')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('data URIs do not render', () => {
|
||||||
|
cy.codemirrorFill('<a href="data:text/plain,evil">data</a>')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('javascript URIs do not render', () => {
|
||||||
|
cy.codemirrorFill('<a href="javascript:alert(\'evil\')">js</a>')
|
||||||
|
cy.getMarkdownBody()
|
||||||
|
.find('a')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
|
@ -25,7 +25,13 @@ export class LinkReplacer extends ComponentReplacer {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = node.attribs.href
|
const url = node.attribs.href.trim()
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-script-url
|
||||||
|
if (url.startsWith('data:') || url.startsWith('javascript:')) {
|
||||||
|
return <span>{ node.attribs.href }</span>
|
||||||
|
}
|
||||||
|
|
||||||
const isJumpMark = url.substr(0, 1) === '#'
|
const isJumpMark = url.substr(0, 1) === '#'
|
||||||
|
|
||||||
const id = url.substr(1)
|
const id = url.substr(1)
|
||||||
|
|
Loading…
Reference in a new issue