-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat: added support to mssql for execute query #6200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ import ( | |
|
||
_ "github.com/microsoft/go-mssqldb" | ||
"github.com/praetorian-inc/fingerprintx/pkg/plugins/services/mssql" | ||
"github.com/projectdiscovery/nuclei/v3/pkg/js/utils" | ||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate" | ||
) | ||
|
||
|
@@ -132,3 +133,53 @@ func isMssql(host string, port int) (bool, error) { | |
} | ||
return false, nil | ||
} | ||
|
||
// ExecuteQuery connects to MS SQL database using given credentials and executes a query. | ||
// It returns the results of the query or an error if something goes wrong. | ||
// @example | ||
// ```javascript | ||
// const mssql = require('nuclei/mssql'); | ||
// const client = new mssql.MSSQLClient; | ||
// const result = client.ExecuteQuery('acme.com', 1433, 'username', 'password', 'master', 'SELECT @@version'); | ||
// log(to_json(result)); | ||
// ``` | ||
func (c *MSSQLClient) ExecuteQuery(host string, port int, username, password, dbName, query string) (*utils.SQLResult, error) { | ||
if host == "" || port <= 0 { | ||
return nil, fmt.Errorf("invalid host or port") | ||
} | ||
if !protocolstate.IsHostAllowed(host) { | ||
// host is not valid according to network policy | ||
return nil, protocolstate.ErrHostDenied.Msgf(host) | ||
} | ||
|
||
target := net.JoinHostPort(host, fmt.Sprintf("%d", port)) | ||
|
||
connString := fmt.Sprintf("sqlserver://%s:%s@%s?database=%s&connection+timeout=30", | ||
url.PathEscape(username), | ||
url.PathEscape(password), | ||
target, | ||
dbName) | ||
|
||
db, err := sql.Open("sqlserver", connString) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer db.Close() | ||
|
||
db.SetMaxOpenConns(1) | ||
db.SetMaxIdleConns(0) | ||
|
||
rows, err := db.Query(query) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
Comment on lines
+180
to
+184
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add explicit rows.Close() to ensure proper resource cleanup. Although many SQL drivers automatically close rows when the connection is closed, it's a best practice to explicitly close the rows after they're no longer needed. This prevents resource leaks, especially in case of errors. rows, err := db.Query(query)
if err != nil {
return nil, err
}
+ defer rows.Close() |
||
data, err := utils.UnmarshalSQLRows(rows) | ||
if err != nil { | ||
if data != nil && len(data.Rows) > 0 { | ||
return data, nil | ||
} | ||
return nil, err | ||
} | ||
return data, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using parameterized queries for security.
The current implementation passes the query string directly to the database, which could potentially lead to SQL injection if the query contains user input. Consider adding a parameter validation mechanism or using parameterized queries.
📝 Committable suggestion