diff --git a/.github/scripts/server-mock/package-lock.json b/.github/scripts/server-mock/package-lock.json index 9e86d31b7e1..369f98283c5 100644 --- a/.github/scripts/server-mock/package-lock.json +++ b/.github/scripts/server-mock/package-lock.json @@ -1,28 +1,39 @@ { "name": "server-mock", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "accepts": { + "packages": { + "": { + "name": "server-mock", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "express": "^4.18.1" + } + }, + "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { + "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "array-flatten": { + "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, - "body-parser": { + "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "requires": { + "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", @@ -35,88 +46,120 @@ "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "bytes": { + "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } }, - "call-bind": { + "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { + "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "content-disposition": { + "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { + "dependencies": { "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" } }, - "content-type": { + "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } }, - "cookie": { + "node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } }, - "cookie-signature": { + "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "debug": { + "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { + "dependencies": { "ms": "2.0.0" } }, - "depd": { + "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } }, - "destroy": { + "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, - "ee-first": { + "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, - "encodeurl": { + "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } }, - "escape-html": { + "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, - "etag": { + "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } }, - "express": { + "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "requires": { + "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.1", @@ -148,13 +191,16 @@ "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" } }, - "finalhandler": { + "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { + "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -162,190 +208,279 @@ "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "forwarded": { + "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } }, - "fresh": { + "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "get-intrinsic": { + "node_modules/get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "requires": { + "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "has": { + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-symbols": { + "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "http-errors": { + "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { + "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" } }, - "iconv-lite": { + "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { + "dependencies": { "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "ipaddr.js": { + "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } }, - "media-typer": { + "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } }, - "merge-descriptors": { + "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, - "methods": { + "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } }, - "mime": { + "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } }, - "mime-db": { + "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { + "dependencies": { "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "ms": { + "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "negotiator": { + "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } }, - "object-inspect": { + "node_modules/object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "on-finished": { + "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { + "dependencies": { "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "parseurl": { + "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } }, - "path-to-regexp": { + "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "proxy-addr": { + "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { + "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" } }, - "qs": { + "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { + "dependencies": { "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "range-parser": { + "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } }, - "raw-body": { + "node_modules/raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { + "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "safer-buffer": { + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "send": { + "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { + "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -360,73 +495,98 @@ "range-parser": "~1.2.1", "statuses": "2.0.1" }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } + "engines": { + "node": ">= 0.8.0" } }, - "serve-static": { + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { + "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "setprototypeof": { + "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, - "side-channel": { + "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { + "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "statuses": { + "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } }, - "toidentifier": { + "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } }, - "type-is": { + "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { + "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } }, - "utils-merge": { + "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } }, - "vary": { + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } } } } diff --git a/assets/queries/ansible/aws/alb_listening_on_http/metadata.json b/assets/queries/ansible/aws/alb_listening_on_http/metadata.json index 66cc6c05d46..ca7898df7c9 100644 --- a/assets/queries/ansible/aws/alb_listening_on_http/metadata.json +++ b/assets/queries/ansible/aws/alb_listening_on_http/metadata.json @@ -9,4 +9,4 @@ "descriptionID": "3a7576e5", "cloudProvider": "aws", "cwe": "" -} \ No newline at end of file +} diff --git a/docs/commands.md b/docs/commands.md index 88e0f34c937..8f66adacb82 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -40,6 +40,7 @@ Use "kics [command] --help" for more information about a command. |-m, --bom |include bill of materials (BoM) in results output| | --cloud-provider strings | list of cloud providers to scan (alicloud, aws, azure, gcp, nifcloud, tencentcloud)| | --config string | path to configuration file| +| --new-severities | use new severities in query results | | --disable-full-descriptions | disable request for full descriptions and use default vulnerability descriptions| | --disable-secrets | disable secrets scanning| | --enable-openapi-refs | resolve the file reference, on OpenAPI files (default [false])| diff --git a/docs/dockerhub.md b/docs/dockerhub.md index efe3ac4b6c6..a3269a7bbd0 100644 --- a/docs/dockerhub.md +++ b/docs/dockerhub.md @@ -84,6 +84,7 @@ Flags: -m, --bom include bill of materials (BoM) in results output --cloud-provider strings list of cloud providers to scan (alicloud, aws, azure, gcp) --config string path to configuration file + --new-severities use new severities in query results --disable-full-descriptions disable request for full descriptions and use default vulnerability descriptions --disable-secrets disable secrets scanning --enable-openapi-refs resolve the file reference, on OpenAPI files (default [false]) diff --git a/e2e/fixtures/E2E_CLI_093_RESULT.json b/e2e/fixtures/E2E_CLI_093_RESULT.json new file mode 100644 index 00000000000..12391380f65 --- /dev/null +++ b/e2e/fixtures/E2E_CLI_093_RESULT.json @@ -0,0 +1,66 @@ +{ + "kics_version": "development", + "files_scanned": 2, + "lines_scanned": 68, + "files_parsed": 2, + "lines_parsed": 68, + "lines_ignored": 0, + "files_failed_to_scan": 0, + "queries_total": 1, + "queries_failed_to_execute": 0, + "queries_failed_to_compute_similarity_id": 0, + "scan_id": "console", + "severity_counters": { + "CRITICAL": 0, + "HIGH": 0, + "INFO": 2, + "LOW": 0, + "MEDIUM": 0, + "TRACE": 0 + }, + "total_counter": 2, + "total_bom_resources": 0, + "start": "2024-01-31T15:46:25.2714687Z", + "end": "2024-01-31T15:46:25.5747871Z", + "paths": [ + "/path/test/fixtures/test_new_severity/test", + "/path/test/fixtures/test_new_severity/info" + ], + "queries": [ + { + "query_name": "Run Block Injection", + "query_id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "query_url": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "severity": "INFO", + "platform": "CICD", + "category": "Insecure Configurations", + "experimental": false, + "description": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "description_id": "02044a75", + "files": [ + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "2197922dab336742ff58010e01218006c9b2c930a840018ef8b42fb1284f2a45", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.body", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + }, + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "efac914cab5fb466570dd3a71ee3edd8197a15928c56c2aabff00f54d05c5e6d", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.title", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + } + ] + } + ] +} diff --git a/e2e/fixtures/E2E_CLI_093_RESULT_2.json b/e2e/fixtures/E2E_CLI_093_RESULT_2.json new file mode 100644 index 00000000000..82575809936 --- /dev/null +++ b/e2e/fixtures/E2E_CLI_093_RESULT_2.json @@ -0,0 +1,66 @@ +{ + "kics_version": "development", + "files_scanned": 2, + "lines_scanned": 68, + "files_parsed": 2, + "lines_parsed": 68, + "lines_ignored": 0, + "files_failed_to_scan": 0, + "queries_total": 1, + "queries_failed_to_execute": 0, + "queries_failed_to_compute_similarity_id": 0, + "scan_id": "console", + "severity_counters": { + "CRITICAL": 0, + "HIGH": 0, + "INFO": 0, + "LOW": 2, + "MEDIUM": 0, + "TRACE": 0 + }, + "total_counter": 2, + "total_bom_resources": 0, + "start": "2024-01-31T15:46:25.2714687Z", + "end": "2024-01-31T15:46:25.5747871Z", + "paths": [ + "/path/test/fixtures/test_new_severity/test", + "/path/test/fixtures/test_new_severity/low" + ], + "queries": [ + { + "query_name": "Run Block Injection", + "query_id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "query_url": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "severity": "LOW", + "platform": "CICD", + "category": "Insecure Configurations", + "experimental": false, + "description": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "description_id": "02044a75", + "files": [ + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "2197922dab336742ff58010e01218006c9b2c930a840018ef8b42fb1284f2a45", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.body", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + }, + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "efac914cab5fb466570dd3a71ee3edd8197a15928c56c2aabff00f54d05c5e6d", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.title", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + } + ] + } + ] +} diff --git a/e2e/fixtures/E2E_CLI_093_RESULT_3.json b/e2e/fixtures/E2E_CLI_093_RESULT_3.json new file mode 100644 index 00000000000..05452546a0b --- /dev/null +++ b/e2e/fixtures/E2E_CLI_093_RESULT_3.json @@ -0,0 +1,66 @@ +{ + "kics_version": "development", + "files_scanned": 2, + "lines_scanned": 68, + "files_parsed": 2, + "lines_parsed": 68, + "lines_ignored": 0, + "files_failed_to_scan": 0, + "queries_total": 1, + "queries_failed_to_execute": 0, + "queries_failed_to_compute_similarity_id": 0, + "scan_id": "console", + "severity_counters": { + "CRITICAL": 0, + "HIGH": 0, + "INFO": 0, + "LOW": 0, + "MEDIUM": 2, + "TRACE": 0 + }, + "total_counter": 2, + "total_bom_resources": 0, + "start": "2024-01-31T15:46:25.2714687Z", + "end": "2024-01-31T15:46:25.5747871Z", + "paths": [ + "/path/test/fixtures/test_new_severity/test", + "/path/test/fixtures/test_new_severity/medium" + ], + "queries": [ + { + "query_name": "Run Block Injection", + "query_id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "query_url": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "severity": "MEDIUM", + "platform": "CICD", + "category": "Insecure Configurations", + "experimental": false, + "description": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "description_id": "02044a75", + "files": [ + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "2197922dab336742ff58010e01218006c9b2c930a840018ef8b42fb1284f2a45", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.body", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + }, + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "efac914cab5fb466570dd3a71ee3edd8197a15928c56c2aabff00f54d05c5e6d", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.title", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + } + ] + } + ] +} diff --git a/e2e/fixtures/E2E_CLI_093_RESULT_4.json b/e2e/fixtures/E2E_CLI_093_RESULT_4.json new file mode 100644 index 00000000000..2cc4c510475 --- /dev/null +++ b/e2e/fixtures/E2E_CLI_093_RESULT_4.json @@ -0,0 +1,66 @@ +{ + "kics_version": "development", + "files_scanned": 2, + "lines_scanned": 68, + "files_parsed": 2, + "lines_parsed": 68, + "lines_ignored": 0, + "files_failed_to_scan": 0, + "queries_total": 1, + "queries_failed_to_execute": 0, + "queries_failed_to_compute_similarity_id": 0, + "scan_id": "console", + "severity_counters": { + "CRITICAL": 0, + "HIGH": 2, + "INFO": 0, + "LOW": 0, + "MEDIUM": 0, + "TRACE": 0 + }, + "total_counter": 2, + "total_bom_resources": 0, + "start": "2024-01-31T15:46:25.2714687Z", + "end": "2024-01-31T15:46:25.5747871Z", + "paths": [ + "/path/test/fixtures/test_new_severity/test", + "/path/test/fixtures/test_new_severity/high" + ], + "queries": [ + { + "query_name": "Run Block Injection", + "query_id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "query_url": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "severity": "HIGH", + "platform": "CICD", + "category": "Insecure Configurations", + "experimental": false, + "description": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "description_id": "02044a75", + "files": [ + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "2197922dab336742ff58010e01218006c9b2c930a840018ef8b42fb1284f2a45", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.body", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + }, + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "efac914cab5fb466570dd3a71ee3edd8197a15928c56c2aabff00f54d05c5e6d", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.title", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + } + ] + } + ] +} diff --git a/e2e/fixtures/E2E_CLI_093_RESULT_5.json b/e2e/fixtures/E2E_CLI_093_RESULT_5.json new file mode 100644 index 00000000000..c3d5bab1d5a --- /dev/null +++ b/e2e/fixtures/E2E_CLI_093_RESULT_5.json @@ -0,0 +1,66 @@ +{ + "kics_version": "development", + "files_scanned": 2, + "lines_scanned": 68, + "files_parsed": 2, + "lines_parsed": 68, + "lines_ignored": 0, + "files_failed_to_scan": 0, + "queries_total": 1, + "queries_failed_to_execute": 0, + "queries_failed_to_compute_similarity_id": 0, + "scan_id": "console", + "severity_counters": { + "CRITICAL": 2, + "HIGH": 0, + "INFO": 0, + "LOW": 0, + "MEDIUM": 0, + "TRACE": 0 + }, + "total_counter": 2, + "total_bom_resources": 0, + "start": "2024-01-31T15:46:25.2714687Z", + "end": "2024-01-31T15:46:25.5747871Z", + "paths": [ + "/path/test/fixtures/test_new_severity/test", + "/path/test/fixtures/test_new_severity/critical" + ], + "queries": [ + { + "query_name": "Run Block Injection", + "query_id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "query_url": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "severity": "CRITICAL", + "platform": "CICD", + "category": "Insecure Configurations", + "experimental": false, + "description": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "description_id": "02044a75", + "files": [ + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "2197922dab336742ff58010e01218006c9b2c930a840018ef8b42fb1284f2a45", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.body", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + }, + { + "file_name": "path\\test\\fixtures\\test_new_severities\\test\\positive1.yaml", + "similarity_id": "efac914cab5fb466570dd3a71ee3edd8197a15928c56c2aabff00f54d05c5e6d", + "line": 10, + "issue_type": "IncorrectValue", + "search_key": "run={{if [ \"${{ github.event.issue.body }}\" ]; then\n if [[ \"${{ github.event.issue.title }}\" =~ ^\\[Auto\\]* ]]; then\n :\n else\n echo \"This issue does not need to generate a markdown file.\" 1\u003e\u00262\n exit 1;\n fi;\nelse\n echo \"The description of the issue is empty.\" 1\u003e\u00262\n exit 1;\nfi;\n}}", + "search_line": 10, + "search_value": "github.event.issue.title", + "expected_value": "Run block does not contain dangerous input controlled by user.", + "actual_value": "Run block contains dangerous input controlled by user." + } + ] + } + ] +} diff --git a/e2e/fixtures/assets/scan_help b/e2e/fixtures/assets/scan_help index 5e130e57353..22b10d3008d 100644 --- a/e2e/fixtures/assets/scan_help +++ b/e2e/fixtures/assets/scan_help @@ -45,6 +45,7 @@ Flags: -b, --libraries-path string path to directory with libraries (default "./assets/libraries") --max-file-size int max file size permitted for scanning, in MB (default 5) --minimal-ui simplified version of CLI output + --new-severities use new severities in query results --no-progress hides the progress bar --output-name string name used on report creations (default "results") -o, --output-path string directory path to store reports diff --git a/e2e/testcases/e2e-cli-093_new_severity_metadata_field.go b/e2e/testcases/e2e-cli-093_new_severity_metadata_field.go new file mode 100644 index 00000000000..d9230058f56 --- /dev/null +++ b/e2e/testcases/e2e-cli-093_new_severity_metadata_field.go @@ -0,0 +1,111 @@ +package testcases + +// E2E-CLI-093 - KICS scan with new severity metadata field +// should perform a scan successfully giving results with new severity metadata field and return exit code according to the severity +func init() { //nolint + testSample01 := TestCase{ + Name: "should perform a scans successfully giving results with new severity and return exit code " + + "according to new severity [E2E-CLI-093_1]", + Args: args{ + Args: []cmdArgs{ + []string{"scan", "-o", "/path/e2e/output", + "--output-name", "E2E_CLI_093_RESULT", + "-p", "\"/path/test/fixtures/test_new_severity/test\"", + "-q", "\"/path/test/fixtures/test_new_severity/info\"", + "--new-severities", + }, + }, + ExpectedResult: []ResultsValidation{ + { + ResultsFile: "E2E_CLI_093_RESULT", + }, + }, + }, + WantStatus: []int{20}, + } + testSample02 := TestCase{ + Name: "should perform a scans successfully giving results with new severity and return exit code " + + "according to new severity [E2E-CLI-093_2]", + Args: args{ + Args: []cmdArgs{ + []string{"scan", "-o", "/path/e2e/output", + "--output-name", "E2E_CLI_093_RESULT_2", + "-p", "\"/path/test/fixtures/test_new_severity/test\"", + "-q", "\"/path/test/fixtures/test_new_severity/low\"", + "--new-severities", + }, + }, + ExpectedResult: []ResultsValidation{ + { + ResultsFile: "E2E_CLI_093_RESULT_2", + }, + }, + }, + WantStatus: []int{30, 40, 50, 60}, + } + testSample03 := TestCase{ + Name: "should perform a scans successfully giving results with new severity and return exit code " + + "according to new severity [E2E-CLI-093_3]", + Args: args{ + Args: []cmdArgs{ + []string{"scan", "-o", "/path/e2e/output", + "--output-name", "E2E_CLI_093_RESULT_3", + "-p", "\"/path/test/fixtures/test_new_severity/test\"", + "-q", "\"/path/test/fixtures/test_new_severity/medium\"", + "--new-severities", + }, + }, + ExpectedResult: []ResultsValidation{ + { + ResultsFile: "E2E_CLI_093_RESULT_3", + }, + }, + }, + WantStatus: []int{40}, + } + testSample04 := TestCase{ + Name: "should perform a scans successfully giving results with new severity and return exit code " + + "according to new severity [E2E-CLI-093_4]", + Args: args{ + Args: []cmdArgs{ + []string{"scan", "-o", "/path/e2e/output", + "--output-name", "E2E_CLI_093_RESULT_4", + "-p", "\"/path/test/fixtures/test_new_severity/test\"", + "-q", "\"/path/test/fixtures/test_new_severity/high\"", + "--new-severities", + }, + }, + ExpectedResult: []ResultsValidation{ + { + ResultsFile: "E2E_CLI_093_RESULT_4", + }, + }, + }, + WantStatus: []int{50}, + } + testSample05 := TestCase{ + Name: "should perform a scans successfully giving results with new severity and return exit code " + + "according to new severity [E2E-CLI-093_5]", + Args: args{ + Args: []cmdArgs{ + + []string{"scan", "-o", "/path/e2e/output", + "--output-name", "E2E_CLI_093_RESULT_5", + "-p", "\"/path/test/fixtures/test_new_severity/test\"", + "-q", "\"/path/test/fixtures/test_new_severity/critical\"", + "--new-severities", + }, + }, + ExpectedResult: []ResultsValidation{ + + { + ResultsFile: "E2E_CLI_093_RESULT_5", + }, + }, + }, + WantStatus: []int{60}, + } + + Tests = append(Tests, testSample01, testSample02, testSample03, testSample04, testSample05) + +} diff --git a/go.sum b/go.sum index eb98380a137..c10f94c5d6b 100644 --- a/go.sum +++ b/go.sum @@ -710,6 +710,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8XGgcUTlTxpp3mKhdR2Q9z9HbXM= +github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= diff --git a/internal/console/assets/scan-flags.json b/internal/console/assets/scan-flags.json index 9969caf33f7..870aa3daccd 100644 --- a/internal/console/assets/scan-flags.json +++ b/internal/console/assets/scan-flags.json @@ -221,5 +221,11 @@ "shorthandFlag": "", "defaultValue": "5", "usage": "max file size permitted for scanning, in MB" + }, + "new-severities": { + "flagType": "bool", + "shorthandFlag": "", + "defaultValue": "false", + "usage": "use new severities in query results" } } diff --git a/internal/console/flags/scan_flags.go b/internal/console/flags/scan_flags.go index 933e66d36f1..9e81e9398e0 100644 --- a/internal/console/flags/scan_flags.go +++ b/internal/console/flags/scan_flags.go @@ -37,4 +37,5 @@ const ( OpenAPIReferencesFlag = "enable-openapi-refs" ParallelScanFile = "parallel" MaxFileSizeFlag = "max-file-size" + UseNewSeveritiesFlag = "new-severities" ) diff --git a/internal/console/scan.go b/internal/console/scan.go index 76f9db7b1da..648c06ca569 100644 --- a/internal/console/scan.go +++ b/internal/console/scan.go @@ -142,6 +142,7 @@ func getScanParameters(changedDefaultQueryPath, changedDefaultLibrariesPath bool OpenAPIResolveReferences: flags.GetBoolFlag(flags.OpenAPIReferencesFlag), ParallelScanFlag: flags.GetIntFlag(flags.ParallelScanFile), MaxFileSizeFlag: flags.GetIntFlag(flags.MaxFileSizeFlag), + UseNewSeverities: flags.GetBoolFlag(flags.UseNewSeveritiesFlag), } return &scanParams diff --git a/pkg/engine/inspector.go b/pkg/engine/inspector.go index 0d876bdba20..cc035030f98 100644 --- a/pkg/engine/inspector.go +++ b/pkg/engine/inspector.go @@ -58,7 +58,7 @@ type QueryLoader struct { // VulnerabilityBuilder represents a function that will build a vulnerability type VulnerabilityBuilder func(ctx *QueryContext, tracker Tracker, v interface{}, - detector *detector.DetectLine) (*model.Vulnerability, error) + detector *detector.DetectLine, useNewSeverities bool) (*model.Vulnerability, error) // PreparedQuery includes the opaQuery and its metadata type PreparedQuery struct { @@ -79,6 +79,7 @@ type Inspector struct { enableCoverageReport bool coverageReport cover.Report queryExecTimeout time.Duration + useNewSeverities bool numWorkers int } @@ -118,6 +119,7 @@ func NewInspector( queryParameters *source.QueryInspectorParameters, excludeResults map[string]bool, queryTimeout int, + useNewSeverities bool, needsLog bool, numWorkers int) (*Inspector, error) { log.Debug().Msg("engine.NewInspector()") @@ -170,6 +172,7 @@ func NewInspector( excludeResults: excludeResults, detector: lineDetector, queryExecTimeout: queryExecTimeout, + useNewSeverities: useNewSeverities, numWorkers: adjustNumWorkers(numWorkers), }, nil } @@ -474,7 +477,7 @@ func (c *Inspector) DecodeQueryResults( } func getVulnerabilitiesFromQuery(ctx *QueryContext, c *Inspector, queryResultItem interface{}) (*model.Vulnerability, bool) { - vulnerability, err := c.vb(ctx, c.tracker, queryResultItem, c.detector) + vulnerability, err := c.vb(ctx, c.tracker, queryResultItem, c.detector, c.useNewSeverities) if err != nil && err.Error() == ErrNoResult.Error() { // Ignoring bad results return nil, false diff --git a/pkg/engine/inspector_test.go b/pkg/engine/inspector_test.go index d357a0e4f09..f9138d8c5e5 100644 --- a/pkg/engine/inspector_test.go +++ b/pkg/engine/inspector_test.go @@ -406,6 +406,7 @@ func TestNewInspector(t *testing.T) { //nolint excludeResults map[string]bool queryExecTimeout int needsLog bool + useNewSeverities bool numWorkers int } tests := []struct { @@ -454,6 +455,7 @@ func TestNewInspector(t *testing.T) { //nolint &tt.args.queryFilter, tt.args.excludeResults, tt.args.queryExecTimeout, + tt.args.useNewSeverities, tt.args.needsLog, tt.args.numWorkers) @@ -761,7 +763,7 @@ func newQueryContext(ctx context.Context) QueryContext { func newInspectorInstance(t *testing.T, queryPath []string) *Inspector { querySource := source.NewFilesystemSource(queryPath, []string{""}, []string{""}, filepath.FromSlash("./assets/libraries"), true) var vb = func(ctx *QueryContext, tracker Tracker, v interface{}, - detector *detector.DetectLine) (*model.Vulnerability, error) { + detector *detector.DetectLine, useNewSeverity bool) (*model.Vulnerability, error) { return &model.Vulnerability{}, nil } ins, err := NewInspector( @@ -770,7 +772,7 @@ func newInspectorInstance(t *testing.T, queryPath []string) *Inspector { vb, &tracker.CITracker{}, &source.QueryInspectorParameters{}, - map[string]bool{}, 60, true, 1, + map[string]bool{}, 60, false, true, 1, ) require.NoError(t, err) return ins diff --git a/pkg/engine/vulnerability_builder.go b/pkg/engine/vulnerability_builder.go index a8ae7d34c8e..58e7879f756 100644 --- a/pkg/engine/vulnerability_builder.go +++ b/pkg/engine/vulnerability_builder.go @@ -56,7 +56,7 @@ func modifyVulSearchKeyReference(doc interface{}, originalSearchKey string, stri var DefaultVulnerabilityBuilder = func(ctx *QueryContext, tracker Tracker, v interface{}, - detector *dec.DetectLine) (*model.Vulnerability, error) { + detector *dec.DetectLine, useNewSeverities bool) (*model.Vulnerability, error) { vObj, ok := v.(map[string]interface{}) if !ok { return &model.Vulnerability{}, ErrInvalidResult @@ -152,7 +152,7 @@ var DefaultVulnerabilityBuilder = func(ctx *QueryContext, queryID := getStringFromMap("id", DefaultQueryID, overrideKey, vObj, &logWithFields) - severity := getResolvedSeverity(vObj, &logWithFields, overrideKey) + severity := getResolvedSeverity(vObj, &logWithFields, overrideKey, useNewSeverities) issueType := DefaultIssueType if v := mustMapKeyToString(vObj, "issueType"); v != nil { @@ -244,9 +244,11 @@ func calculeSearchLine(searchLineCalc *searchLineCalculator) (lineNumber int, return lineNumber, similarityIDLineInfo, linesVulne } -func getResolvedSeverity(vObj map[string]interface{}, logWithFields *zerolog.Logger, overrideKey string) model.Severity { +func getResolvedSeverity(vObj map[string]interface{}, logWithFields *zerolog.Logger, + overrideKey string, useNewSeverities bool) model.Severity { var severity model.Severity = model.SeverityInfo s, err := mapKeyToString(vObj, "severity", false) + if err == nil { sev := getSeverity(strings.ToUpper(*s)) if sev == "" { @@ -259,6 +261,12 @@ func getResolvedSeverity(vObj map[string]interface{}, logWithFields *zerolog.Log if sev != "" { severity = sev } + } else if useNewSeverities { + oldS, errOld := mapKeyToString(vObj, "newSeverity", false) + if errOld == nil { + oldSev := getSeverity(strings.ToUpper(*oldS)) + severity = oldSev + } } } } else { diff --git a/pkg/engine/vulnerability_builder_test.go b/pkg/engine/vulnerability_builder_test.go index 3be4b2ceaa5..23fcedb007f 100644 --- a/pkg/engine/vulnerability_builder_test.go +++ b/pkg/engine/vulnerability_builder_test.go @@ -20,10 +20,11 @@ type vbArgs struct { } var vbTests = []struct { - name string - args vbArgs - want model.Vulnerability - wantErr bool + name string + args vbArgs + want model.Vulnerability + useNewVulnerability bool + wantErr bool }{ { name: "DefaultVulnerabilityBuilder", @@ -34,10 +35,11 @@ var vbTests = []struct { Query: &PreparedQuery{ Metadata: model.QueryMetadata{ Metadata: map[string]interface{}{ - "key": "123", - "severity": model.SeverityInfo, - "issueType": "IncorrectValue", - "searchKey": "testSearchKey", + "key": "123", + "severity": model.SeverityInfo, + "newSeverity": model.SeverityCritical, + "issueType": "IncorrectValue", + "searchKey": "testSearchKey", }, Query: "TestQuery", CWE: "", @@ -71,7 +73,7 @@ var vbTests = []struct { KeyActualValue: "", KeyExpectedValue: "", Value: nil, - Output: `{"documentId":"testV","issueType":"IncorrectValue","key":"123","searchKey":"testSearchKey","severity":"INFO"}`, + Output: `{"documentId":"testV","issueType":"IncorrectValue","key":"123","newSeverity":"CRITICAL","searchKey":"testSearchKey","severity":"INFO"}`, }, wantErr: false, }, @@ -188,6 +190,59 @@ var vbTests = []struct { }, wantErr: false, }, + { + name: "DefaultVulnerabilityBuilder with new Severity", + args: vbArgs{ + tracker: &tracker.CITracker{}, + ctx: &QueryContext{ + scanID: "ScanID", + Query: &PreparedQuery{ + Metadata: model.QueryMetadata{ + Metadata: map[string]interface{}{ + "key": "123", + "severity": model.SeverityInfo, + "newSeverity": model.SeverityCritical, + "issueType": "IncorrectValue", + "searchKey": "testSearchKey", + "queryName": "testName", + }, + Query: "TestQuery", + CWE: "", + }, + }, + Files: map[string]model.FileMetadata{ + "testV": {LinesOriginalData: &[]string{}}, + }, + }, + v: map[string]interface{}{ + "documentId": "testV", + }, + }, + useNewVulnerability: true, + want: model.Vulnerability{ + ID: 0, + SimilarityID: "2fefa27cc667decf203d10f103b7ffdec232e9af16e361f47d626e72c72b8d63", + ScanID: "ScanID", + FileID: "", + FileName: "", + DescriptionID: "Undefined", + CWE: "", + QueryID: "Undefined", + QueryName: "testName", + QueryURI: "https://github.com/Checkmarx/kics/", + Severity: model.SeverityCritical, + Line: 1, + SearchLine: -1, + VulnLines: &[]model.CodeLine{}, + IssueType: "IncorrectValue", + SearchKey: "testSearchKey", + KeyActualValue: "", + KeyExpectedValue: "", + Value: nil, + Output: `{"documentId":"testV","issueType":"IncorrectValue","key":"123","newSeverity":"CRITICAL","queryName":"testName","searchKey":"testSearchKey","severity":"INFO"}`, //nolint + }, + wantErr: false, + }, } // TestDefaultVulnerabilityBuilder tests the functions [DefaultVulnerabilityBuilder] and all the methods called by them @@ -195,7 +250,7 @@ func TestDefaultVulnerabilityBuilder(t *testing.T) { for _, tt := range vbTests { insDetector := detector.NewDetectLine(3) t.Run(tt.name, func(t *testing.T) { - got, err := DefaultVulnerabilityBuilder(tt.args.ctx, tt.args.tracker, tt.args.v, insDetector) + got, err := DefaultVulnerabilityBuilder(tt.args.ctx, tt.args.tracker, tt.args.v, insDetector, tt.useNewVulnerability) if (err != nil) != tt.wantErr { t.Errorf("test[%s] DefaultVulnerabilityBuilder() error %v, wantErr %v", tt.name, err, tt.wantErr) return diff --git a/pkg/remediation/scan.go b/pkg/remediation/scan.go index 3a06ea98184..3c9fbf99df7 100644 --- a/pkg/remediation/scan.go +++ b/pkg/remediation/scan.go @@ -239,6 +239,7 @@ func initScan(queryID string) (*engine.Inspector, error) { &queryFilter, make(map[string]bool), c.ScanParams.QueryExecTimeout, + c.ScanParams.UseNewSeverities, false, c.ScanParams.ParallelScanFlag, ) diff --git a/pkg/scan/client.go b/pkg/scan/client.go index df8e34c57d9..05a7ff290a9 100644 --- a/pkg/scan/client.go +++ b/pkg/scan/client.go @@ -47,6 +47,7 @@ type Parameters struct { OpenAPIResolveReferences bool ParallelScanFlag int MaxFileSizeFlag int + UseNewSeverities bool } // Client represents a scan client diff --git a/pkg/scan/scan.go b/pkg/scan/scan.go index 30f01be82e4..6f32cabe951 100644 --- a/pkg/scan/scan.go +++ b/pkg/scan/scan.go @@ -71,6 +71,7 @@ func (c *Client) initScan(ctx context.Context) (*executeScanParameters, error) { queryFilter, c.ExcludeResultsMap, c.ScanParams.QueryExecTimeout, + c.ScanParams.UseNewSeverities, true, c.ScanParams.ParallelScanFlag, ) diff --git a/pkg/scanner/scanner_test.go b/pkg/scanner/scanner_test.go index f2a45e248b8..87cf79da41d 100644 --- a/pkg/scanner/scanner_test.go +++ b/pkg/scanner/scanner_test.go @@ -101,7 +101,7 @@ func createServices(types, cloudProviders []string) (serviceSlice, *storage.Memo inspector, err := engine.NewInspector(context.Background(), querySource, engine.DefaultVulnerabilityBuilder, - t, &source.QueryInspectorParameters{}, map[string]bool{}, 60, true, 1) + t, &source.QueryInspectorParameters{}, map[string]bool{}, 60, true, true, 1) if err != nil { return nil, nil, err } diff --git a/test/fixtures/test_new_severity/critical/metadata.json b/test/fixtures/test_new_severity/critical/metadata.json new file mode 100644 index 00000000000..1179f6c49b8 --- /dev/null +++ b/test/fixtures/test_new_severity/critical/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "queryName": "Run Block Injection", + "newSeverity": "CRITICAL", + "severity": "INFO", + "category": "Insecure Configurations", + "descriptionText": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "descriptionUrl": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "platform": "CICD", + "descriptionID": "02044a75", + "cloudProvider": "common", + "cwe": "" +} diff --git a/test/fixtures/test_new_severity/critical/query.rego b/test/fixtures/test_new_severity/critical/query.rego new file mode 100644 index 00000000000..ae9a223c10e --- /dev/null +++ b/test/fixtures/test_new_severity/critical/query.rego @@ -0,0 +1,186 @@ +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + + input.document[i].on["pull_request_target"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.head_ref", + "github.event.pull_request.body", + "github.event.pull_request.head.label", + "github.event.pull_request.head.ref", + "github.event.pull_request.head.repo.default_branch", + "github.event.pull_request.head.repo.description", + "github.event.pull_request.head.repo.homepage", + "github.event.pull_request.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issues"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issue_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["workflow_run"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.workflow.path", + "github.event.workflow_run.head_branch", + "github.event.workflow_run.head_commit.author.email", + "github.event.workflow_run.head_commit.author.name", + "github.event.workflow_run.head_commit.message", + "github.event.workflow_run.head_repository.description" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["author"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.*.authors.name", + "github.*.authors.email" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + + + +containsPatterns(str, patterns) = matched { + matched := {pattern | + pattern := patterns[_] + regex.match(pattern, str) + } +} + diff --git a/test/fixtures/test_new_severity/high/metadata.json b/test/fixtures/test_new_severity/high/metadata.json new file mode 100644 index 00000000000..add094a692a --- /dev/null +++ b/test/fixtures/test_new_severity/high/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "queryName": "Run Block Injection", + "newSeverity": "HIGH", + "severity": "CRITICAL", + "category": "Insecure Configurations", + "descriptionText": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "descriptionUrl": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "platform": "CICD", + "descriptionID": "02044a75", + "cloudProvider": "common", + "cwe": "" +} diff --git a/test/fixtures/test_new_severity/high/query.rego b/test/fixtures/test_new_severity/high/query.rego new file mode 100644 index 00000000000..ae9a223c10e --- /dev/null +++ b/test/fixtures/test_new_severity/high/query.rego @@ -0,0 +1,186 @@ +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + + input.document[i].on["pull_request_target"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.head_ref", + "github.event.pull_request.body", + "github.event.pull_request.head.label", + "github.event.pull_request.head.ref", + "github.event.pull_request.head.repo.default_branch", + "github.event.pull_request.head.repo.description", + "github.event.pull_request.head.repo.homepage", + "github.event.pull_request.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issues"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issue_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["workflow_run"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.workflow.path", + "github.event.workflow_run.head_branch", + "github.event.workflow_run.head_commit.author.email", + "github.event.workflow_run.head_commit.author.name", + "github.event.workflow_run.head_commit.message", + "github.event.workflow_run.head_repository.description" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["author"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.*.authors.name", + "github.*.authors.email" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + + + +containsPatterns(str, patterns) = matched { + matched := {pattern | + pattern := patterns[_] + regex.match(pattern, str) + } +} + diff --git a/test/fixtures/test_new_severity/info/metadata.json b/test/fixtures/test_new_severity/info/metadata.json new file mode 100644 index 00000000000..edd948fcbef --- /dev/null +++ b/test/fixtures/test_new_severity/info/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "queryName": "Run Block Injection", + "newSeverity": "INFO", + "severity": "CRITICAL", + "category": "Insecure Configurations", + "descriptionText": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "descriptionUrl": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "platform": "CICD", + "descriptionID": "02044a75", + "cloudProvider": "common", + "cwe": "" +} diff --git a/test/fixtures/test_new_severity/info/query.rego b/test/fixtures/test_new_severity/info/query.rego new file mode 100644 index 00000000000..ae9a223c10e --- /dev/null +++ b/test/fixtures/test_new_severity/info/query.rego @@ -0,0 +1,186 @@ +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + + input.document[i].on["pull_request_target"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.head_ref", + "github.event.pull_request.body", + "github.event.pull_request.head.label", + "github.event.pull_request.head.ref", + "github.event.pull_request.head.repo.default_branch", + "github.event.pull_request.head.repo.description", + "github.event.pull_request.head.repo.homepage", + "github.event.pull_request.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issues"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issue_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["workflow_run"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.workflow.path", + "github.event.workflow_run.head_branch", + "github.event.workflow_run.head_commit.author.email", + "github.event.workflow_run.head_commit.author.name", + "github.event.workflow_run.head_commit.message", + "github.event.workflow_run.head_repository.description" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["author"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.*.authors.name", + "github.*.authors.email" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + + + +containsPatterns(str, patterns) = matched { + matched := {pattern | + pattern := patterns[_] + regex.match(pattern, str) + } +} + diff --git a/test/fixtures/test_new_severity/low/metadata.json b/test/fixtures/test_new_severity/low/metadata.json new file mode 100644 index 00000000000..2e19e0601dc --- /dev/null +++ b/test/fixtures/test_new_severity/low/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "queryName": "Run Block Injection", + "newSeverity": "LOW", + "severity": "CRITICAL", + "category": "Insecure Configurations", + "descriptionText": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "descriptionUrl": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "platform": "CICD", + "descriptionID": "02044a75", + "cloudProvider": "common", + "cwe": "" +} diff --git a/test/fixtures/test_new_severity/low/query.rego b/test/fixtures/test_new_severity/low/query.rego new file mode 100644 index 00000000000..ae9a223c10e --- /dev/null +++ b/test/fixtures/test_new_severity/low/query.rego @@ -0,0 +1,186 @@ +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + + input.document[i].on["pull_request_target"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.head_ref", + "github.event.pull_request.body", + "github.event.pull_request.head.label", + "github.event.pull_request.head.ref", + "github.event.pull_request.head.repo.default_branch", + "github.event.pull_request.head.repo.description", + "github.event.pull_request.head.repo.homepage", + "github.event.pull_request.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issues"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issue_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["workflow_run"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.workflow.path", + "github.event.workflow_run.head_branch", + "github.event.workflow_run.head_commit.author.email", + "github.event.workflow_run.head_commit.author.name", + "github.event.workflow_run.head_commit.message", + "github.event.workflow_run.head_repository.description" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["author"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.*.authors.name", + "github.*.authors.email" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + + + +containsPatterns(str, patterns) = matched { + matched := {pattern | + pattern := patterns[_] + regex.match(pattern, str) + } +} + diff --git a/test/fixtures/test_new_severity/medium/metadata.json b/test/fixtures/test_new_severity/medium/metadata.json new file mode 100644 index 00000000000..ab357e7db37 --- /dev/null +++ b/test/fixtures/test_new_severity/medium/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "20f14e1a-a899-4e79-9f09-b6a84cd4649b", + "queryName": "Run Block Injection", + "newSeverity": "MEDIUM", + "severity": "CRITICAL", + "category": "Insecure Configurations", + "descriptionText": "GitHub Actions workflows can be triggered by a variety of events. Every workflow trigger is provided with a GitHub context that contains information about the triggering event, such as which user triggered it, the branch name, and other event context details. Some of this event data, like the base repository name, hash value of a changeset, or pull request number, is unlikely to be controlled or used for injection by the user that triggered the event.", + "descriptionUrl": "https://securitylab.github.com/research/github-actions-untrusted-input/", + "platform": "CICD", + "descriptionID": "02044a75", + "cloudProvider": "common", + "cwe": "" +} diff --git a/test/fixtures/test_new_severity/medium/query.rego b/test/fixtures/test_new_severity/medium/query.rego new file mode 100644 index 00000000000..ae9a223c10e --- /dev/null +++ b/test/fixtures/test_new_severity/medium/query.rego @@ -0,0 +1,186 @@ +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + + input.document[i].on["pull_request_target"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.head_ref", + "github.event.pull_request.body", + "github.event.pull_request.head.label", + "github.event.pull_request.head.ref", + "github.event.pull_request.head.repo.default_branch", + "github.event.pull_request.head.repo.description", + "github.event.pull_request.head.repo.homepage", + "github.event.pull_request.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issues"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["issue_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.issue.body", + "github.event.issue.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["discussion_comment"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.comment.body", + "github.event.discussion.body", + "github.event.discussion.title" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["workflow_run"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.event.workflow.path", + "github.event.workflow_run.head_branch", + "github.event.workflow_run.head_commit.author.email", + "github.event.workflow_run.head_commit.author.name", + "github.event.workflow_run.head_commit.message", + "github.event.workflow_run.head_repository.description" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + +CxPolicy[result] { + + input.document[i].on["author"] + run := input.document[i].jobs[j].steps[k].run + + patterns := [ + "github.*.authors.name", + "github.*.authors.email" + ] + + matched = containsPatterns(run, patterns) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("run={{%s}}", [run]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Run block does not contain dangerous input controlled by user.", + "keyActualValue": "Run block contains dangerous input controlled by user.", + "searchLine": common_lib.build_search_line(["jobs", j, "steps", k, "run"],[]), + "searchValue": matched[m] + } +} + + + +containsPatterns(str, patterns) = matched { + matched := {pattern | + pattern := patterns[_] + regex.match(pattern, str) + } +} + diff --git a/test/fixtures/test_new_severity/test/negative.yaml b/test/fixtures/test_new_severity/test/negative.yaml new file mode 100644 index 00000000000..5f9d4a2dfd5 --- /dev/null +++ b/test/fixtures/test_new_severity/test/negative.yaml @@ -0,0 +1,29 @@ +name: check-go-coverage + +on: + pull_request_target: + branches: [master] + +jobs: + coverage: + name: Check Go coverage + runs-on: ubuntu-latest + steps: + - name: Checkout Source + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Go 1.20.x + uses: actions/setup-go@v4 + with: + go-version: 1.20.x + - name: Run test metrics script + id: testcov + run: | + make test-coverage-report | tee test-results + echo "coverage=$(cat test-results | grep "Total coverage: " test-results | cut -d ":" -f 2 | bc)" >> $GITHUB_ENV + - name: Checks if Go coverage is at least 80% + if: env.coverage < 80 + run: | + echo "Go coverage is lower than 80%: ${{ env.coverage }}%" + exit 1 \ No newline at end of file diff --git a/test/fixtures/test_new_severity/test/positive1.yaml b/test/fixtures/test_new_severity/test/positive1.yaml new file mode 100644 index 00000000000..6ee6d54c544 --- /dev/null +++ b/test/fixtures/test_new_severity/test/positive1.yaml @@ -0,0 +1,39 @@ +name: Web Page To Markdown +on: + issues: + types: [opened] +jobs: + WebPageToMarkdown: + runs-on: ubuntu-latest + steps: + - name: Does the issue need to be converted to markdown + run: | + if [ "${{ github.event.issue.body }}" ]; then + if [[ "${{ github.event.issue.title }}" =~ ^\[Auto\]* ]]; then + : + else + echo "This issue does not need to generate a markdown file." 1>&2 + exit 1; + fi; + else + echo "The description of the issue is empty." 1>&2 + exit 1; + fi; + shell: bash + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + - name: Crawl pages and generate Markdown files + uses: freeCodeCamp-China/article-webpage-to-markdown-action@v0.1.8 + with: + newsLink: '${{ github.event.issue.Body }}' + markDownFilePath: './chinese/articles/' + githubToken: ${{ github.token }} + - name: Git Auto Commit + uses: stefanzweifel/git-auto-commit-action@v4.9.2 + with: + commit_message: '${{ github.event.issue.title }}' + file_pattern: chinese/articles/*.md + commit_user_name: PageToMarkdown Bot + commit_user_email: PageToMarkdown-bot@freeCodeCamp.org \ No newline at end of file diff --git a/test/fixtures/test_new_severity/test/positive_expected_result.json b/test/fixtures/test_new_severity/test/positive_expected_result.json new file mode 100644 index 00000000000..2c8cf126a1c --- /dev/null +++ b/test/fixtures/test_new_severity/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Run Block Injection", + "severity": "CRITICAL", + "line": 10, + "fileName": "positive1.yaml" + } +] diff --git a/test/queries_content_test.go b/test/queries_content_test.go index fc9271cbd2b..618c0ac15ef 100644 --- a/test/queries_content_test.go +++ b/test/queries_content_test.go @@ -201,7 +201,7 @@ func testQueryHasGoodReturnParams(t *testing.T, entry queryEntry) { //nolint inspector, err := engine.NewInspector( ctx, queriesSource, - func(ctx *engine.QueryContext, trk engine.Tracker, v interface{}, detector *detector.DetectLine) (*model.Vulnerability, error) { + func(ctx *engine.QueryContext, trk engine.Tracker, v interface{}, detector *detector.DetectLine, useNewSeverities bool) (*model.Vulnerability, error) { m, ok := v.(map[string]interface{}) require.True(t, ok) @@ -267,6 +267,7 @@ func testQueryHasGoodReturnParams(t *testing.T, entry queryEntry) { //nolint map[string]bool{}, 60, true, + true, 1, ) require.Nil(t, err) diff --git a/test/queries_test.go b/test/queries_test.go index 190f069b298..1832785bc52 100644 --- a/test/queries_test.go +++ b/test/queries_test.go @@ -226,7 +226,7 @@ func testQuery(tb testing.TB, entry queryEntry, filesPath []string, expectedVuln ExcludeQueries: source.ExcludeQueries{ByIDs: []string{}, ByCategories: []string{}}, InputDataPath: "", }, - map[string]bool{}, 60, true, 1) + map[string]bool{}, 60, true,true, 1) require.Nil(tb, err) require.NotNil(tb, inspector) diff --git a/test/similarity_id_test.go b/test/similarity_id_test.go index e61fe3eddcb..bc27742138c 100644 --- a/test/similarity_id_test.go +++ b/test/similarity_id_test.go @@ -309,7 +309,7 @@ func createInspectorAndGetVulnerabilities(ctx context.Context, t testing.TB, ExcludeQueries: source.ExcludeQueries{ByIDs: []string{}, ByCategories: []string{}}, InputDataPath: "", }, - map[string]bool{}, 60, true, 1) + map[string]bool{}, 60, true, true, 1) require.Nil(t, err) require.NotNil(t, inspector)