Files
Thomas Vincent 926d5b66af security: fix SQL injection, buffer overflow, and input validation (#519)
## Summary

Fix five security issues found during code review:

1. **SQL injection via unescaped SNMP result in INSERT**
(`poller.c:1844`): `poller_items[i].result` and `rrd_name` flow directly
into SQL VALUES clause. Added `db_escape()` calls for both values before
interpolation.

2. **Buffer overflow in `buffer_output_errors`** (`poller.c:2047`):
`snprintf` used `DBL_BUFSIZE` as the size limit instead of the remaining
buffer space `DBL_BUFSIZE - *buf_size`, allowing a write past the end of
`error_string`.

3. **SQL injection via `--hostlist` CLI argument** (`spine.c:388`): The
`host_id_list` string is interpolated into SQL queries without
validation. Added input validation to reject any characters other than
digits, commas, and spaces.

4. **Undocumented command injection trust boundary** (`nft_popen.c:126`,
`poller.c:2245`): `nft_popen()` passes commands to `/bin/sh -c` without
shell escaping. Added warning comments documenting that callers must
ensure commands originate from the Cacti database.

5. **Unbounded `sprintf` calls in `util.c`** (lines 99, 141, 145, 191,
286, 2036): Replaced all 6 `sprintf(qstring, ...)` calls with
`snprintf(qstring, sizeof(qstring), ...)` to prevent buffer overflows.

## Files changed

- `poller.c` - escape SQL values (fix 1), bound snprintf (fix 2),
document trust boundary (fix 4)
- `spine.c` - validate --hostlist input (fix 3)
- `nft_popen.c` - document trust boundary (fix 4)
- `util.c` - replace sprintf with snprintf (fix 5)

## Test plan

- [x] `make clean && make` compiles without errors or warnings
- [ ] Run spine against a test Cacti instance with SNMP results
containing single quotes
- [ ] Run spine with `--hostlist "1; DROP TABLE"` and verify it exits
with error
- [ ] Verify poller output results are correctly escaped in the database

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-03-26 07:45:48 -04:00

71 lines
2.0 KiB
Groff

.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
.TH SPINE "1" "March 2026" "SPINE 1.3.0 Copyright 2004-2026 by The Cacti Group" "User Commands"
.SH NAME
SPINE \- Data Collector for Cacti
.SH SYNOPSIS
.B spine
[\fI\,options\/\fR] [[\fI\,firstid lastid\/\fR] \fI\,|| \/\fR[\fI\,-H/--hostlist='hostid1,hostid2,\/\fR...\fI\,,hostidn'\/\fR]]
.SH DESCRIPTION
SPINE 1.3.0 Copyright 2004\-2026 by The Cacti Group
.SH OPTIONS
.TP
\fB\-h\fR/\-\-help
Show this brief help listing
.TP
\fB\-f\fR/\-\-first=X
Start polling with host id X
.TP
\fB\-l\fR/\-\-last=X
End polling with host id X
.TP
\fB\-H\fR/\-\-hostlist=X
Poll the list of host ids, separated by comma's
.TP
\fB\-p\fR/\-\-poller=X
Set the poller id to X
.TP
\fB\-t\fR/\-\-threads=X
Override the database threads setting.
.TP
\fB\-C\fR/\-\-conf=F
Read spine configuration from file F
.TP
\fB\-O\fR/\-\-option=S:V
Override DB settings 'set' with value 'V'
.TP
\fB\-M\fR/\-\-mibs
Refresh the device System Mib data
.TP
\fB\-N\fR/\-\-mode=online
For remote pollers, the operating mode.
Options include: online, offline, recovery.
The default is 'online'.
.TP
\fB\-R\fR/\-\-readonly
Spine will not write output to the DB
.TP
\fB\-S\fR/\-\-stdout
Logging is performed to standard output
.TP
\fB\-P\fR/\-\-pingonly
Ping device and update device status only
.TP
\fB\-V\fR/\-\-verbosity=V
Set logging verbosity to <V>
.PP
Either both of \fB\-\-first\fR/\-\-last must be provided, a valid hostlist must be provided.
In their absence, all hosts are processed.
.SS "Without the --conf parameter, spine searches in order:"
.IP
current directory, /etc/, /etc/cacti/, ../etc/ for spine.conf.
.PP
Verbosity is one of NONE/LOW/MEDIUM/HIGH/DEBUG or 1..5
.PP
Runtime options are read from the 'settings' table in the Cacti
database, but they can be overridden with the \fB\-\-option\fR=\fI\,S\/\fR:V
parameter.
.PP
Spine is distributed under the Terms of the GNU Lesser
General Public License Version 2.1. (http://www.gnu.org/licenses/lgpl.txt)
For more information, see http://www.cacti.net