fix(client): fix security issues in adguardhome client (#4)

* fix(client): Check uint16 bounds for user provided port

see https://github.com/csfreak/adguard-exporter/security/code-scanning/4

* fix(client): add option to disable tls verification

defaults to false

see https://github.com/csfreak/adguard-exporter/security/code-scanning/3
This commit is contained in:
Jason Ross 2023-09-15 12:02:46 -05:00 committed by GitHub
parent 483435d1e9
commit 887ff4afea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 32 deletions

View File

@ -228,6 +228,9 @@ scrape_configs:
# Port to be used for the exporter # Port to be used for the exporter
-server_port string (optional) (default "9617") -server_port string (optional) (default "9617")
# Disable TLS verification
-insecure_tls_skip_verify bool (optional) (default "false")
``` ```
## Available Prometheus metrics ## Available Prometheus metrics

View File

@ -17,30 +17,32 @@ import (
// Config is the exporter CLI configuration. // Config is the exporter CLI configuration.
type Config struct { type Config struct {
AdguardProtocol string `config:"adguard_protocol"` AdguardProtocol string `config:"adguard_protocol"`
AdguardHostname string `config:"adguard_hostname"` AdguardHostname string `config:"adguard_hostname"`
AdguardUsername string `config:"adguard_username"` AdguardUsername string `config:"adguard_username"`
AdguardPassword string `config:"adguard_password"` AdguardPassword string `config:"adguard_password"`
AdguardPort string `config:"adguard_port"` AdguardPort string `config:"adguard_port"`
ServerPort string `config:"server_port"` ServerPort string `config:"server_port"`
Interval time.Duration `config:"interval"` Interval time.Duration `config:"interval"`
LogLimit string `config:"log_limit"` LogLimit string `config:"log_limit"`
RDnsEnabled bool `config:"rdns_enabled"` RDnsEnabled bool `config:"rdns_enabled"`
PasswordFromFile bool `config:"password_from_file"` PasswordFromFile bool `config:"password_from_file"`
InsecureTLSSkipVerify bool `config:"insecure_tls_skip_verify"`
} }
func getDefaultConfig() *Config { func getDefaultConfig() *Config {
return &Config{ return &Config{
AdguardProtocol: "http", AdguardProtocol: "http",
AdguardHostname: "127.0.0.1", AdguardHostname: "127.0.0.1",
AdguardUsername: "", AdguardUsername: "",
AdguardPassword: "", AdguardPassword: "",
AdguardPort: "80", AdguardPort: "80",
ServerPort: "9617", ServerPort: "9617",
Interval: 10 * time.Second, Interval: 10 * time.Second,
LogLimit: "1000", LogLimit: "1000",
RDnsEnabled: true, RDnsEnabled: true,
PasswordFromFile: false, PasswordFromFile: false,
InsecureTLSSkipVerify: false,
} }
} }

View File

@ -39,9 +39,9 @@ type Client struct {
} }
// NewClient method initializes a new AdGuard client. // NewClient method initializes a new AdGuard client.
func NewClient(protocol, hostname, username, password, adport string, interval time.Duration, logLimit string, rdnsenabled bool) *Client { func NewClient(protocol, hostname, username, password, adport string, interval time.Duration, logLimit string, rdnsenabled bool, insecuretls bool) *Client {
temp, err := strconv.Atoi(adport) temp, err := strconv.ParseInt(adport, 10, 16)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -56,7 +56,9 @@ func NewClient(protocol, hostname, username, password, adport string, interval t
interval: interval, interval: interval,
logLimit: logLimit, logLimit: logLimit,
httpClient: http.Client{ httpClient: http.Client{
Transport: &http.Transport{TLSClientConfig: GetTlsConfig()}, Transport: &http.Transport{TLSClientConfig: &tls.Config{
InsecureSkipVerify: insecuretls,
}},
CheckRedirect: func(req *http.Request, via []*http.Request) error { CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse return http.ErrUseLastResponse
}, },
@ -263,12 +265,6 @@ func (c *Client) authenticateRequest(req *http.Request) {
req.SetBasicAuth(c.username, c.password) req.SetBasicAuth(c.username, c.password)
} }
func GetTlsConfig() *tls.Config {
return &tls.Config{
InsecureSkipVerify: true,
}
}
func isValidIp(ip string) bool { func isValidIp(ip string) bool {
if net.ParseIP(ip) == nil { if net.ParseIP(ip) == nil {
return false return false

View File

@ -26,14 +26,14 @@ func main() {
metrics.Init() metrics.Init()
initAdguardClient(conf.AdguardProtocol, conf.AdguardHostname, conf.AdguardUsername, conf.AdguardPassword, conf.AdguardPort, conf.Interval, conf.LogLimit, conf.RDnsEnabled) initAdguardClient(conf.AdguardProtocol, conf.AdguardHostname, conf.AdguardUsername, conf.AdguardPassword, conf.AdguardPort, conf.Interval, conf.LogLimit, conf.RDnsEnabled, conf.InsecureTLSSkipVerify)
initHttpServer(conf.ServerPort) initHttpServer(conf.ServerPort)
handleExitSignal() handleExitSignal()
} }
func initAdguardClient(protocol, hostname, username, password, port string, interval time.Duration, logLimit string, rdnsenabled bool) { func initAdguardClient(protocol, hostname, username, password, port string, interval time.Duration, logLimit string, rdnsenabled bool, insecuretls bool) {
client := adguard.NewClient(protocol, hostname, username, password, port, interval, logLimit, rdnsenabled) client := adguard.NewClient(protocol, hostname, username, password, port, interval, logLimit, rdnsenabled, insecuretls)
go client.Scrape() go client.Scrape()
} }