Building a Cargo.toml scanner for Rust
New fresh rusty updates
So we wanted to make a command line version of rust.firosolutions.com for
quickly being able to check and validate current crate(/library) versions
in the Cargo.toml file.
So when building a rust project we could simply validate the external crate(’s)
versions.
Because running with = “*” where the version is equal to just get the latest version is dangerous
and will mostly break things in the future, luckily we could
just run cargo search to grab the latest version from crates.io.
We added /apiadd which takes json as input and the url of the Cargo.toml file as
a json key, So it can look like:
>>>
>>> aa = requests.get('https://rust.firosolutions.com/apiadd', json={'urllink':'https://raw.githubusercontent.com/FiroSolutions/vuln_rust/master/Cargo.toml'})
>>> aa.text
'{"pasteid":"cVQGCgcBYXoftYSGNWjzd84vAvmVMCkZPbQiGSHGmmg"}\n'
or use curl:
$ curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"urllink":"https://raw.githubusercontent.com/FiroSolutions/vuln_rust/master/Cargo.toml"}' https://rust.firosolutions.com/apiadd
then it returns a paste id that we can go to https://rust.firosolutions.com/paste/
to view it in a regular browser like if you where just using the site as regularly. In order for you to integrate it in to your applications we added support so you
can get the response in a json back instead of html by just adding /jsonresponse
to the url.
An example of this would be:
https://rust.firosolutions.com/paste/uoXgZ9hRqXh7798F0UCMpCFYnYEzqf6iGlSGqYCgdc/jsonresponse
Hacking together a script
rust python script
We summoned our inner spaghetti coder and wrote a script in python :)
$ cat checklibs.py
#python >=3.6
import requests, json
import os, sys
from subprocess import Popen, PIPE, STDOUT
print('Checking Cargo.toml')
#check if file is here
print('Uploading Cargo.toml')
command = "cat Cargo.toml | nc termbin.com 9999"
fluff = Popen(command, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
link = fluff.stdout.read()#b'https://termbin.com/7a3u\n\x00'
link = link.decode().split('\n')[0]
aa = requests.get('https://rust.firosolutions.com/apiadd', json={'urllink':link})
print('Result:')
for x in json.loads(requests.get("https://rust.firosolutions.com/paste/{}/jsonresponse".format(json.loads(aa.text).get('pasteid'))).text).get('libs'):
if len(x)==4:
print('\033[1;31m Found a vulnerability for {} \033[0;0m'.format(x[0]))
print('\033[0;92m Description: \033[0;0m')
print(x[3].get(list(x[3].keys())[0]).get('description'))
print("Link:", x[3].get(list(x[3].keys())[0]).get('link'))
else:
print("Library:",x[0], 'Your Version:', x[1], 'Latest Version', x[2])
print('View result on:')
print('https://rust.firosolutions.com/paste/{}/jsonresponse'.format(json.loads(aa.text).get('pasteid')))
Sidenote termbin.com:
While looking for a alternative to dpaste.com that:
- 0: is a paste service
- 1: supports syntax highlighting
- 2: can be used from the command line
Scratch syntax highlighting(feature request if you read this termbin) and we
cherry picked termbin.
Which lets simply upload a file using netcat.
Normally we love dpaste.com as our main paste tool(which do in fact support syntax highlighting).
Feature requests are welcome :)
Our github app
We have a github application which continuously scans your Cargo.toml file
and creates an issue if you are using a crate with a bad version
Link:
https://blog.firosolutions.com/2019/09/github-rust-firo/
Cifiro
If you wanna do more cool thing we have another python script called Cifiro
which you can use together with Jenkins! You find it on our github linked bellow.
Links:
https://en.wikipedia.org/wiki/Jenkins_(software)
https://rust.firosolutions.com
https://github.com/firosolutions
https://vulns.firosolutions.com
https://blog.firosolutions.com/2020/04/cargo-scanner-updates/