Pest
:beetle: Primitive Erlang Security Tool
Install / Use
/learn @okeuday/PestREADME
Primitive Erlang Security Tool (PEST)
CVEs: Erlang OpenSSL LibreSSL PCRE zlib asmjit ryu
Do a basic scan of Erlang source code and report any function calls that may cause Erlang source code to be insecure.
The tool is provided in the form of an escript (an Erlang script) which may
also be used as a module. Usage of the script is provided with the -h
command line argument, with the output shown below:
Usage pest.erl [OPTION] [FILES] [DIRECTORIES]
-b Only process beam files recursively
-c Perform internal consistency checks
-d DEPENDENCY Expand the checks to include a dependency
(provide the dependency as a file path or directory)
-D IDENTIFIER Expand the checks to include a dependency from an identifier
-e Only process source files recursively
-E IDENTIFIER Erase data associated with a dependency identifier
-h List available command line flags
-i Display checks information after expanding dependencies
-L List available dependency identifiers
-m APPLICATION Display a list of modules in an Erlang/OTP application
-p DIRECTORY Append a directory on the code server's search path list
-r Recursively search directories
-s SEVERITY Set the minimum severity to use when reporting problems
(default is 50)
-U COMPONENT Update local data related to a component
(valid components are: crypto, pest/dependency/IDENTIFIER)
-v Verbose output (set the minimum severity to 0)
-V [COMPONENT] Print version information
(valid components are: pest, crypto)
Erlang/OTP version 21.0 and higher is required.
If beam files are used, they must have been compiled with the debug_info
option to provide the abstract_code used by pest.erl. However, pest.erl
also consumes Erlang source code, including Erlang source escript files.
If beam files are available, it is best to use the beam files with pest.erl
due to how the Erlang compiler preprocessor and optimizations can influence
function calls.
Please feel free to contribute! To add security problems to the scan insert information into the list of checks.
Usage
To scan any .beam files in a lib directory recursively, use:
./pest.erl -b /path_to_somewhere/lib
If you want to see all possible checks,
just turn on the verbose output with -v:
./pest.erl -vb /path_to_somewhere/lib
To check version information related to Erlang/OTP crypto, use:
./pest.erl -V crypto
To do a slower scan that includes indirect function calls from Erlang/OTP (as described in Indirect Security Concerns in Erlang/OTP and Elixir), use:
./pest.erl -vb -d /erlang_install_prefix/lib/erlang/lib/ /path_to_somewhere/lib
Determining checks that include all indirect function calls for Erlang/OTP 23 can take several minutes, so it is easier to use cached results. The checks have already been cached for Erlang/OTP 23.2.3, which can be used to obtain the same output with:
./pest.erl -vb -D ErlangOTP/23.2.3 /path_to_somewhere/lib
If beam files created by an Elixir project need to be checked, the following command line could be used:
./pest.erl -vb -D ErlangOTP/23.2.3 -D Elixir/1.11.3/23.2.3 -p ~/installed/lib/elixir/lib/elixir/ebin /path_to_somewhere/lib
The Elixir installation directory beam file path needs to be added to the
code search path for accessing an Elixir project's beam files
(the command line above is using the path
~/installed/lib/elixir/lib/elixir/ebin).
Test
To have pest.erl check itself, use:
./pest.erl -vc -D ErlangOTP/23.2.3 ./pest.erl
Indirect Security Concerns in Erlang/OTP
Usage of various Erlang/OTP dependencies can have their own security concerns which Erlang source code may depend on indirectly. To provide a representation of security concerns related to Erlang/OTP dependencies, the pest.erl script was ran on all of the beam files installed for Erlang/OTP 23.2.3, with the result provided below:
$ ./pest.erl -vb ~/installed/lib/erlang/lib/
90: Port Drivers may cause undefined behavior
erl_ddll.beam:153 (erl_ddll:try_load/3)
megaco_flex_scanner.beam:91 (erl_ddll:load_driver/2)
dbg.beam:[440,447,478,485] (erl_ddll:load_driver/2)
wxe_master.beam:125 (erl_ddll:load_driver/2)
90: NIFs may cause undefined behavior
asn1rt_nif.beam:[58,70] (erlang:load_nif/2)
crypto.beam:[2541,2554] (erlang:load_nif/2)
erl_tracer.beam:36 (erlang:load_nif/2)
prim_buffer.beam:48 (erlang:load_nif/2)
prim_file.beam:103 (erlang:load_nif/2)
prim_net.beam:112 (erlang:load_nif/2)
prim_socket.beam:371 (erlang:load_nif/2)
zlib.beam:115 (erlang:load_nif/2)
dyntrace.beam:[84,96] (erlang:load_nif/2)
80: OS process creation may require input validation
prim_inet.beam:93 (erlang:open_port/2)
ram_file.beam:400 (erlang:open_port/2)
megaco_flex_scanner.beam:116 (erlang:open_port/2)
os_mon.beam:[89,95] (erlang:open_port/2)
15: Keep OpenSSL updated for crypto module use (run with "-V crypto")
ct_config.beam:[596,605,635,639] (crypto:_/_)
ct_make.beam:285 (compile:file/2)
ct_netconfc.beam:[1992,2065] (ssh:_/_)
ct_netconfc.beam:[1024,2010,2012,2020,2023,2046,2055] (ssh_connection:_/_)
ct_slave.beam:280 (ssh:_/_)
ct_slave.beam:[281,283,287] (ssh_connection:_/_)
ct_snmp.beam:[259,291,463,479,494,510,525,540,555,571] (snmp_config:_/_)
ct_snmp.beam:[226,229] (snmpa:_/_)
ct_snmp.beam:[97,102,110,111,347,371,379,384,390,395] (snmpm:_/_)
ct_ssh.beam:443 (crypto:_/_)
ct_ssh.beam:[444,447,719] (ssh:_/_)
ct_ssh.beam:[474,479,487,502,505,524,532,545,553,737,742] (ssh_connection:_/_)
ct_ssh.beam:[449,468,562,568,574,580,586,592,598,604,610,616,622,628,634,640,646,652,658,664,670,676,682,688,694,700,706,723] (ssh_sftp:_/_)
compile.beam:[1590,1606,1608] (crypto:_/_)
crypto.beam:[1643,1722,2443] (crypto:_/_)
crypto.beam:[2724,2729,2775] (crypto_ec_curves:_/_)
crypto_ec_curves.beam:6 (crypto:_/_)
dialyzer_cl.beam:563 (compile:file/2)
dialyzer_utils.beam:99 (compile:noenv_file/2)
diameter_tcp.beam:[198,721,723,844,846,892,901] (ssl:_/_)
eldap.beam:[513,585,625,963,1012,1017,1131,1133] (ssl:_/_)
ftp.beam:[1599,2203,2221,2253,2302,2426,2429,2434] (ssl:_/_)
http_transport.beam:[110,180,215,236,257,290,338,357,380,413,496] (ssl:_/_)
httpc_handler.beam:1661 (ssl:_/_)
httpd_script_env.beam:66 (ssl:_/_)
hdlt_client.beam:211 (crypto:_/_)
hdlt_client.beam:212 (ssl:_/_)
hdlt_ctrl.beam:196 (crypto:_/_)
hdlt_ctrl.beam:[198,302,421,992,1008] (ssh:_/_)
hdlt_ctrl.beam:[295,330,336,342,353,366,415,444,450,456,471,985,1003,1012,1014,1020,1024,1026,1438,1458,1474,1485,1494] (ssh_sftp:_/_)
hdlt_server.beam:149 (crypto:_/_)
hdlt_server.beam:150 (ssl:_/_)
hdlt_slave.beam:[153,221,226] (ssh:_/_)
hdlt_slave.beam:[165,176] (ssh_connection:_/_)
net_kernel.beam:1753 (crypto:_/_)
OTP-PUB-KEY.beam:[1822,2101,2149,2230,2278,2439,2487,2924,2972,3019,3067,3114,3162,8644,8704,8848,8898,9354,9402,9431,9479,9653,9701,9730,9778,9807,9855,10016,10076,10151,10201,10306,10383,10466,10512,10636,10673,16767,16828,16885,16927,16984,17037,17062,17104,17190,17238,17327,17375,17508,17534,17579,17616,17747,17789] ('OTP-PUB-KEY':_/_)
PKCS-FRAME.beam:[200,412,441,512,553,604,633,704,745,893,922,1044,1085,1144,1203,1295,1366,1412,1537,1714,1805] ('PKCS-FRAME':_/_)
pubkey_cert.beam:618 ('OTP-PUB-KEY':_/_)
pubkey_cert.beam:1315 (crypto:_/_)
pubkey_cert.beam:1137 (pubkey_cert:_/_)
pubkey_cert.beam:[80,1319] (pubkey_cert_records:_/_)
pubkey_cert.beam:[537,542,565,608,610,613,1161,1288,1293,1309,1393,1396,1398,1400,1406] (public_key:_/_)
pubkey_cert_records.beam:[40,231,244,289,303] ('OTP-PUB-KEY':_/_)
pubkey_crl.beam:586 ('OTP-PUB-KEY':_/_)
pubkey_crl.beam:[43,71,86,318,334,421,431,483,503,644,655,681] (pubkey_cert:_/_)
pubkey_crl.beam:[287,316,332,344,383,388,391,399,705,710] (pubkey_cert_records:_/_)
pubkey_crl.beam:[220,234,245,485,571,573,581,668,670,672] (public_key:_/_)
pubkey_ocsp.beam:[223,336,338] (crypto:_/_)
pubkey_ocsp.beam:[72,129,148,192,193,221,235,234,237,245,256,270,272,297,333] (public_key:_/_)
pubkey_pbe.beam:[163,189,192,195,198,201,205,211] ('PKCS-FRAME':_/_)
pubkey_pbe.beam:[42,45,48,51,54,57,66,69,72,75,78,81,92,151,157,186,261] (crypto:_/_)
pubkey_pem.beam:[80,90,162,166] (pubkey_pbe:_/_)
pubkey_pem.beam:[161,167] (public_key:_/_)
pubkey_ssh.beam:[464,481
Related Skills
healthcheck
342.5kHost security hardening and risk-tolerance configuration for OpenClaw deployments
node-connect
342.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
prose
342.5kOpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.
frontend-design
85.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.


