Skip to content

Commit

Permalink
BACKLOG-22207: Fix href pattern to allow ref and external links (#10)
Browse files Browse the repository at this point in the history
* BACKLOG-22207: Fix ONSITE_URL pattern to allow asset links

* Fix lint

* Remove .DS_Store

* Fix issue adding external links

* Add invalid links test
  • Loading branch information
gflores-jahia authored Jan 17, 2024
1 parent 95a83f8 commit 7759f0d
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ private enum PolicyType {

static {
PATTERNS = new HashMap<>();
String onsiteUrl = "(?:[\\p{L}\\p{N}\\\\\\.\\#@\\$%\\+&;\\-_~,\\?=/!{}:]+|\\#(\\w)+)";
String offsiteUrl = "(\\s*(?:(?:ht|f)tps?://|mailto:)[\\p{L}\\p{N}][\\p{L}\\p{N}\\p{Zs}\\.\\#@\\$%\\+&;:\\-_~,\\?=/!\\(\\)"
+ "]*+\\s*)";
PATTERNS.put("NUMBER_OR_PERCENT", Pattern.compile("[0-9]+%?"));
PATTERNS.put("ONSITE_URL", Pattern.compile("(?:[\\p{L}\\p{N}\\\\\\.\\#@\\$%\\+&;\\-_~,\\?=/!]+|\\#(\\w)+)"));
PATTERNS.put("ONSITE_URL", Pattern.compile(onsiteUrl));
PATTERNS.put("OFFSITE_URL", Pattern.compile(onsiteUrl));
PATTERNS.put("LINKS_URL", Pattern.compile(String.format("(?:%s|%s)", onsiteUrl, offsiteUrl)));
PATTERNS.put("HTML_ID", Pattern.compile("[a-zA-Z0-9\\:\\-_\\.]+"));
PATTERNS.put("OFFSITE_URL", Pattern.compile("\\s*(?:(?:ht|f)tps?://|mailto:)[\\p{L}\\p{N}]"
+ "[\\p{L}\\p{N}\\p{Zs}\\.\\#@\\$%\\+&;:\\-_~,\\?=/!\\(\\)]*+\\s*"));
PATTERNS.put("HTML_CLASS", Pattern.compile("[a-zA-Z0-9\\s,\\-_]+"));
PATTERNS.put("NUMBER", Pattern.compile("[+-]?(?:(?:[0-9]+(?:\\.[0-9]*)?)|\\.[0-9]+)"));
PATTERNS.put("NAME", Pattern.compile("[a-zA-Z0-9\\-_\\$]+"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ htmlFiltering:
pattern: NUMBER_OR_PERCENT
elements: canvas, img, table, td, th, col, colgroup, video
- name: href
pattern: ONSITE_URL
pattern: LINKS_URL
elements: a
- name: hreflang
elements: a
Expand Down
80 changes: 80 additions & 0 deletions tests/cypress/e2e/defaultFiltering.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {addNode, deleteNode} from '@jahia/cypress';
import {
disableHtmlFiltering,
enableHtmlFiltering,
getContent,
modifyContent
} from '../fixtures/utils';

/**
* Test scenarios for default filtering cases
*/
describe('Default HTML filtering', () => {
const siteKey = 'digitall';
const textName = 'myText';
const path = `/sites/${siteKey}/contents/${textName}`;

before(() => {
addNode({
parentPathOrId: `/sites/${siteKey}/contents`,
primaryNodeType: 'jnt:bigText',
name: textName,
properties: [{name: 'text', value: '<p>hello there</p>', language: 'en'}]
});
enableHtmlFiltering(siteKey);
});

after(() => {
disableHtmlFiltering(siteKey);
deleteNode(path);
});

it('allows internal links', () => {
// Note that the actual href text being sent over to the sanitizer is '##doc-context##/{workspace}/##ref:link1##'
const text = '<p><a href="/files/{workspace}/sites/digitall/files/images/pdf/Conference%20Guide.pdf" ' +
'title="Conference Guide.pdf">/files/{workspace}/sites/digitall/files/images/pdf/Conference%20Guide.pdf</a></p>';
modifyContent(path, text);
getContent(path).then(result => {
const value = result.data.jcr.nodeByPath.property.value;
expect(value).to.contain('<p>');
expect(value).to.contain('<a');
expect(value).to.contain('href');
expect(value).to.contain('title');
});
});

it('allows external links', () => {
const text = '<p>This is a <a href="http://google.com" title="My google link">google link</a></p>';
modifyContent(path, text);
getContent(path).then(result => {
const value = result.data.jcr.nodeByPath.property.value;
expect(value).to.contain('<p>');
expect(value).to.contain('<a');
expect(value).to.contain('href');
expect(value).to.contain('title');
});
});

it('rejects invalid protocol links', () => {
const text = '<p>This is an <a href="javascript://%0aalert(document.location)">xss test</a></p>';
modifyContent(path, text);
getContent(path).then(result => {
const value = result.data.jcr.nodeByPath.property.value;
expect(value).to.contain('<p>');
expect(value).to.not.contain('<a');
expect(value).to.not.contain('href');
});
});

it('rejects invalid href links', () => {
const text = '<p>This is an <a href="#javascript:alert(\'hello\')" target="_blank">xss test</a></p>';
modifyContent(path, text);
getContent(path).then(result => {
const value = result.data.jcr.nodeByPath.property.value;
expect(value).to.contain('<p>');
expect(value).to.contain('<a');
expect(value).to.not.contain('href');
expect(value).to.contain('target');
});
});
});

0 comments on commit 7759f0d

Please sign in to comment.