@fabriziosalmi/slopless 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabriziosalmi/slopless",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -6,8 +6,11 @@ tags:
6
6
  - security
7
7
  match:
8
8
  regex: >-
9
- (?:"[^"\n]*|'[^'\n]*|`[^`\n]*)(?:\bSELECT\b[^\n]{0,80}?\bFROM\b|\bINSERT\s+INTO\b|\bUPDATE\b[^\n]{0,80}?\bSET\b|\bDELETE\b[^\n]{0,80}?\bFROM\b|\bWHERE\b|\bVALUES\s*\()[^\n]{0,120}?["'`]\s*\+|\+=?\s*["'`][^\n]{0,80}?\b(?:WHERE\s|VALUES\s*\(|SET\s+\w+\s*=|ORDER\s+BY|GROUP\s+BY|LIMIT\s+\d|AND\s+\w+\s*=|OR\s+\w+\s*=)
9
+ (?:"[^"\n]*|'[^'\n]*|`[^`\n]*)(?:\bSELECT\b[^\n]{0,80}?\bFROM\b|\bINSERT\s+INTO\b|\bUPDATE\b[^\n]{0,80}?\bSET\b|\bDELETE\b[^\n]{0,80}?\bFROM\b|\bWHERE\b|\bVALUES\s*\()[^\n]{0,120}?["'`]\s*\+|\+=?\s*["'`][^\n]{0,80}?\b(?:WHERE\s|VALUES\s*\(|SET\s+\w+\s*=(?!\s*(?:\?|\$\d+|:\w+|%[sd])\s*[\"'`])|ORDER\s+BY|GROUP\s+BY|LIMIT\s+\d|AND\s+\w+\s*=(?!\s*(?:\?|\$\d+|:\w+|%[sd])\s*[\"'`])|OR\s+\w+\s*=(?!\s*(?:\?|\$\d+|:\w+|%[sd])\s*[\"'`]))
10
10
  flags: i
11
+ # A fragment that closes on a placeholder injects nothing: `q += " AND p = ?"`
12
+ # beside `args = append(args, v)` is how a dynamic WHERE clause is built
13
+ # safely, and it is the shape every Go and Python query builder uses.
11
14
  scan: all
12
15
  file_types:
13
16
  - js
@@ -30,4 +33,7 @@ tests:
30
33
  - sql += " AND status = " + status;
31
34
  quiet:
32
35
  - db.query("SELECT * FROM users WHERE id = $1", [id]);
36
+ - 'q += ` AND project = ?`'
37
+ - sql += " AND id = $1"
38
+ - sql += " AND name = :name"
33
39
  - const label = 'Update ' + count + ' items';
@@ -6,7 +6,11 @@ tags:
6
6
  - security
7
7
  match:
8
8
  regex: >-
9
- (?<!new URL\([^)]{0,200})http://(?!localhost|127\.|0\.0\.0\.0|169\.254\.|\[::1\]|test\b|example\.(?:com|org)|www\.w3\.org|schemas?\.|json-schema\.org|purl\.org|ns\.adobe|www\.apache\.org)
9
+ (?<!new URL\([^)]{0,200})http://(?!localhost|127\.|0\.0\.0\.0|169\.254\.|\[::1\]|test\b|example\.(?:com|org)|www\.w3\.org|schemas?\.|json-schema\.org|purl\.org|ns\.adobe|www\.apache\.org)(?=[\w\[$\{])
10
+ # A scheme with no host after it is prose about the scheme, not an endpoint:
11
+ # a security standard writing "a single http:// subresource downgrades the
12
+ # page" is describing the hazard, and an error message saying "must use
13
+ # http:// or https://" is naming it.
10
14
  scan: strings
11
15
  file_types:
12
16
  - js
@@ -43,5 +47,8 @@ tests:
43
47
  - const dev = 'http://localhost:3000';
44
48
  - const dev2 = 'http://127.0.0.1:8000';
45
49
  - "refuse http://169.254.169.254 (cloud metadata) before connecting"
50
+ - '"A single http:// subresource downgrades the page"'
51
+ - "\"the {label} must use http:// or https://\""
52
+
46
53
  - const parsed = new URL(req.url, `http://${req.headers.host}`);
47
54
  - const svg = 'http://www.w3.org/2000/svg';
@@ -8,6 +8,28 @@ match:
8
8
  ast_check:
9
9
  type: file-length-limit
10
10
  threshold: 500
11
+ # Code files. A long piece of documentation is not a module that wants
12
+ # splitting, and telling a README to become smaller modules is nonsense.
13
+ file_types:
14
+ - js
15
+ - ts
16
+ - tsx
17
+ - jsx
18
+ - py
19
+ - go
20
+ - rs
21
+ - java
22
+ - c
23
+ - cpp
24
+ - cs
25
+ - kt
26
+ - swift
27
+ - rb
28
+ - sh
29
+ - php
30
+ - css
31
+ - scss
32
+ - less
11
33
  message: >-
12
34
  File is too long ({count} lines). Consider splitting it into smaller modules. Max recommended:
13
35
  {threshold}.
@@ -5,8 +5,20 @@ category: core
5
5
  tags:
6
6
  - security
7
7
  match:
8
+ # A literal has no injection point, and neither does a run of them joined with
9
+ # `+`: a tip string split over three lines for readability is still a constant.
8
10
  regex: >-
9
- \.innerHTML\s*=(?!=)(?!\s*(['"])(?:(?!\1)[^\\])*\1\s*[;\n])
11
+ \.innerHTML\s*=(?!=)(?!\s*(?:(['"])(?:(?!\1)[^\\])*\1|\s|\+)+[;\n])
12
+ # The exclusion has to see the lines after the `=`, which line-by-line
13
+ # matching cannot.
14
+ multiline: true
15
+ exclude_test_code: true
16
+ exclude_files:
17
+ - '**/test/**'
18
+ - '**/tests/**'
19
+ - '**/__tests__/**'
20
+ - '**/*.test.*'
21
+ - '**/*.spec.*'
10
22
  file_types:
11
23
  - js
12
24
  - ts
@@ -21,4 +33,9 @@ tests:
21
33
  - el.textContent = text;
22
34
  - alert.innerHTML = '<i class="fa-check"></i> <span id="t"></span>';
23
35
  - el.innerHTML = "";
36
+ # A tip split over several lines for readability is still a constant.
37
+ - |
38
+ el.innerHTML =
39
+ "Tip: try <code>/status</code>, " +
40
+ "or <code>/help</code> for all commands.";
24
41
  - if (el.innerHTML === "") { init(); }
@@ -9,6 +9,22 @@ match:
9
9
  regex: Lorem ipsum dolor sit amet
10
10
  flags: i
11
11
  scan: all
12
+ # A corpus that tests for placeholder text is full of placeholder text. This
13
+ # rule found `Lorem ipsum dolor sit amet.` inside the table of a Go test for a
14
+ # gate that detects exactly that.
15
+ exclude_test_code: true
16
+ exclude_files:
17
+ - '**/test/**'
18
+ - '**/tests/**'
19
+ - '**/__tests__/**'
20
+ - '**/testdata/**'
21
+ - '**/fixtures/**'
22
+ - '**/test_*.py'
23
+ - '**/*_test.py'
24
+ - '**/*_test.go'
25
+ - '**/*_test.rs'
26
+ - '**/*.test.*'
27
+ - '**/*.spec.*'
12
28
  file_types:
13
29
  - md
14
30
  - txt