-
Notifications
You must be signed in to change notification settings - Fork 659
eslint security spike #31887
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 25_2
Are you sure you want to change the base?
eslint security spike #31887
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a new GitHub Actions workflow to run ESLint security scanning on the DevExtreme monorepo. The workflow is designed to scan JavaScript and TypeScript files for security vulnerabilities using a custom ESLint security configuration (@devexpress/eslint-security-config). The scan runs on pull requests and can be manually triggered, generating an HTML report as an artifact.
Key changes:
- New workflow file that runs security-focused ESLint rules
- Isolated ESLint configuration in
.github/eslint/with its own dependencies - Custom HTML formatter for security scan results
- Configuration to use private package registry for
@devexpress/eslint-security-config
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/eslint-security.yml |
Main workflow definition that triggers on PR changes to JS/TS files; runs ESLint with security rules and uploads HTML report |
.github/eslint/security.config.mjs |
ESLint configuration that applies security rules, disables inline config in CI, and loads ignore patterns |
.github/eslint/package.json |
Isolated npm package with ESLint 9.x, TypeScript-ESLint 8.x, and custom security config as dependencies |
.github/eslint/package-lock.json |
Lockfile for the isolated ESLint environment ensuring reproducible builds |
.github/eslint/only-problems-html.mjs |
Custom ESLint formatter that generates an HTML report showing only files with security issues |
.github/eslint/targets.txt |
Specifies which files/directories to scan (currently set to ** - all files) |
.github/eslint/ignore-security.txt |
Empty file for defining paths to exclude from security scanning |
.github/eslint/.npmrc |
Configuration for authenticating with GitHub Packages to access private security config |
| ignores: [ | ||
| '**/node_modules/**', | ||
| ...extraIgnores, | ||
| ], |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace detected after the closing brace on line 26. This should be removed for consistency and to avoid linting issues.
| ], | |
| ], |
| workflow_dispatch: | ||
| pull_request: | ||
| paths: | ||
| - '.github/eslint/**' |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace detected after .github/eslint/**. This should be removed for consistency.
| - '.github/eslint/**' | |
| - '.github/eslint/**' |
| - '.github/eslint/**' | ||
| - '**/*.ts' | ||
| - '**/*.js' | ||
|
|
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workflow is missing the concurrency configuration that is present in other workflows like lint.yml. Without this, multiple runs of this security scan could execute simultaneously on the same PR, wasting resources. Consider adding:
concurrency:
group: wf-${{github.event.pull_request.number || github.sha}}-${{github.workflow}}
cancel-in-progress: true| concurrency: | |
| group: wf-${{github.event.pull_request.number || github.sha}}-${{github.workflow}} | |
| cancel-in-progress: true |
| cache: npm | ||
| cache-dependency-path: .github/eslint/package-lock.json |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using cache: npm when the repository uses pnpm is incorrect. Other workflows in this repository use pnpm with proper caching setup (see lint.yml). This should use pnpm's action-setup and cache the pnpm store directory instead:
- uses: pnpm/action-setup@v4
with:
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('.github/eslint/package-lock.json') }}| VM_MEMORY: 18144 | ||
| VM_CPU: 16 | ||
| SECURITY_LINT: "1" | ||
| runs-on: farm |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using runs-on: farm is inconsistent with other workflows in this repository which use devextreme-shr2 as the runner. This should be aligned with the repository's standard runner configuration for consistency and to ensure the appropriate environment is used.
| runs-on: farm | |
| runs-on: devextreme-shr2 |
.github/eslint/targets.txt
Outdated
| @@ -0,0 +1 @@ | |||
| ** No newline at end of file | |||
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Targeting ** will scan the entire repository including node_modules, build artifacts, test files, and other directories that shouldn't be security linted. This will cause extremely long execution times and produce irrelevant results. You should specify only the source code directories that need security scanning, such as:
packages/*/js/**
packages/*/src/**
apps/*/src/**
Additionally, consider excluding test files and build artifacts explicitly.
| ** | |
| # Include only relevant source code directories for linting/scanning | |
| packages/*/js/** | |
| packages/*/src/** | |
| apps/*/src/** | |
| # Exclude test files and build artifacts | |
| !**/test*/** | |
| !**/tests/** | |
| !**/testing/** | |
| !**/build/** | |
| !**/artifacts/** | |
| !**/dist/** | |
| !**/node_modules/** |
| ignores: [ | ||
| '**/node_modules/**', | ||
| ...extraIgnores, | ||
| ], |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation: lines 23-26 use tabs while the rest of the file uses spaces. This should be consistent throughout the file.
| ignores: [ | |
| '**/node_modules/**', | |
| ...extraIgnores, | |
| ], | |
| ignores: [ | |
| '**/node_modules/**', | |
| ...extraIgnores, | |
| ], |
| "private": true, | ||
| "type": "module", | ||
| "devDependencies": { | ||
| "@devexpress/eslint-security-config": "^0.1.0", |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation: line 6 uses tabs while lines 7-10 use spaces. This should be consistent throughout the file.
| "@devexpress/eslint-security-config": "^0.1.0", | |
| "@devexpress/eslint-security-config": "^0.1.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 6 out of 8 changed files in this pull request and generated 3 comments.
| mapfile -t TARGETS < <( | ||
| sed 's/^[[:space:]]*//;s/[[:space:]]*$//' .github/eslint/targets.txt \ | ||
| | grep -vE '^\s*#' \ | ||
| | sed '/^\s*$/d' | ||
| ) |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mapfile command is Bash 4+ specific and may not be available on all systems. Consider adding a shebang #!/usr/bin/env bash at the start of the script or using a more portable approach with while read loop for better compatibility.
| export default function(results, _context) { | ||
| const esc = (s) => String(s).replace(/[&<>"']/g, m => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m])); |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HTML escape function doesn't handle all potential XSS vectors. While basic HTML entities are escaped, consider using a well-tested library or ensuring all user-controlled data (file paths, messages, rule IDs) are properly escaped. The current implementation is adequate for the basic cases but could be more robust.
| export default function(results, _context) { | |
| const esc = (s) => String(s).replace(/[&<>"']/g, m => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m])); | |
| import escapeHtml from 'escape-html'; | |
| export default function(results, _context) { | |
| const esc = escapeHtml; |
| cache: npm | ||
| cache-dependency-path: .github/eslint/package-lock.json | ||
|
|
||
| - name: Install security lint dependencies | ||
| working-directory: .github/eslint | ||
| env: | ||
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| npm ci |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache strategy should use pnpm instead of npm to match the repository's package manager. According to the repository guidelines, DevExtreme uses pnpm 9.15.4 as its package manager.
| cache: npm | |
| cache-dependency-path: .github/eslint/package-lock.json | |
| - name: Install security lint dependencies | |
| working-directory: .github/eslint | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| npm ci | |
| cache: pnpm | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Install security lint dependencies | |
| working-directory: .github/eslint | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| pnpm install --frozen-lockfile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 6 out of 8 changed files in this pull request and generated 1 comment.
| code=$? | ||
| set -e | ||
| code=$? |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant variable assignment. Line 60 captures the exit code after set +e, but line 63 reassigns code=$? after set -e, which will always be 0 (the exit code of the successful set -e command itself). Remove line 63 to preserve the ESLint exit code.
| code=$? |
No description provided.