Skip to content

Commit

Permalink
add security warning for anchor element (rel attribute)
Browse files Browse the repository at this point in the history
  • Loading branch information
jleveugle committed May 6, 2021
1 parent 086cff2 commit 37aa32a
Show file tree
Hide file tree
Showing 5 changed files with 452 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/compiler/compile/nodes/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,26 @@ export default class Element extends Node {
const href_attribute = attribute_map.get('href') || attribute_map.get('xlink:href');
const id_attribute = attribute_map.get('id');
const name_attribute = attribute_map.get('name');
const target_attribute = attribute_map.get('target');

if (target_attribute && target_attribute.get_static_value() === '_blank' && href_attribute) {
const href_static_value = href_attribute.get_static_value() ? href_attribute.get_static_value().toLowerCase() : null;

if(href_static_value === null || href_static_value.startsWith('http') || href_static_value.startsWith('//')) {
const rel = attribute_map.get('rel');
const rel_values = rel ? rel.get_static_value().split(' ') : [];
const expected_values = ['noopener', 'noreferrer'];

expected_values.forEach(expected_value => {
if (!rel || rel && rel_values.indexOf(expected_value) < 0) {
component.warn(this, {
code: `security-anchor-rel-${expected_value}`,
message: `Security: Anchor with "target=_blank" should have rel attribute containing the value "${expected_value}"`
});
}
});
}
}

if (href_attribute) {
const href_value = href_attribute.get_static_value();
Expand Down
34 changes: 34 additions & 0 deletions test/validator/samples/security-anchor-rel-noopener/input.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="https://svelte.dev" target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="https://svelte.dev" target="_blank" rel="">svelte website (invalid)</a>
<a href="https://svelte.dev" target="_blank" rel="noreferrer">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href={'https://svelte.dev'} target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href={'https://svelte.dev'} target="_blank" rel="">svelte website (invalid)</a>
<a href={'https://svelte.dev'} target="_blank" rel="noreferrer">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="//svelte.dev" target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="//svelte.dev" target="_blank" rel="">svelte website (invalid)</a>
<a href="//svelte.dev" target="_blank" rel="noreferrer">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="http://svelte.dev" target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="http://svelte.dev" target="_blank" rel="">svelte website (invalid)</a>
<a href="http://svelte.dev" target="_blank" rel="noreferrer">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="same-host" target="_blank">Same host (valid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="same-host" target="_blank" rel="">Same host (valid)</a>
<a href="same-host" target="_blank" rel="noreferrer">Same host (valid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="http://svelte.dev" target="_blank" rel="noopener">svelte website (valid)</a>
<a href="http://svelte.dev" target="_blank" rel="noreferrer noopener">svelte website (valid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="https://svelte.dev" target="_blank" rel="noopener">svelte website (valid)</a>
<a href="https://svelte.dev" target="_blank" rel="noreferrer noopener">svelte website (valid)</a>
<!-- svelte-ignore security-anchor-rel-noreferrer -->
<a href="//svelte.dev" target="_blank" rel="noopener">svelte website (valid)</a>
<a href="//svelte.dev" target="_blank" rel="noreferrer noopener">svelte website (valid)</a>
182 changes: 182 additions & 0 deletions test/validator/samples/security-anchor-rel-noopener/warnings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
[
{
"code": "security-anchor-rel-noopener",
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"start": {
"line": 2,
"column": 0,
"character": 54
},
"end": {
"line": 2,
"column": 73,
"character": 127
},
"pos": 54
},
{
"code": "security-anchor-rel-noopener",
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"start": {
"line": 4,
"column": 0,
"character": 182
},
"end": {
"line": 4,
"column": 80,
"character": 262
},
"pos": 182
},
{
"code": "security-anchor-rel-noopener",
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"start": {
"line": 5,
"column": 0,
"character": 263
},
"end": {
"line": 5,
"column": 90,
"character": 353
},
"pos": 263
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 483,
"column": 75,
"line": 7
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 408,
"start": {
"character": 408,
"column": 0,
"line": 7
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 620,
"column": 82,
"line": 9
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 538,
"start": {
"character": 538,
"column": 0,
"line": 9
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 713,
"column": 92,
"line": 10
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 621,
"start": {
"character": 621,
"column": 0,
"line": 10
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 835,
"column": 67,
"line": 12
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 768,
"start": {
"character": 768,
"column": 0,
"line": 12
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 964,
"column": 74,
"line": 14
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 890,
"start": {
"character": 890,
"column": 0,
"line": 14
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 1049,
"column": 84,
"line": 15
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 965,
"start": {
"character": 965,
"column": 0,
"line": 15
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 1176,
"column": 72,
"line": 17
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 1104,
"start": {
"character": 1104,
"column": 0,
"line": 17
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 1310,
"column": 79,
"line": 19
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 1231,
"start": {
"character": 1231,
"column": 0,
"line": 19
}
},
{
"code": "security-anchor-rel-noopener",
"end": {
"character": 1400,
"column": 89,
"line": 20
},
"message": "Security: Anchor with \"target=_blank\" should have rel attribute containing the value \"noopener\"",
"pos": 1311,
"start": {
"character": 1311,
"column": 0,
"line": 20
}
}
]
34 changes: 34 additions & 0 deletions test/validator/samples/security-anchor-rel-noreferrer/input.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="https://svelte.dev" target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="https://svelte.dev" target="_blank" rel="">svelte website (invalid)</a>
<a href="https://svelte.dev" target="_blank" rel="noopener">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href={'https://svelte.dev'} target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href={'https://svelte.dev'} target="_blank" rel="">svelte website (invalid)</a>
<a href={'https://svelte.dev'} target="_blank" rel="noopener">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="//svelte.dev" target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="//svelte.dev" target="_blank" rel="">svelte website (invalid)</a>
<a href="//svelte.dev" target="_blank" rel="noopener">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="http://svelte.dev" target="_blank">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="http://svelte.dev" target="_blank" rel="">svelte website (invalid)</a>
<a href="http://svelte.dev" target="_blank" rel="noopener">svelte website (invalid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="same-host" target="_blank">Same host (valid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="same-host" target="_blank" rel="">Same host (valid)</a>
<a href="same-host" target="_blank" rel="noopener">Same host (valid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="http://svelte.dev" target="_blank" rel="noreferrer">svelte website (valid)</a>
<a href="http://svelte.dev" target="_blank" rel="noreferrer noopener">svelte website (valid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="https://svelte.dev" target="_blank" rel="noreferrer">svelte website (valid)</a>
<a href="https://svelte.dev" target="_blank" rel="noreferrer noopener">svelte website (valid)</a>
<!-- svelte-ignore security-anchor-rel-noopener -->
<a href="//svelte.dev" target="_blank" rel="noreferrer">svelte website (valid)</a>
<a href="//svelte.dev" target="_blank" rel="noreferrer noopener">svelte website (valid)</a>
Loading

0 comments on commit 37aa32a

Please sign in to comment.