Skip to content

JavaScript URLs in Tab component don't play nicely with strict CSP #2493

Closed
bluecanvas/design-system-react
#1
@jimmydief

Description

@jimmydief

The tab component uses an <a> element to wrap the tab contents but prevents default navigation behavior through the use of href="javascript:void(0);". This doesn't play nicely with CSP policies without the unsafe-inline directive which prevent the script from executing but also add a warning in the console.

href="javascript:void(0);" // eslint-disable-line no-script-url

The SLDS blueprints for the tab component seem to suggest the Javascript URL approach as well so I'm not sure whether this issue really belongs there.

A potential solution would be to prevent the default behavior of click/keydown events where they're handled within the parent tabs component.

handleClick = (e) => {
let node = e.target;
/* eslint-disable no-cond-assign, fp/no-loops */
do {
if (this.isTabFromContainer(node)) {
if (isTabDisabled(node)) {
return;
}
let parentNode = node.parentNode; // eslint-disable-line prefer-destructuring
if (parentNode.nodeName === 'LI') {
node = node.parentNode;
parentNode = node.parentNode; // eslint-disable-line prefer-destructuring
}
const index = [].slice.call(parentNode.children).indexOf(node);
this.setSelected(index);
return;
}
} while ((node = node.parentNode) !== null);
/* eslint-enable no-cond-assign */
};
handleKeyDown = (event) => {
if (this.isTabFromContainer(event.target)) {
let index = this.getSelectedIndex();
let preventDefault = false;
if (event.keyCode === KEYS.LEFT || event.keyCode === KEYS.UP) {
// Select next tab to the left
index = this.getPrevTab(index);
preventDefault = true;
} else if (event.keyCode === KEYS.RIGHT || event.keyCode === KEYS.DOWN) {
// Select next tab to the right
index = this.getNextTab(index);
preventDefault = true;
}
// Prevent any dumn scrollbars from moving around as we type.
if (preventDefault) {
EventUtil.trap(event);
}
this.setSelected(index, true);
}
};

Happy to contribute if there's an agreeable fix.

It looks like there are some more examples of this. #2463 seems likely related.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions