Skip to content

Introduction of custom function calling support from within the Yaml based checkers. #222

@unnxt30

Description

@unnxt30

Currently, the YAML-based checkers rely heavily on Tree-sitter pattern matching. However, this approach can be limiting in cases that require taint analysis, and other custom rules that require customization.
A better solution would be to enable passing the values captured by Tree-sitter queries to our custom Go-based analyzers, which can then handle the reporting logic.

A prototypic example:

  • For Code example
function getUserInput(key) {

    return document.getElementById(key).value;

}

userInput = getUserInput('username')

// A sink method, which performs some raw databse operation on the userInput
perform_db_operation(userInput)
  • Yaml checker format with custom Function for taint :
name: "run_taint_analysis"
language: javascript
description: "Runs a taint analysis on the provided function and its parameters."
analysisFunction:
  name: taint
  parameters:
    sources: |
         (call_expression
            function: (identifier) @sourceName 
              (#eq? @sourceName "getUserInput"))
    sinks: |
         (call_expression
               function: (identifier) @sinkName
                  (#eq? @sinkName "perform_db_operation"))
  • This YAML checker, in turn, will have a new function signature for the analysisFunction field, which returns an internal Go-based taint analyzer using the Run field.
type AnalysisFunction struct {
	Name 	  string
	Parameters []reflect.Type
	Description string
	Run func(args ...interface{}) (interface{}, error)
}

TaintAnalysisFunction := AnalysisFunction{
	Name: "taint",
	Parameters: []reflect.Type{
		reflect.TypeOf([]string), // sources
		reflect.TypeOf([]string), // sinks
	},
	Description: "Runs a taint analysis on the provided function and its parameters.",
	Run: func(args ...interface{}) (Analyzer, error) {
		sources := args[0].([]string)
		sinks := args[1].([]string)

		analyzer := NewTaintAnalyzer(sources, sinks)
		return analyzer, nil
	}
}

func NewTaintAnalyzer(sources, sinks []string) Analyzer {

        // Internal Go-based analyzer
	return &TaintAnalyzer{
		Sources: sources,
		Sinks:   sinks,
	}
}

This approach will make the YAML analyzer architecture more robust by targeting specific edge cases and enabling the easy development of custom analyzers without the need for writing code-heavy Go-based implementations.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions