diff --git a/resources/cfml/modules/fixinator/README.md b/resources/cfml/modules/fixinator/README.md index f9cebce..92697df 100644 --- a/resources/cfml/modules/fixinator/README.md +++ b/resources/cfml/modules/fixinator/README.md @@ -41,11 +41,18 @@ Writes results to a file specified by the path in resultFile. You may specify a Specify a format for the `resultFile`: `json` (default), `html`, `pdf`, `csv`, `junit`, `sast`, or `findbugs`. You may specify a comma seperated list of formats and `resultFile` paths if you want to write multiple files. - ### ignorePaths A file globber pattern of paths to ignore from the scan. +### failOnIssues + +Default: `true` - When true returns an exit code of `1` when issues are found, this will cause your build to fail if you are running in CI. If you do not want the build to fail when issues are found, set this to `false`. + +### listScanners + +Default: `false` - Prints out a list of scanners supported by the server in the results. Automatically set to `true` when `verbose` is `true` + ## Environment Variables The following environment variables are used by fixinator: @@ -96,7 +103,8 @@ A `.fixinator.json` configuration file can be placed in the root of a folder to "ignoreExtensions":["ign","ore"], "ignoreScanners":["xss"], "minSeverity": "low", - "minConfidence": "low" + "minConfidence": "low", + "ignorePatterns": {} } Note that `.fixinator.json` files placed in a subfolder of the base scan path are currently ignored. @@ -121,13 +129,23 @@ Default: `low` - The minimum severity level that will be flagged. Set this to `h Default: `high` - The minimum confidence level that will be flagged. Issues with `low` confidence will be more likely to be false positives. -### failOnIssues +### ignorePatterns -Default: `true` - When true returns an exit code of `1` when issues are found, this will cause your build to fail if you are running in CI. If you do not want the build to fail when issues are found, set this to `false`. +Some applications may have their own functions for safely encoding varaibles to prevent Cross Site Scripting (XSS). Suppose you have a `customEncodeHTML()` function that is similar to `encodeForHTML()`, we can tell Fixinator's XSS scanner to ignore variables that have the `customEncodeHTML` function call -### listScanners + "ignorePatterns": { + "xss": ["customEncodeHTML("] + } + +Now suppose you have an a few application variables that are used in SQL, they are not vulnerable to SQL injection because they are hard coded in the application. We can ignore those by adding some patterns for the `sqlinjection` scanner: + + "ignorePatterns": { + "xss": ["customEncodeHTML("], + "sqlinjection": ["application.table_prefix", "application.items_per_page"] + } + +This is a very powerful feature, so make sure you only use it on variables, functions or patterns you know are safe. -Default: `false` - Prints out a list of scanners supported by the server in the results. Automatically set to `true` when `verbose` is `true` ## Ignoring issues in code @@ -143,3 +161,5 @@ The comment must be on the same line as the issue, or on the line above the issu //ignore:iif - b and a are safe variables because... x = iif(c, b, a); + +Also take a look at the `ignorePatterns` object in the `.fixinator.json` file for another way to ignore code from fixinator. diff --git a/resources/cfml/modules/fixinator/box.json b/resources/cfml/modules/fixinator/box.json index 9ef7658..098e2d2 100644 --- a/resources/cfml/modules/fixinator/box.json +++ b/resources/cfml/modules/fixinator/box.json @@ -1,8 +1,8 @@ { "name":"fixinator", - "version":"2.0.0", + "version":"2.0.3", "author":"Foundeo Inc.", - "location":"foundeo/fixinator#v2.0.0", + "location":"foundeo/fixinator#v2.0.3", "homepage":"https://fixinator.app/", "documentation":"https://github.com/foundeo/fixinator/wiki", "repository":{ @@ -11,7 +11,7 @@ }, "bugs":"https://github.com/foundeo/fixinator/issues", "slug":"fixinator", - "shortDescription":"A CommandBox comand for scanning CFML code.", + "shortDescription":"A CommandBox command for scanning CFML code.", "type":"commandbox-modules", "keywords":[ "security", diff --git a/resources/cfml/modules/fixinator/commands/fixinator.cfc b/resources/cfml/modules/fixinator/commands/fixinator.cfc index 288eaf0..e7652e8 100644 --- a/resources/cfml/modules/fixinator/commands/fixinator.cfc +++ b/resources/cfml/modules/fixinator/commands/fixinator.cfc @@ -463,6 +463,8 @@ component extends="commandbox.system.BaseCommand" excludeFromHelp=false { toFix.append({"fix":local.i.fixes[local.fix], "issue":local.i}); } + } else if (arguments.autofix == "auto" || arguments.autofix == "automatic") { + toFix.append({"fix":local.i.fixes[1], "issue":local.i}); } } } else { diff --git a/resources/cfml/modules/fixinator/models/fixinator/FixinatorClient.cfc b/resources/cfml/modules/fixinator/models/fixinator/FixinatorClient.cfc index fb2e935..35b52b1 100644 --- a/resources/cfml/modules/fixinator/models/fixinator/FixinatorClient.cfc +++ b/resources/cfml/modules/fixinator/models/fixinator/FixinatorClient.cfc @@ -255,7 +255,7 @@ component singleton="true" { payload = {"config"=element.config, "files"=[]}; } local.size+= local.fileInfo.size; - payload.files.append({"path":replace(local.f, element.baseDir, ""), "data":(local.ext == "jar") ? "" : fileRead(local.f), "sha1":fileSha1(local.f)}); + payload.files.append({"path":removeBasePathFromPath(element.baseDir, local.f), "data":(local.ext == "jar") ? "" : fileRead(local.f), "sha1":fileSha1(local.f)}); } } else { element.results.warnings.append( { "message":"Missing Read Permission", "path":local.f } ); @@ -452,7 +452,7 @@ component singleton="true" { public function filterPaths(baseDirectory, paths, config) { var f = ""; var ignoredPaths = ["/.git/","\.git\","/.svn/","\.svn\", ".git/", ".hg/", "/.hg/"]; - var ignoredExtensions = ["jpg","png","txt","pdf","dat", "doc","docx","gif","css","zip","bak","exe","pack","log","csv","xsl","xslx","psd","ai", "svg", "ttf", "woff", "ttf", "gz", "tar", "7z", "epub", "mobi", "ppt", "pptx", "swf", "fla", "flv", "m4v","mp3","mp4","DS_Store"]; + var ignoredExtensions = ["jpg","png","txt","pdf","dat", "doc","docx","gif","css","zip","bak","exe","pack","log","csv","xsl","xslx","psd","ai", "svg", "ttf", "woff", "ttf", "gz", "tar", "7z", "epub", "mobi", "ppt", "pptx", "swf", "fla", "flv", "m4v","mp3","mp4","DS_Store", "dll", "ico", "class"]; var filteredPaths = []; //always ignore git paths if (arguments.config.keyExists("ignorePaths") && arrayLen(arguments.config.ignorePaths)) { @@ -489,6 +489,17 @@ component singleton="true" { return filteredPaths; } + public function removeBasePathFromPath(basePath, path) { + arguments.basePath = normalizeSlashes(arguments.basePath); + arguments.path = normalizeSlashes(arguments.path); + if (findNoCase(arguments.basePath, arguments.path) == 1) { + return replaceNoCase(arguments.path, arguments.basePath, ""); + } else { + //basepath not found at beginning of path + return arguments.path; + } + } + public function fixCode(basePath, fixes, writeFiles=true) { var fix = ""; var basePathInfo = getFileInfo(arguments.basePath); @@ -582,13 +593,13 @@ component singleton="true" { local.filePositionOffset += ( len(fix.fix.fixCode) - len(fix.fix.replaceString) ); //throw(message="FPO:#local.filePositionOffset# FileContent:#local.fileContent#"); - + /* these appear to be left over debugging if (fix.fix.replaceString contains chr(13)) { throw(message="rs contains char(13)"); } if (fix.fix.replaceString contains chr(10)) { throw(message="rs contains char(13)"); - } + }*/ if (arguments.writeFiles) { fileWrite(local.filePath, local.fileContent);