diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 0000000..034591e --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,31 @@ +plugins: + duplication: + enabled: true + eslint: + enabled: true + fixme: + enabled: true + git-legal: + enabled: true + markdownlint: + enabled: true + sass-lint: + enabled: true + shellcheck: + enabled: true + checks: + SC2086: + enabled: false + scss-lint: + enabled: true + tslint: + enabled: true + vint: + enabled: true +exclude_patterns: + - "db/" + - "**/data.*" + - "dist/" + - "**/node_modules/" + - "**/spec/" + - "**/vendor/" diff --git a/package-lock.json b/package-lock.json index 6ad7042..524e6ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,12 +29,14 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@types/shell-escape": "^0.2.3", "autoprefixer": "^10.0.1", "eslint": "^8", "eslint-config-next": "14.1.0", "postcss": "^8", "prettier": "^3.2.5", "prettier-plugin-organize-imports": "^3.2.4", + "shell-escape": "^0.2.0", "tailwindcss": "^3.3.0", "typescript": "^5" }, @@ -1102,6 +1104,12 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", "devOptional": true }, + "node_modules/@types/shell-escape": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/shell-escape/-/shell-escape-0.2.3.tgz", + "integrity": "sha512-xZWkMuQkn1I20gEzhYRa4/t1pwZ8XiIkqGA1Iee1D2IgAUIRLr57nrgJgF2QmHEfkfVzOM59gi/4xp6V+Aq+4A==", + "dev": true + }, "node_modules/@typescript-eslint/parser": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", @@ -4779,6 +4787,12 @@ "node": ">=8" } }, + "node_modules/shell-escape": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/shell-escape/-/shell-escape-0.2.0.tgz", + "integrity": "sha512-uRRBT2MfEOyxuECseCZd28jC1AJ8hmqqneWQ4VWUTgCAFvb3wKU1jLqj6egC4Exrr88ogg3dp+zroH4wJuaXzw==", + "dev": true + }, "node_modules/side-channel": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", diff --git a/package.json b/package.json index 301cccc..f3881ee 100644 --- a/package.json +++ b/package.json @@ -34,11 +34,13 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "@types/shell-escape": "^0.2.3", "autoprefixer": "^10.0.1", "eslint": "^8", "eslint-config-next": "14.1.0", "postcss": "^8", "prettier": "^3.2.5", + "shell-escape": "^0.2.0", "prettier-plugin-organize-imports": "^3.2.4", "tailwindcss": "^3.3.0", "typescript": "^5" diff --git a/scripts/run.sh b/scripts/run.sh index f2bf5c2..2ffacc4 100644 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -1 +1,3 @@ -npx tsc zenodo.ts && node zenodo.js $1 $2 +#!/usr/bin/bash +set -euo pipefail +npx tsc --esModuleInterop zenodo.ts && node zenodo.js $1 $2 diff --git a/scripts/zenodo.ts b/scripts/zenodo.ts index 277aedd..a73f357 100644 --- a/scripts/zenodo.ts +++ b/scripts/zenodo.ts @@ -1,4 +1,5 @@ import { execSync } from 'child_process' +import shellescape from 'shell-escape' const TOKEN = process.env.ZENODO const filename = process.argv[2] @@ -6,6 +7,8 @@ const path = process.argv[3] const run = (cmd: string): string | Buffer => { try { + // sanitize user input before running to prevent arbitrary code execution + cmd = shellescape(cmd.split(' ')) const output = execSync(cmd, { stdio: 'pipe' }) return output } catch (error) {