SAST Autofix
Tags: sast, security, programming, go
Published: 2022-11-24 22:55:53

## Intro
I believe in automation. That's not very revealing, neither bold, statement, as for 2022. 

But most tooling from security world does not include any kind of automation, or, to make it worse, do it unnecessary complicated. Especially fixing findings from static application security testing tools (SAST), shouldn't be much of a hassle. After all, it is operating on finding the patterns, or exact matches in the code. 

That got me thinking: is it possible to make simple fixing rules. And I am delighted to say, I've found one! Without further due, the tool in question is: `sed`

## Idea
The high level idea is: in the CI/CD job, when vulnerable part of the code is found, the fix, if available, can be applied, and the vulnerability no longer exist in the code. And all that with simple sed command. 

If you do not recall what the sed is
> sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). 

As it seems to be too good to be true - let's examine the functionality of the `sed`, and how we could potentially used it against vulnerable code.

## Execution
The `sed` with `s` command, recognised as substitution, is able to change occurrences of matching regex into something else. 

### First: `s` into `http`
Starting with simple `test.sh` file: 
```
curl http://internal.eks-asdf.com/asdf 
curl https://internal.eks-asdf.com/asdf
``` 
Let's start with simple scenario: we would love to enforce all scripts to communicate, using `https`, rather than `http` to internal EKS address. To achieve that, we could embedded simple job, that changes all occurrences, in all, bash files: 
```
sed 's+http://internal.eks-asdf.com+https://internal.eks-asdf.com/asdf+g' test.sh
```
The sed command simply states, that `http://internal.eks-asdf.com` should be replaced with `https://internal.eks-asdf.com/asdf`, for all occurrences in file.

As we could argue if this example is more associated with migrating from http to https (which is security 'thing'), the fact is, it worked. 

### Second: SQLi 
Going to more security related scenarios: using recommendation from the golang recommendation: https://go.dev/doc/database/sql-injection we can use following rule to remove `fmt.Sprintf` and change all `%s` into `?` - change assembly of statement as string into actual query.
Having following part of code:
```
rows, err := db.Query(fmt.Sprintf("SELECT * FROM user WHERE id = %s", id))
```
And using our 'autofix':

```
sed 's+(fmt.Sprintf++g;s+%s+?+g;s+.$++g' test.go
```
Command is combined: removing `(fmt.Sprintf`, exchanging `%s` with `?` and removing last char `.$` (which should be the latest `)` character).

We will end with that code, the output will be, valid, and working go sql query:
```
rows, err := db.Query("SELECT * FROM user WHERE id = ?", id)
```
It is way more approachable rule than I could imagine: it works for query with multiple parameters, it's self-explanatory, and make everything better. 

## Usability 
Is it possible to implement it user friendly way, into security job? Starting from beginning, `sed` package can work with configuration file, called `Scripts`, that stores multiple substitute commands. And it should be possible to write multiple rules for each language, with ease. 

Are presented 'rules' optimal? It depends, probably not, but the concept is very appealing to me - the opposite is to change it manually. Or not changing it at all.

It is also very easy, to incorporate it as a job, into pipelines - it should be very appealing concept to everyone. 

## Outro
I am not saying that you should ditch your sast tooling in the CI/CD pipelines, in favour of ‘sed’. Treat this post as proof of concept of ‘Autofix on cheap’. 

## Semgrep
It's well thought SAST solution, with great 'user base' and amazing features, and one of them is the automated fixing of the vulnerabilities. It is in the experimental phase, so you can try it yourself.

## Links
https://www.nongnu.org/bibledit/sed_rules_reference.html
https://semgrep.dev/docs/