Files
cariddi/pkg/scanner/error.go
T
2026-02-16 10:11:43 +01:00

184 lines
5.2 KiB
Go

/*
==========
Cariddi
==========
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
@Repository: https://github.com/edoardottt/cariddi
@Author: edoardottt, https://edoardottt.com
@License: https://github.com/edoardottt/cariddi/blob/main/LICENSE
*/
package scanner
import (
"regexp"
"sync"
)
// Error struct.
// ErrorName = the name that identifies the error.
// Regex = The regular expression to be matched.
type Error struct {
ErrorName string
Regex regexp.Regexp
}
// ErrorMatched struct.
// Error = Error struct.
// Url = url in which the error is found.
// Match = the string matching the regex.
type ErrorMatched struct {
Error Error
URL string
Match string
}
var (
errors []Error //nolint: gochecknoglobals
onceErrors sync.Once //nolint: gochecknoglobals
)
// GetErrorRegexes returns all the error structs.
func GetErrorRegexes() []Error {
onceErrors.Do(func() {
errors = []Error{
{
"PHP error",
*regexp.MustCompile(`(?i)(php (warning|error)` +
`|include_path` +
`|undefined (variable|index)` +
`|expect(s*) parameter [A-Za-z0-9-_]{1,30}` +
`|call to undefined method` +
`|failed to open stream` +
`|cannot modify header information` +
`|(syntax|parse|fatal) error` +
`|safe mode restriction in effect` +
`|uncaught exception)`),
},
{
"ASP.Net error",
*regexp.MustCompile(`(?i)(\"Message\"\:\"Invalid web service call` +
`|\-\-\- End of inner exception stack trace \-\-\-` +
`|Syntax error in string in query expression)`),
},
{
"Python error",
*regexp.MustCompile(`(?i)(Traceback \(most recent call last\)\:` +
`|\(generated by waitress\)` +
`|Syntax error in string in query expression)`),
},
{
"General error",
*regexp.MustCompile(`(?i)(fatal|critical|severe|high|medium|low) error`),
},
{
"Debug information",
*regexp.MustCompile(`(?i)(Debug trace|stack trace\:)`),
},
{
"MySQL error",
*regexp.MustCompile(`(?i)(valid MySQL result` +
`|check the manual that (fits|corresponds to) your MySQL server version` +
`|MySQLSyntaxErrorException` +
`|MySqlException` +
`|MySql error` +
`|Unknown column ` +
`|SQL syntax.*?MySQL` +
`|Warning.*?mysqli?` +
`|com\.mysql\.jdbc` +
`|Zend_Db_(Adapter|Statement)_Mysqli_Exception` +
`|Syntax error or access violation)`),
},
{
"MariaDB error",
*regexp.MustCompile(`(?i)(check the manual that (fits|corresponds to) your MariaDB server version` +
`|MariaDB error)`),
},
{
"PostgreSQL error",
*regexp.MustCompile(`(?i)(valid PostgreSQL result` +
`|PG::SyntaxError:` +
`|PSQLException` +
`|PostgreSQL query failed` +
`|ERROR: parser: parse error at or near` +
`|PostgreSQL error` +
`|PostgreSQL.*?ERROR` +
`|Warning.*?\\Wpg_` +
`|Npgsql\.` +
`|org\.postgresql\.util\.PSQLException` +
`|ERROR:\s\ssyntax error at or near` +
`|org\.postgresql\.jdbc)`),
},
{
"MSSQL error",
*regexp.MustCompile(`(?i)(Microsoft SQL error` +
`|Microsoft SQL Native Client error` +
`|ODBC SQL Server Driver` +
`|Unclosed quotation mark after the character string` +
`|SQLServer JDBC Driver` +
`|Driver.*? SQL[\-\_\ ]*Server` +
`|OLE DB.*? SQL Server` +
`|\bSQL Server[^<"]+Driver|Warning.*?\W(mssql|sqlsrv)_` +
`|\bSQL Server[^<"]+[0-9a-fA-F]{8}` +
`|System\.Data\.SqlClient\.SqlException` +
`|Exception.*?\bRoadhouse\.Cms\.` +
`|\[SQL Server\]` +
`|ODBC Driver \d+ for SQL Server` +
`|com\.jnetdirect\.jsql` +
`|macromedia\.jdbc\.sqlserver` +
`|Zend_Db_(Adapter|Statement)_Sqlsrv_Exception` +
`|com\.microsoft\.sqlserver\.jdbc` +
`|SQL(Srv|Server)Exception` +
`|Cannot initialize the data source object of OLE DB provider)`),
},
{
"OracleDB error",
*regexp.MustCompile(`(?i)(\bORA-\d{5}|Oracle error|Oracle.*Driver|Warning.*\Woci_.*|Warning.*\Wora_.*)`),
},
{
"IBMDB2 error",
*regexp.MustCompile(`(?i)(CLI Driver.*DB2|DB2 SQL error|\bdb2_\w+\(|SQLSTATE.+SQLCODE)`),
},
{
"SQLite error",
*regexp.MustCompile(`(?i)(SQLite\/JDBCDriver` +
`|SQLite.Exception` +
`|System.Data.SQLite.SQLiteException` +
`|Warning.*sqlite_.*` +
`|Warning.*SQLite3::` +
`|\[SQLITE_ERROR\])`),
},
}
})
return errors
}
// RemoveDuplicateErrors removes duplicates from Errors found.
func RemoveDuplicateErrors(input []ErrorMatched) []ErrorMatched {
keys := make(map[string]bool)
list := []ErrorMatched{}
for _, entry := range input {
if _, value := keys[entry.Match+entry.URL]; !value {
keys[entry.Match+entry.URL] = true
list = append(list, entry)
}
}
return list
}