diff --git a/rules/go/gorilla/cookie_missing_http_only.yml b/rules/go/gorilla/cookie_missing_http_only.yml index 3c89e1248..44f9083ec 100644 --- a/rules/go/gorilla/cookie_missing_http_only.yml +++ b/rules/go/gorilla/cookie_missing_http_only.yml @@ -37,52 +37,29 @@ languages: - go metadata: description: Missing HTTP Only option in cookie configuration - remediation_message: | + remediation_message: |- ## Description - When set to "true", the "HttpOnly" attribute protects the cookie value from being accessed by client side JavaScript such as reading the "document.cookie" values. - By enabling this protection, a website that is vulnerable to Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing the cookie value from JavaScript. - - It's essential to configure cookie security options properly, especially when using session management libraries like Gorilla Sessions in Go. + The absence of the "HttpOnly" attribute in cookie settings leaves the cookie vulnerable to being accessed by client-side JavaScript, such as through "document.cookie". This vulnerability is particularly concerning for websites susceptible to Cross-Site Scripting (XSS) attacks, as it allows malicious scripts to read the cookie value. Properly configuring the "HttpOnly" attribute is a critical step in securing cookies, especially for session management. ## Remediations - To ensure that cookies, particularly session cookies, are secure: - - ✅ Configure HttpOnly - - Set the `HttpOnly` attribute to `true` within the Gorilla Sessions cookie store. This prevents client-side scripts from accessing the cookie data, reducing XSS attack risks. - - ```go - import ( - "github.com/gorilla/sessions" - "net/http" - ) - - var store = sessions.NewCookieStore([]byte("your-secret-key")) - - func MyHandler(w http.ResponseWriter, r *http.Request) { - // Get a session. We're ignoring the error resulted from decoding an - // existing session: Get() always returns a session, even if empty. - session, _ := store.Get(r, "session-name") - // Set some session values. - session.Values["foo"] = "bar" - // Set the session to be HttpOnly. - session.Options.HttpOnly = true - // Save changes. - session.Save(r, w) - } - ``` - - ✅ Leverage Gorilla SecureCookie - - Utilize the encoding/decoding capabilities of Gorilla's SecureCookie to securely store session data. - - ✅ Implement Strong Session Management - - Use Gorilla's session management features to create, renew, and expire sessions in a secure manner, preventing session fixation and other session-related attacks. - - ## Resources + - **Do** set the `HttpOnly` attribute to `true` for cookies, especially session cookies, to prevent them from being accessed by client-side scripts. This is a key measure in mitigating the risk of XSS attacks. + ```go + func MyHandler(w http.ResponseWriter, r *http.Request) { + session, _ := store.Get(r, "session-name") + ... + session.Options.HttpOnly = true + session.Save(r, w) + } + ``` + - **Do** use Gorilla SecureCookie for encoding and decoding session data securely. This method provides an additional layer of security for session information. + ```go + var s = sessions.NewCookieStore([]byte("your-secret-key")) + ``` + - **Do** implement robust session management with Gorilla Sessions. Proper session management helps prevent attacks related to session fixation and enhances overall session security. + + ## References - [Gorilla Sessions Documentation](http://www.gorillatoolkit.org/pkg/sessions) - [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html) diff --git a/rules/go/gorilla/insecure_cookie.yml b/rules/go/gorilla/insecure_cookie.yml index c0a314461..95ffa367d 100644 --- a/rules/go/gorilla/insecure_cookie.yml +++ b/rules/go/gorilla/insecure_cookie.yml @@ -37,31 +37,29 @@ languages: - go metadata: description: "Missing Secure option in cookie configuration" - remediation_message: | + remediation_message: |- ## Description - When set to "true", the "Secure" attribute ensures that a client will only send the cookie to the server when HTTPS is being used. - This prevents the cookie from being observed by unauthorized third parties. - - It's essential to configure cookie security options properly, especially when using session management libraries like Gorilla Sessions in Go. + The Secure attribute in cookie configuration is crucial for protecting cookies from unauthorized third-party access. When set to "true," it ensures cookies are only sent over HTTPS, safeguarding the data during transmission. ## Remediations - To ensure that cookies, particularly session cookies, are secure: - - ✅ Set Secure Flag - - If your site is served over HTTPS, also set the `Secure` flag on the cookie to ensure it's transmitted over secure channels only. - - ✅ Leverage Gorilla SecureCookie - - Utilize the encoding/decoding capabilities of Gorilla's SecureCookie to securely store session data. - - ✅ Implement Strong Session Management - - Use Gorilla's session management features to create, renew, and expire sessions in a secure manner, preventing session fixation and other session-related attacks. + - **Do** set the Secure flag for cookies if your site uses HTTPS. This action restricts cookies to secure channels, enhancing their security. + ```go + http.SetCookie(w, &http.Cookie{ + Name: "session_token", + Value: sessionToken, + Secure: true, + HttpOnly: true, + }) + ``` + - **Do** use Gorilla SecureCookie for encoding and decoding session data securely. This method provides an additional layer of security for session information. + ```go + var s = sessions.NewCookieStore([]byte("your-secret-key")) + ``` + - **Do** implement robust session management with Gorilla Sessions. Proper session management helps prevent attacks related to session fixation and enhances overall session security. - ## Resources + ## References - [Gorilla Sessions Documentation](http://www.gorillatoolkit.org/pkg/sessions) - [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html) diff --git a/rules/go/gosec/blocklist/cgi.yml b/rules/go/gosec/blocklist/cgi.yml index 701910652..6f2df5f3e 100644 --- a/rules/go/gosec/blocklist/cgi.yml +++ b/rules/go/gosec/blocklist/cgi.yml @@ -9,48 +9,23 @@ languages: - go metadata: description: Usage of vulnerable CGI package - remediation_message: | + remediation_message: |- ## Description - Using the `net/http/cgi` package in Go, especially with versions prior to 1.6.3, exposes the application to the Httpoxy attack, a vulnerability identified as CVE-2016-5386. This vulnerability arises from the way CGI and FastCGI protocols handle certain environment variables, which can be manipulated to intercept and redirect outgoing HTTP requests made by the web application. + The `net/http/cgi` package in Go versions before 1.6.3 is vulnerable to the Httpoxy attack. This vulnerability, identified as CVE-2016-5386, occurs because of how CGI and FastCGI protocols manage certain environment variables. Attackers can exploit this to intercept and redirect outgoing HTTP requests from the web application. ## Remediations - ✅ Update Go Version + - **Do** update your Go version to 1.6.3 or later to mitigate this vulnerability. + - **Do** opt for alternative packages, like the standard `net/http` library, for handling HTTP requests that do not use the CGI protocol. + - **Do not** use the `net/http/cgi` package if your Go version is older than 1.6.3, as it is vulnerable to the Httpoxy attack. + ```go + import "net/http/cgi" + ``` + - **Do** ensure that environment variables like `HTTP_PROXY` are not unintentionally exposed, as this can be leveraged for Httpoxy attacks. - Ensure you are using a version of Go that is 1.6.3 or later, where this vulnerability is patched. + ## References - ```sh - # Check Go version and update if necessary - go version - # Follow Go's update instructions if your version is < 1.6.3 - ``` - - ✅ Use Alternative Packages - - Refrain from using CGI where possible. Utilize alternative packages and methods to handle HTTP requests which do not rely on the CGI protocol. - - ```go - // Use the standard net/http package instead - import "net/http" - ``` - - ❌ Don't Use `net/http/cgi` in Older Versions - - Do not use the `net/http/cgi` package if you are operating on Go versions older than 1.6.3 as they are susceptible to the Httpoxy vulnerability. - - ```go - // This import is vulnerable to Httpoxy in Go < 1.6.3 - import "net/http/cgi" - ``` - - ❌ Avoid Exposing Environment Variables - - Ensure that the environment variables such as `HTTP_PROXY` are not being exposed unintentionally, as this can be leveraged for Httpoxy attacks. - - ## Resources - - - [CVE-2016-5386 Detail](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5386) - [Httpoxy.org](https://httpoxy.org/) cwe_id: diff --git a/rules/go/gosec/blocklist/des.yml b/rules/go/gosec/blocklist/des.yml index b9e2df06b..027a06da4 100644 --- a/rules/go/gosec/blocklist/des.yml +++ b/rules/go/gosec/blocklist/des.yml @@ -9,64 +9,17 @@ languages: - go metadata: description: "Import of weak encryption algorithm (DES)" - remediation_message: | + remediation_message: |- ## Description - The Data Encryption Standard (DES) is an outdated symmetric-key algorithm for encryption. Officially deemed insecure and no longer recommended for use, DES was withdrawn by the National Institute of Standards and Technology (NIST) as a standard in 2005, primarily because of its 56-bit key size, which is vulnerable to brute-force attacks. + The Data Encryption Standard (DES) is an outdated encryption algorithm that is officially considered insecure and is no longer recommended for use. DES was withdrawn as a standard by the National Institute of Standards and Technology (NIST) in 2005 because of its 56-bit key size which makes it susceptible to brute-force attacks. - ## Remediation + ## Remediations - To ensure the confidentiality and integrity of sensitive data, it is crucial to utilize a modern and secure encryption algorithm. The use of Advanced Encryption Standard (AES) with a key size of 256 bits (AES-256) is recommended for its strong security properties and widespread acceptance as a replacement for DES. + - **Do not** use DES for encrypting data. Its known vulnerabilities and insecurities make it an unsuitable choice for protecting sensitive information. + - **Do** implement the Advanced Encryption Standard (AES) with a key size of 256 bits (AES-256) for encryption. AES-256 is recognized for its strong security properties and is widely accepted as a secure replacement for DES. - ✅ Implement AES-256 for Strong Encryption - - ```go - // Use AES-256 for secure encryption by initializing a 32-byte key for AES-256 - key := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - log.Fatal(err) - } - - // Create a new cipher block from the key - blockCipher, err := aes.NewCipher(key) - if err != nil { - log.Fatal(err) - } - - // Use Galois/Counter Mode (GCM) for both encryption and decryption - aead, err := cipher.NewGCM(blockCipher) - if err != nil { - log.Fatal(err) - } - - var encrypted = []byte{} - var nonce = []byte{} - - // Encrypt a message with AES-256 using GCM - { - msg := []byte("Some secret message") - // Ensure nonces are unique for each encryption to maintain security - nonce = make([]byte, 12) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - log.Fatal(err) - } - encrypted = aead.Seal(nil, nonce, msg, nil) - } - - // Decrypt the message securely - { - msg, err := aead.Open(nil, nonce, encrypted, nil) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Decrypted: %s\n", msg) - } - ``` - - ❌ Do Not Use Deprecated Algorithms - Avoid using deprecated cryptographic algorithms such as DES, as they do not provide adequate security against modern threats and attacks. - - ## Resources + ## References - [NIST Recommendations](https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final) - [AES-256 Encryption](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) diff --git a/rules/go/gosec/blocklist/md5.yml b/rules/go/gosec/blocklist/md5.yml index 79541633b..200107415 100644 --- a/rules/go/gosec/blocklist/md5.yml +++ b/rules/go/gosec/blocklist/md5.yml @@ -9,35 +9,18 @@ languages: - go metadata: description: "Import of weak hashing library (MD5)" - remediation_message: | + remediation_message: |- ## Description - MD5 is a widely used cryptographic hash function that produces a 128-bit (16-byte) hash value. It's commonly used to check the integrity of files. However, MD5 is not collision-resistant; this means that different inputs may produce the same output hash. MD5's vulnerabilities and the feasibility of collision attacks have rendered it obsolete for security-related purposes, particularly digital signatures, SSL certificates, and cryptographic message authentication. + Using a weak hashing library like MD5 increases the risk of data breaches. MD5 is vulnerable to collision attacks, where two different inputs produce the same output, compromising data integrity and security. - ## Remediation + ## Remediations - Given the vulnerabilities of MD5, it is highly recommended to switch to more secure hashing algorithms. For hashing purposes that do not involve passwords, such as verifying file integrity or generating unique identifiers, SHA-3 or BLAKE2 can be used due to their stronger cryptographic properties. + - **Do not** use MD5 for hashing. It is considered a weak hash algorithm and can compromise data security. + - **Do** use stronger hashing algorithms such as SHA-3 or BLAKE2 for general hashing purposes, such as file integrity checks or generating unique identifiers. + - **Do** use recommended algorithms such as bcrypt or Argon2id for password hashing, as these are designed to be slower and therefore more effective against brute-force attacks. - ✅ Use SHA-3 or BLAKE2 for General Hashing Needs - - ```go - // BLAKE2 is a cryptographic hash function faster than MD5, SHA-1, and SHA-2, and as secure as the latest standard SHA-3 - fileContents := []byte("some file contents to create hash for") - blake2bHasher, err := blake2b.New512(nil) - if err != nil { - log.Fatal(err) - } - hashedValue := blake2bHasher.Sum(fileContents) - fmt.Printf("%s\n", hex.EncodeToString(hashedValue)) - ``` - - For password hashing, where the hash functions need to be slow to combat brute-force attacks, bcrypt or Argon2id should be used. These algorithms are designed to be computationally intensive to hash and verify, which helps protect against password cracking attempts. - - ✅ Adopt bcrypt or Argon2id for Password Hashing - - The bcrypt algorithm is a good choice for password hashing as it allows you to adjust the cost (computational complexity) and is widely supported. Argon2id is the winner of the Password Hashing Competition and offers a good balance between resistance to GPU cracking attacks and usability. - - ## Resources + ## References - [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) diff --git a/rules/go/gosec/blocklist/rc4.yml b/rules/go/gosec/blocklist/rc4.yml index 16f6469cd..e57ad62ee 100644 --- a/rules/go/gosec/blocklist/rc4.yml +++ b/rules/go/gosec/blocklist/rc4.yml @@ -9,60 +9,17 @@ languages: - go metadata: description: "Import of weak encryption algorithm (RCA)" - remediation_message: | + remediation_message: |- ## Description - RC4 is a stream cipher that was once popular for its simplicity and speed in operation. However, extensive research over the years has revealed multiple vulnerabilities, rendering RC4 insecure in most contexts. Its weaknesses in key scheduling and the generation of non-random bytes have led to successful cryptanalysis and practical attacks, making it unsuitable for securing data. + The RC4 encryption algorithm is outdated and vulnerable. It has been found to have significant security flaws, including predictable key generation and weak randomization, which have been exploited in various attacks. These vulnerabilities make RC4 unsuitable for secure data encryption. - ## Remediation + ## Remediations - With the known vulnerabilities of RC4, it's essential to move to a more secure cipher. AES (Advanced Encryption Standard) is the recommended replacement because it has undergone extensive scrutiny and is considered secure against cryptanalysis. + - **Do not** use RC4 for encrypting data. Its vulnerabilities to cryptanalysis and practical attacks compromise data security. + - **Do** switch to AES-256 for encryption. AES-256 is a secure and widely accepted standard that provides strong protection against attacks. Using AES-256 ensures compliance with current security standards and provides a robust defense against known cryptographic attacks. - ✅ Switch to AES-256 for Robust Encryption - - ```go - // 32 byte keys will set up AES-256, which is a secure block cipher that has become the industry standard for encryption. - key := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - log.Fatal(err) - } - - blockCipher, err := aes.NewCipher(key) - if err != nil { - log.Fatal(err) - } - - aead, err := cipher.NewGCM(blockCipher) - if err != nil { - log.Fatal(err) - } - - var encrypted = []byte{} - var nonce = []byte{} - // Encryption routine - { - msg := []byte("Some secret message") - // Note that the key must be rotated after every 2^32 uses of a single nonce-value to avoid cipher text repetition. - nonce = make([]byte, 12) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - log.Fatal(err) - } - encrypted = aead.Seal(nil, nonce, msg, nil) - } - - // Decryption routine - { - msg, err := aead.Open(nil, nonce, encrypted, nil) - if err != nil { - log.Fatal(err) - } - fmt.Printf("Decrypted: %s\n", msg) - } - ``` - - Using AES-256 ensures that your encryption mechanism meets current security standards and is robust against known attacks. AES has been widely adopted across various industries and has proven its reliability over time. - - ## Resources + ## References - [NIST Guidelines on Cryptography](https://csrc.nist.gov/publications/detail/sp/800-38a/final) cwe_id: diff --git a/rules/go/gosec/blocklist/sha1.yml b/rules/go/gosec/blocklist/sha1.yml index 41e4d650e..b9f798d3d 100644 --- a/rules/go/gosec/blocklist/sha1.yml +++ b/rules/go/gosec/blocklist/sha1.yml @@ -9,30 +9,18 @@ languages: - go metadata: description: "Import of weak hashing library (SHA-1)" - remediation_message: | + remediation_message: |- ## Description - The SHA-1 hashing algorithm is no longer considered secure against well-funded attackers. It is vulnerable to collision attacks, which means it's possible to generate two different inputs that result in the same SHA-1 hash, undermining the hash's uniqueness and security. Due to these vulnerabilities, it is advised to discontinue using SHA-1 for cryptographic security. + The SHA-1 hashing algorithm is outdated and vulnerable to collision attacks, where two distinct inputs produce the same output hash. This flaw compromises the algorithm's ability to securely verify data integrity and authenticity, making it unsuitable for cryptographic security. - ## Remediation + ## Remediations - When choosing a hashing algorithm for cryptographic purposes, it's important to select one that is resistant to collisions and other attack vectors. SHA-3 and BLAKE2 are both excellent choices for non-password-based hashing requirements due to their strong cryptographic properties. + - **Do not** use SHA-1 for cryptographic purposes or to ensure data integrity. Its susceptibility to collision attacks poses a significant security risk. + - **Do** use stronger hashing algorithms such as SHA-3 or BLAKE2 for general hashing purposes, such as file integrity checks or generating unique identifiers. + - **Do** use recommended algorithms such as bcrypt or Argon2id for password hashing, as these are designed to be slower and therefore more effective against brute-force attacks. - ✅ For General Hashing Needs, Use SHA-3 or BLAKE2 - - Choose SHA-3 or BLAKE2 for their resistance to known hash attack vectors, ensuring the integrity and uniqueness of your data fingerprints. - - ✅ For Password Hashing, Prefer bcrypt or Argon2id - - For password hashing specifically, bcrypt or Argon2id are recommended. These algorithms are designed to be computationally intensive, which helps protect against brute-force attacks. - - ❌ Discontinue Using SHA-1 for Security Purposes - - Given its vulnerabilities, avoid using SHA-1 in any security context to prevent potential collision attacks. - - The code snippet provided is unrelated to the hashing algorithms and seems to be a continuation of the previous examples for encryption with AES-256. Ensure your hashing and encryption strategies are correctly implemented as per their intended use-cases. - - ## Resources + ## References - [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html) - [NIST Policy on Hash Functions](https://csrc.nist.gov/projects/hash-functions) diff --git a/rules/go/gosec/crypto/bad_tls_settings.yml b/rules/go/gosec/crypto/bad_tls_settings.yml index 5d5cf734c..1aebec758 100644 --- a/rules/go/gosec/crypto/bad_tls_settings.yml +++ b/rules/go/gosec/crypto/bad_tls_settings.yml @@ -39,34 +39,23 @@ languages: - go metadata: description: "Usage of insecure cipher" - remediation_message: | + remediation_message: |- ## Description - A security concern arises when a cryptographically insecure cipher suite is used in an application. Such cipher suites may be vulnerable to various types of attacks, reducing the security of the communication channel. + Using an insecure cipher suite in your application introduces a significant security risk. These weak cipher suites are susceptible to various attacks, compromising the security of your communications. - ## Remediation + ## Remediations - To enhance the security of TLS connections, it is crucial to use up-to-date and secure cipher suites and protocols. Here are the recommended steps to ensure the use of secure ciphers: + - **Do** use modern, secure cipher suites that offer Perfect Forward Secrecy (PFS), such as ECDHE-RSA-AES256-GCM-SHA384 or ECDHE-RSA-CHACHA20-POLY1305. PFS ensures that even if future private keys are compromised, past communications remain secure. + - **Do** adopt TLS 1.3 whenever possible, as it includes enhancements that offer better security against various attacks. The Go standard library, for instance, automatically prefers the most secure protocol and cipher suite available. + ```go + cfg := &tls.Config{ + MinVersion: tls.VersionTLS13, + } + ``` + - **Do not** use obsolete or insecure cipher suites. Avoid any cipher suites that lack support for modern security standards or have known vulnerabilities. - ✅ Use Modern, Secure Cipher Suites - - Select cipher suites that are known to be secure and have properties such as Perfect Forward Secrecy (PFS), which protects past communications even if future private keys are compromised. - - ✅ Adopt TLS 1.3 Where Possible - - TLS 1.3 should be the preferred protocol as it includes improvements over previous versions, making it more secure against various attacks. Go's standard library will automatically prefer the most secure protocol and cipher suite available during the TLS handshake. - - ✅ Configure TLS Properly If Using TLS 1.0-1.2 - - In cases where TLS 1.3 is not an option and you must use TLS 1.0-1.2, ensure to configure the cipher suites to use those that support PFS, as listed below. - - ❌ Avoid Using Obsolete or Insecure Cipher Suites - - Avoid any cipher suites that do not support modern security standards, including those without PFS or with known vulnerabilities. - - The provided Go code examples demonstrate how to configure the `tls.Config` struct for a Go server to use TLS 1.3 or to specify a list of secure cipher suites when using TLS 1.0-1.2. - - ## Resources + ## References - [Mozilla's SSL Configuration Generator](https://ssl-config.mozilla.org/) - [OWASP TLS Cipher String Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/TLS_Cipher_String_Cheat_Sheet.html) diff --git a/rules/go/gosec/crypto/insecure_ignore_host_key.yml b/rules/go/gosec/crypto/insecure_ignore_host_key.yml index 0b01ef710..90aeecefe 100644 --- a/rules/go/gosec/crypto/insecure_ignore_host_key.yml +++ b/rules/go/gosec/crypto/insecure_ignore_host_key.yml @@ -4,30 +4,18 @@ languages: - go metadata: description: "Missing verification of host keys" - remediation_message: | + remediation_message: |- ## Description - The security vulnerability identified pertains to the application neglecting the verification of host keys during SSH connections. Host keys are crucial for confirming the server's identity, preventing Man-in-the-Middle (MitM) attacks where an attacker could impersonate the server. When these keys are ignored, the client cannot guarantee the authenticity of the server it connects to. + Lacking verification of host key during SSH connections compromises the security of your application. Host keys are essential for verifying the server's identity to prevent Man-in-the-Middle (MitM) attacks, where an attacker could pose as the server. Without this verification, there's no way to ensure the server's authenticity. - ## Remediation + ## Remediations - To mitigate this risk, it is essential to implement proper host key checking: + - **Do not** use `ssh.InsecureIgnoreHostKey` as a `HostKeyCallback` function. This method bypasses any form of host validation, making your application vulnerable to attacks. + - **Do** implement host key verification. For example, use the `knownhosts` package from Go's `x/crypto/ssh` to check server keys against a list of known hosts, similar to OpenSSH's approach. + - **Do not** disable host key checking in your production code. While it might seem convenient for development or testing environments, it significantly increases the risk of security breaches. - ✅ Implement Host Key Verification - - Use the `knownhosts` package from Go's `x/crypto/ssh` to validate server keys against known hosts. This mirrors the functionality found in OpenSSH. - - ✅ Avoid Disabling Host Key Checking - - Never disable host key checking in production code. While it might be convenient for testing, it opens up security vulnerabilities. - - ❌ Do Not Use `InsecureIgnoreHostKey` - - Although available, using `ssh.InsecureIgnoreHostKey` as a `HostKeyCallback` function should be strictly avoided as it does not offer any form of host validation. - - Below is a code snippet showing how to set up an SSH `ClientConfig` in Go to use the `knownhosts` callback for server verification: - - ## Resources + ## References - [GoDoc for x/crypto/ssh](https://pkg.go.dev/golang.org/x/crypto/ssh) - [Secure use of SSH - OpenSSH](https://www.openssh.com/) diff --git a/rules/go/gosec/crypto/weak_crypto.yml b/rules/go/gosec/crypto/weak_crypto.yml index 466138259..368645ce6 100644 --- a/rules/go/gosec/crypto/weak_crypto.yml +++ b/rules/go/gosec/crypto/weak_crypto.yml @@ -10,32 +10,19 @@ languages: - go metadata: description: "Usage of weak hashing library" - remediation_message: | + remediation_message: |- ## Description - The issue identified indicates the use of a cryptographic algorithm that is no longer considered secure by current standards. Such algorithms can compromise data confidentiality and integrity, making it vulnerable to decryption and tampering by unauthorized parties. + Your code uses a weak hashing library, which means it relies on cryptographic algorithms that are no longer secure. This vulnerability can lead to compromised data confidentiality and integrity, as it makes the data susceptible to unauthorized decryption and tampering. - ## Remediation + ## Remediations - To ensure the security of the data, adhere to the following guidelines: + - **Do** replace weak or outdated algorithms with strong, modern alternatives. For encryption, use AES (Advanced Encryption Standard), and for hashing, opt for SHA-256 or higher. + - **Do** always use the latest versions of cryptographic libraries. These versions are more likely to use secure algorithms and settings by default. + - **Do not** use cryptographic algorithms that have been deprecated due to known vulnerabilities. Avoid MD5, SHA-1, or DES for any cryptographic operations. + - **Do not** attempt to create custom cryptographic solutions. Instead use well-reviewed and tested standard cryptographic libraries to ensure security. - ✅ Employ Strong Cryptographic Algorithms - - Replace deprecated or weak algorithms with strong, modern alternatives such as AES (Advanced Encryption Standard) for encryption, and SHA-256 or higher for hashing. - - ✅ Keep Libraries Updated - - Use the latest versions of cryptographic libraries, as they are more likely to default to secure algorithms and settings. - - ❌ Avoid Deprecated Algorithms - - Do not use cryptographic algorithms that have been deprecated due to vulnerabilities, such as MD5, SHA-1, or DES. - - ❌ Do Not Reinvent Cryptography - - Avoid custom cryptographic implementations as they are more susceptible to errors. Instead, rely on well-reviewed and tested standard cryptographic libraries. - - ## Resources + ## References - [NIST Cryptographic Standards and Guidelines](https://csrc.nist.gov/publications/sp) - [Cryptography Coding Standard](https://cryptocoding.net/index.php/Coding_rules) diff --git a/rules/go/gosec/crypto/weak_key_strength.yml b/rules/go/gosec/crypto/weak_key_strength.yml index 8bacf172e..0f472b55a 100644 --- a/rules/go/gosec/crypto/weak_key_strength.yml +++ b/rules/go/gosec/crypto/weak_key_strength.yml @@ -7,46 +7,20 @@ languages: - go metadata: description: "Usage of inadequate encryption strength" - remediation_message: | + remediation_message: |- ## Description - The application generates an RSA key with a bit length that is shorter than the current recommended minimum of 2048 bits. Keys shorter than 2048 bits are considered insecure due to advancements in computational power which could potentially allow them to be factored, thereby breaking the encryption. + Your application uses RSA encryption with a key length shorter than the recommended 2048 bits. Keys under 2048 bits are vulnerable because of the increasing power of modern computers, which could break the encryption by factoring the key. - ## Remediation + ## Remediations - To ensure the security of RSA keys, follow these guidelines: + - **Do** generate RSA keys with a minimum of 2048 bits. This meets NIST recommendations and protects against the risk of keys being compromised by advancements in computing power. Keys shorter than 2048 bits do not provide adequate protection against brute-force attacks. + ```go + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + ``` + - **Do** adhere to industry standards and guidelines for cryptographic practices to ensure the security of your data. - ✅ Use Sufficient Key Length - - Generate RSA keys with a minimum length of 2048 bits to align with NIST recommendations and safeguard against future advancements in computing power that could compromise keys of shorter lengths. - - ```go - // Example of generating a secure RSA key with 2048 bits - import ( - "crypto/rand" - "crypto/rsa" - "log" - ) - - func generateSecureKey() { - // Use at least 2048 bits for secure RSA keys - privateKey, err := rsa.GenerateKey(rand.Reader, 2048) - if err != nil { - log.Fatalf("Error generating RSA key: %v", err) - } - // privateKey can now be used for secure cryptographic operations - } - ``` - - ❌ Avoid Short Keys - - Do not use RSA keys that are less than 2048 bits in length, as they do not offer sufficient protection against brute-force attacks. - - ❌ Don't Ignore Industry Standards - - Always follow industry standards and guidelines for cryptographic practices to maintain the integrity and confidentiality of data. - - ## Resources + ## References - [NIST Special Publication 800-57 Part 1](https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/final) cwe_id: diff --git a/rules/go/gosec/crypto/weak_random.yml b/rules/go/gosec/crypto/weak_random.yml index b19eb6b0f..30b346099 100644 --- a/rules/go/gosec/crypto/weak_random.yml +++ b/rules/go/gosec/crypto/weak_random.yml @@ -40,49 +40,18 @@ languages: - go metadata: description: "Usage of weak Pseudo-Random Number Generator (PRNG)" - remediation_message: | + remediation_message: |- ## Description - The `math/rand` package in Go is designed for generating pseudorandom numbers, which are not secure for cryptographic purposes. These numbers are predictable if the seed is known, which could compromise the security of applications using them for secrets, tokens, or other security-sensitive features. + The `math/rand` package in Go generates pseudorandom numbers that are not secure for cryptographic purposes. These numbers can be predicted if the seed is known, posing a risk to the security of applications that use them for generating secrets, tokens, or other security-sensitive elements. ## Remediations - To securely generate random numbers in a security-sensitive context, implement the following measures: + - **Do** use `crypto/rand` instead of `math/rand` for generating random numbers in contexts where security is crucial. This ensures the randomness is cryptographically secure and unpredictable. + - **Do not** use `math/rand` for generating random numbers in cryptographic applications, including but not limited to key generation, authentication tokens, or security challenges. + - **Do not** initialize `math/rand` with predictable seeds, such as timestamps or other easily guessable values, if it is required to use `math/rand`. - ✅ Use Cryptographically Secure Randomness - - Replace the use of `math/rand` with `crypto/rand` to ensure that the random numbers generated are suitable for cryptographic use and are not predictable. - - ```go - import ( - "crypto/rand" - "log" - "math/big" - ) - - func generateSecureRandomNumber() *big.Int { - // Generate a cryptographically secure random number - randomNumber, err := rand.Int(rand.Reader, big.NewInt(1<<62)) - if err != nil { - log.Fatalf("Failed to generate a secure random number: %v", err) - } - return randomNumber - } - ``` - - ✅ Audit Existing Code - - Review your codebase for instances where `math/rand` is used in security-sensitive contexts and update them to use `crypto/rand`. - - ❌ Do Not Use Predictable Seeds - - Avoid initializing `math/rand` with predictable seeds, such as timestamps or other easily guessable values, especially in a security context. - - ❌ Don't Use for Security Purposes - - Never rely on `math/rand` for generating random numbers in cryptographic applications, like key generation, authentication tokens, or any form of security challenge. - - ## Resources + ## References - [crypto/rand package documentation](https://pkg.go.dev/crypto/rand) diff --git a/rules/go/gosec/crypto/weak_tls_version.yml b/rules/go/gosec/crypto/weak_tls_version.yml index df4c20b4d..34464fac1 100644 --- a/rules/go/gosec/crypto/weak_tls_version.yml +++ b/rules/go/gosec/crypto/weak_tls_version.yml @@ -5,67 +5,25 @@ languages: - go metadata: description: "Usage of deprecated TLS version" - remediation_message: | + remediation_message: |- ## Description - TLS (Transport Layer Security) versions 1.1 and 1.0 have been deprecated due to known security vulnerabilities that can expose sensitive data to interception and attacks. Using these versions can put data transmissions at risk. + TLS (Transport Layer Security) versions 1.0 and 1.1 have known vulnerabilities and using them introduces security risks to your application. These outdated TLS versions can lead to the interception and compromise of sensitive data during transmission. ## Remediations - To ensure secure data transmission, you should enforce the use of TLS 1.3, which includes security enhancements over its predecessors. The following steps can be taken: - - ✅ Enforce TLS 1.3 - - Update your server configuration to support and prefer TLS 1.3, which includes modern security features and mitigates known vulnerabilities found in older versions. - - ✅ Configure Go’s TLS Library - - Set `MinVersion` in the `tls.Config` struct to `tls.VersionTLS13` to ensure that the server only accepts TLS 1.3 connections. - - ```go - import ( - "crypto/tls" - "log" - "net/http" - "time" - ) - - func main() { - cert, err := tls.LoadX509KeyPair("server.crt", "server.key") - if err != nil { - log.Fatalf("failed to load key pair: %s", err) - } - - cfg := &tls.Config{ - Certificates: []tls.Certificate{cert}, - MinVersion: tls.VersionTLS13, // Enforce TLS 1.3 - } - - srv := &http.Server{ - Addr: ":8999", // Listen on port 8999 - TLSConfig: cfg, - ReadTimeout: time.Minute, - WriteTimeout: time.Minute, - } - - log.Printf("Server is starting...") - log.Fatal(srv.ListenAndServeTLS("", "")) // TLS cert and key are already provided in the TLSConfig - } - ``` - - ✅ Perfect Forward Secrecy (PFS) - - TLS 1.3 configurations ensure PFS by default, which protects past communications even if future session keys are compromised. - - ✅ Regularly Update Dependencies - - Keep your Go version and dependencies up-to-date to benefit from the latest security fixes and improvements. - - ❌ Do Not Use Deprecated TLS Versions - - Avoid configuring your server to accept TLS 1.0 or 1.1. Remove these options from your TLS configuration to prevent downgrade attacks. - - ## Resources + - **Do** enforce the use of TLS 1.3 when configuring Go's TLS library. TLS 1.3 offers significant security improvements, helping to protect data from known vulnerabilities present in older versions. + ```go + cfg := &tls.Config{ + MinVersion: tls.VersionTLS13, + ... + } + ``` + - **Do** utilize configurations that support Perfect Forward Secrecy (PFS) with TLS 1.3. PFS enhances security by ensuring that past communications remain secure even if future session keys are compromised. + - **Do** regularly update your Go version and dependencies to incorporate the latest security fixes and improvements. + - **Do not** configure your server to accept TLS versions 1.0 or 1.1. Removing these options from your TLS configuration is crucial to prevent downgrade attacks. + + ## References - [IETF's Deprecation of TLS 1.0 and 1.1](https://tools.ietf.org/html/rfc8996) - [OWASP TLS Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Security_Cheat_Sheet.html) diff --git a/rules/go/gosec/file_permissions/file_perm.yml b/rules/go/gosec/file_permissions/file_perm.yml index 74c788bfd..8c6a51f35 100644 --- a/rules/go/gosec/file_permissions/file_perm.yml +++ b/rules/go/gosec/file_permissions/file_perm.yml @@ -26,58 +26,26 @@ languages: - go metadata: description: "Permissive file assignment" - remediation_message: | + remediation_message: |- ## Description - When creating or updating files, ensuring proper file permissions is crucial to maintain security. Overly permissive file settings can allow unauthorized users to read, modify, or execute files, which could lead to information disclosure, data tampering, or compromise of the system. + Setting overly permissive file permissions exposes your system to risks such as unauthorized access, data tampering, and potential system compromise. This vulnerability arises when files are created or updated without adequately restrictive permissions, allowing unauthorized users to read, modify, or execute files. ## Remediations - To prevent unauthorized access, it's important to set restrictive file permissions, particularly when sensitive data is involved. Here's how to manage file permissions in Go: - - ✅ Restrict File Permissions - - Set file permissions to allow only the necessary access level for the application. Avoid using permissions like `0777`, which allows read, write, and execute permissions for all users. - - ✅ Use Go’s `os` Package - - Utilize the `os.OpenFile` function with the appropriate file permission flags. - - ✅ Recommended File Permissions - - - `0400` grants read-only access to the file's owner. - - `0200` grants write-only access to the file's owner. - - `0600` grants read and write access to the file's owner and is commonly used for files that need to be both read from and written to by the application. - - ```go - import ( - "log" - "os" - ) - - func main() { - // Use os.OpenFile to create a file with restricted permissions - // 0600 permission: Read and write for the owner, no permissions for others - f, err := os.OpenFile("file.txt", os.O_CREATE|os.O_WRONLY, 0600) - if err != nil { - log.Fatalf("failed to create file: %s", err) - } - defer f.Close() - // Continue to work with the file here - } - ``` - - ✅ Verify File Permissions - - After file creation, check the file permissions to ensure they are set correctly. - - ✅ Secure Default Permissions - - If you are developing an application that creates multiple files, consider setting umask in your application to a secure default. - - ✅ Review File Permission Settings - - Regularly audit file permissions to ensure they adhere to the principle of least privilege. + - **Do not** use overly permissive file permissions, such as `0777`, which grants read, write, and execute permissions to all users. + - **Do** set file permissions to restrict access appropriately: + - `0400` for read-only access by the file's owner. + - `0200` for write-only access by the file's owner. + - `0600` for read and write access by the file's owner, suitable for files that the application needs to read from and write to. + - **Do** use Go's `os` package to manage file permissions effectively. For example, use `os.OpenFile` with appropriate permission flags such as 0600. + ```go + f, err := os.OpenFile("file.txt", os.O_CREATE|os.O_WRONLY, 0600) + ... + ``` + - **Do** verify file permissions after creation or update to ensure they are set as intended. + - **Do** consider setting umask to a secure default, if your application creates multiple files, to ensure that files are created with safe default permissions. + - **Do** regularly review and audit file permissions in your system to ensure they adhere to the principle of least privilege, minimizing the access level to what is strictly necessary for operational functionality. cwe_id: - 276 diff --git a/rules/go/gosec/file_permissions/mkdir.yml b/rules/go/gosec/file_permissions/mkdir.yml index 24174d158..ccfb1225f 100644 --- a/rules/go/gosec/file_permissions/mkdir.yml +++ b/rules/go/gosec/file_permissions/mkdir.yml @@ -20,56 +20,26 @@ languages: - go metadata: description: "Permissive folder creation" - remediation_message: | + remediation_message: |- ## Description - Setting correct directory permissions is critical to maintaining the security of a system. Directories with overly permissive access rights can become a vector for security breaches, allowing unauthorized users to add, remove, or change files, potentially leading to the execution of malicious code, data leaks, or system compromise. + Incorrect directory permissions can severely compromise system security.Directories with overly permissive access rights can allow unauthorized users to manipulate files, potentially leading to malicious code execution, data breaches, or full system compromise. ## Remediations - When creating directories, apply the principle of least privilege to ensure users have only the permissions necessary for their role: - - ✅ Restrict Directory Permissions - - Use permissions that restrict access to what is strictly necessary for the operation of the application. Avoid overly permissive settings such as `0777`, which allow all users to read, write, and execute. - - ✅ Use Go’s `os` Package - - Leverage the `os.Mkdir` or `os.MkdirAll` function with appropriate permission flags to create directories. - - ✅ Recommended Directory Permissions - - - `0700` gives the owner read, write, and execute permissions, with no access for group and others, suitable for private user data. - - `0750` gives the owner full permissions, the group read and execute permissions, and no permissions for others, which is commonly used for directories that need to be shared within a group. - - ```go - import ( - "log" - "os" - ) - - func main() { - // Use os.Mkdir to create a directory with restricted permissions - // 0700 permission: Full control for the owner, no permissions for group and others - err := os.Mkdir("secure_directory", 0700) - if err != nil { - log.Fatalf("failed to create directory: %s", err) - } - // Continue setting up the directory here - } - ``` - - ✅ Verify Directory Permissions - - After creating a directory, confirm the permissions to ensure they have been set correctly. - - ✅ Set Secure Umask - - Consider setting a secure umask in your application or user profile to ensure that all newly created files and directories have restrictive permissions by default. - - ✅ Regular Auditing - - Implement regular checks of directory permissions as part of your security auditing procedures to identify and correct any permissions that are too broad. + - **Do not** use overly broad permissions like `0777` for directories, as this allows all users to read, write, and execute files, posing a significant security risk. + ```go + os.Mkdir("example_directory", 0777) // unsafe + ``` + - **Do** set directory permissions to: + - `0700` for private user data, granting full control to the owner only. + - `0750` for directories requiring group access, granting full control to the owner and read/execute to the group. + ```go + os.Mkdir("secure_directory", 0700) + ``` + - **Do** verify file permissions after creation or update to ensure they are set as intended. + - **Do** consider setting umask to a secure default, if your application creates multiple files, to ensure that files are created with safe default permissions. + - **Do** regularly review and audit file permissions in your system to ensure they adhere to the principle of least privilege, minimizing the access level to what is strictly necessary for operational functionality. cwe_id: - 276 diff --git a/rules/go/gosec/filesystem/decompression_bomb.yml b/rules/go/gosec/filesystem/decompression_bomb.yml index 88e06f767..bf05449c4 100644 --- a/rules/go/gosec/filesystem/decompression_bomb.yml +++ b/rules/go/gosec/filesystem/decompression_bomb.yml @@ -44,74 +44,23 @@ languages: - go metadata: description: "Missing configuration against decompression bomb" - remediation_message: | + remediation_message: |- ## Description - Decompression bombs are a form of attack against an application or service that processes compressed files. The attacker crafts a compressed file that is small in size, but when decompressed, expands to a much larger size that is disproportionate to the original. This can exhaust system resources like CPU, memory, or disk space, leading to a Denial of Service (DoS). + Decompression bombs pose a risk by exploiting applications that process compressed files. These attacks involve a compressed file that is small in size but expands to a significantly larger size when decompressed. This can overwhelm system resources such as CPU, memory, or disk space, causing a Denial of Service (DoS). ## Remediations - Implement measures to mitigate the impact of decompression bombs: - - ✅ Limit Decompression Size - - Use `io.LimitReader` to restrict the amount of data that a reader will decompress. This prevents the decompression of large files that could fill up memory or disk space. - - ✅ Monitor Resource Usage - - Implement resource monitoring to watch for unexpected spikes in CPU, memory, or disk usage, which could indicate an attempted decompression bomb attack. - - ✅ Input Validation - - Validate the size and type of the input before decompressing. If possible, reject files that do not meet expected criteria. - - ✅ Fail Safely - - Ensure that your application can handle errors from the decompression process safely, without crashing or becoming unresponsive. - - ✅ Regular Updates - - Keep compression libraries up to date with the latest security patches to protect against known vulnerabilities. - - ✅ User Education - - Educate users about the risks of decompression bombs if they are able to upload compressed files. - - ```go - import ( - "compress/gzip" - "io" - "log" - "os" - ) - - func main() { - // Open the gzip file - f, err := os.Open("example.gz") - if err != nil { - log.Fatal(err) - } - defer f.Close() - - // Create a gzip reader on the file - r, err := gzip.NewReader(f) - if err != nil { - log.Fatal(err) - } - defer r.Close() - - // Define a limit for decompression + - **Do** limit the decompression size. Use `io.LimitReader`, for example, to restrict the amount of data that a reader will decompress. This prevents the decompression of large files that could fill up memory or disk space. + ```go const maxDecompressSize = 10 * 1024 * 1024 // 10 MB - - // Limit the size of the reader limitedReader := io.LimitReader(r, maxDecompressSize) - - // Use the limited reader to decompress, preventing the decompression bomb from expanding fully - if _, err := io.Copy(os.Stdout, limitedReader); err != nil { - log.Fatal(err) - } - } - ``` + ``` + - **Do** monitor resource usage to detect unexpected increases in CPU, memory, or disk usage, which may indicate an attack. + - **Do** validate the size and type of input files before decompression. Reject files that do not meet predefined criteria to avoid processing potentially harmful data. + - **Do** ensure your application fails safely. It should handle decompression errors without crashing or becoming unresponsive. + - **Do** regularly update your compression libraries to incorporate the latest security patches and protect against known vulnerabilities. + - **Do** educate users about the risks associated with decompression bombs, especially if they have the ability to upload compressed files. cwe_id: - 409 diff --git a/rules/go/gosec/filesystem/dirtraversal.yml b/rules/go/gosec/filesystem/dirtraversal.yml index ae1b75647..4415f379b 100644 --- a/rules/go/gosec/filesystem/dirtraversal.yml +++ b/rules/go/gosec/filesystem/dirtraversal.yml @@ -17,57 +17,21 @@ languages: - go metadata: description: "Usage of Root directory mounting" - remediation_message: | + remediation_message: |- ## Description - Mounting the root directory (`/`) in an HTTP server is a significant security risk. It potentially allows anyone with access to the HTTP service to browse and access system files, which can lead to information disclosure, data breaches, or further exploitation of the system. + Mounting the root directory (`/`) on an HTTP server exposes a significant security risk. This setup could allow unauthorized individuals to access and browse system files, potentially leading to information disclosure, data breaches, or further system exploitation. ## Remediations - Implement the following measures to prevent exposing the entire filesystem through your web server: + - **Do not** mount the root directory as the web server's root. Doing so would make the entire filesystem accessible over the web. + - **Do** serve files from a specific directory designed for public access. Ensure this directory only contains files intended for public viewing. + - **Do** apply strict permissions to the directory being served. This ensures the server process accesses only the files it's meant to serve. + - **Do** utilize server configuration files, such as `.htaccess` for Apache HTTP Server, to control access to directories if your server supports it. + - **Do** consider isolating your server environment using containerization or virtualization techniques. This limits potential damage in case of a security breach by enforcing strict access controls. + - **Do** conduct regular audits of your filesystem and the files your server is hosting. This helps ensure no sensitive information is accidentally exposed. - ✅ Serve Specific Directory - - Change the `http.Dir` to serve files from a specific, safe directory intended for public access rather than the root directory. Ensure this directory contains only the files that are meant to be publicly accessible. - - ✅ Access Control - - Apply appropriate permissions to the directory being served to ensure that the server process can only access the files that it's supposed to serve. - - ✅ Use of Configuration Files - - If supported, use configuration files like `.htaccess` (for Apache HTTP Server) or equivalent server configuration to control access to directories. - - ✅ Isolate Environment - - Consider running your server in a containerized or virtualized environment with strict access controls to limit the potential damage in case of a security breach. - - ✅ Regular Audits - - Perform regular audits of the filesystem and the files being served to ensure that no sensitive information is being unintentionally exposed. - - ```go - import ( - "net/http" - "log" - ) - - func main() { - // Define the specific path to a directory to be served - const safePath = "/var/www/html/public" - - // Create a new file server handler that serves files from the safePath - fs := http.FileServer(http.Dir(safePath)) - - // Configure the server to handle requests to the root with the file server handler - http.Handle("/", http.StripPrefix("/", fs)) - - // Start the server - log.Fatal(http.ListenAndServe(":9000", nil)) - } - ``` - - ## Resources + ## References - [Go Documentation: http package](https://pkg.go.dev/net/http) - [OWASP: Securing File Uploads](https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload) diff --git a/rules/go/gosec/filesystem/filereadtaint.yml b/rules/go/gosec/filesystem/filereadtaint.yml index 7f7f583af..43dcddc98 100644 --- a/rules/go/gosec/filesystem/filereadtaint.yml +++ b/rules/go/gosec/filesystem/filereadtaint.yml @@ -43,84 +43,22 @@ languages: - go metadata: description: "Unsanitized user input in file path" - remediation_message: | + remediation_message: |- ## Description - Constructing file or path information dynamically, especially from user input, poses a significant security risk. If not handled correctly, attackers could manipulate these paths to access or manipulate sensitive files, leading to data breaches or system compromise. It is crucial to ensure that user input is not used directly to interact with the file system, as this can be exploited to perform path traversal attacks. + Using user input to dynamically construct file paths without proper sanitization introduces a high security risk. This practice can allow attackers to manipulate file paths to access or alter sensitive files, potentially leading to data breaches or system compromise. It is essential to sanitize user input before using it in file system operations to prevent path traversal attacks. ## Remediations - To mitigate the risks associated with dynamic file path construction from user inputs, apply the following best practices: + - **Do not** use unsanitized user input directly in file path construction. This can lead to path traversal vulnerabilities. + - **Do** hash or replace user input with a system-generated unique identifier when constructing file paths. This approach minimizes the risk of path manipulation. + - **Do** use `filepath.Base` to extract the filename from a path, discarding any directory information. This helps prevent directory traversal attacks. + ```go + safeFilename := filepath.Base(userInput) + ``` + - **Do** validate paths before accessing files to ensure they are within the intended directory. This validation acts as a safeguard against unauthorized file access. - ✅ Hash or Replace User Input - - When dealing with user input for file operations, hash the input or replace it with a system-generated unique identifier to prevent path manipulation. - - ✅ Use `filepath.Base` - - Extract only the filename from the path, ignoring any directory information, to avoid directory traversal vulnerabilities. - - ✅ Validate Paths Before Use - - Always perform validation on the resolved paths before accessing files to ensure they are within the expected directory. - - ```go - import ( - "crypto/rand" - "encoding/hex" - "io" - "log" - "path/filepath" - "strings" - ) - - // userData struct holds user-related data with a unique ID for file operations - type userData struct { - id string // Unique identifier for the filename - userFilename string // Original filename from the user, kept for reference - } - - // newUserData constructs a new userData instance with a random file ID - func newUserData(userFilename string) userData { - return userData{ - id: randomFileID(), // Use a random ID instead of user-provided filename - userFilename: userFilename, - } - } - - // randomFileID generates a secure random ID to be used as a filename - func randomFileID() string { - id := make([]byte, 16) - if _, err := io.ReadFull(rand.Reader, id); err != nil { - log.Fatal(err) - } - return hex.EncodeToString(id) - } - - func main() { - // Simulated user input, which may be malicious - data := newUserData("../../possibly/malicious") - - // Define a safe base path for file operations - const basePath = "/tmp/" - - // Resolve the full path using the safe base path and the random ID - resolvedPath, err := filepath.Join(basePath, filepath.Base(data.id)) - if err != nil { - log.Fatal(err) - } - - // Ensure the resolved path is within our designated base path - if !strings.HasPrefix(resolvedPath, basePath) { - log.Fatal("The resolved path does not start with the expected base path") - } - - // The file can now be safely accessed using resolvedPath - // Further file processing code would go here - } - ``` - - ## Resources + ## References - [OWASP Guide to Preventing Path Traversal](https://owasp.org/www-community/attacks/Path_Traversal) cwe_id: diff --git a/rules/go/gosec/filesystem/poor_write_permissions.yml b/rules/go/gosec/filesystem/poor_write_permissions.yml index 97de323f2..1ca10298f 100644 --- a/rules/go/gosec/filesystem/poor_write_permissions.yml +++ b/rules/go/gosec/filesystem/poor_write_permissions.yml @@ -21,50 +21,21 @@ languages: - go metadata: description: "Permissive file creation" - remediation_message: | + remediation_message: |- ## Description - The application has been detected setting file permissions that are too permissive. This configuration could allow unauthorized users to read, write, or execute files, potentially leading to information disclosure or other security vulnerabilities. + Your application sets file permissions that are overly permissive. This oversight could let unauthorized individuals read, write, or execute files, which could lead to the exposure of sensitive information or other security risks. ## Remediations - To enhance security, file permissions should be set to more restrictive values, especially when the files contain sensitive information: + - **Do** use restrictive file permissions. Assign file permissions that strictly limit access, aligning with what your application genuinely needs: + - `0400` for read-only access by the file's owner. + - `0200` for write-only access by the file's owner. + - `0600` for read and write access by the file's owner, suitable for files that the application needs to read from and write to. + - **Do** set the correct permissions when you create or modify files. This step is crucial to prevent unauthorized access right from the start. + - **Do** regularly review and audit file permissions in your system to ensure they adhere to the principle of least privilege, minimizing the access level to what is strictly necessary for operational functionality. - ✅ Use Restrictive File Permissions - - Assign file permissions to limit access appropriately based on the application's requirements. - - - `0400`: Grants read-only access to the file for the owner. - - `0200`: Grants write-only access to the file for the owner. - - `0600`: Grants read and write access to the file for the owner. - - ✅ Apply Permissions During File Creation - - When creating or modifying files, set the appropriate permissions to prevent unauthorized access. - - ```go - import ( - "os" - "log" - ) - - func main() { - // Data to be written to the file - dat := []byte("sensitive data") - - // Write the data to 'file.txt' with read and write permissions for the owner only - if err := os.WriteFile("file.txt", dat, 0600); err != nil { - log.Fatalf("failed to write file: %s", err) - } - // File is now safely written with restricted permissions - } - ``` - - ✅ Review File Permission Settings - - Regularly audit the permissions of files to ensure they conform to the principle of least privilege. - - ## Resources + ## References - [Go Documentation for os Package](https://pkg.go.dev/os) - [Linux 'chmod' Command](https://linux.die.net/man/1/chmod) diff --git a/rules/go/gosec/filesystem/tempfile.yml b/rules/go/gosec/filesystem/tempfile.yml index 26ce04930..ab124946d 100644 --- a/rules/go/gosec/filesystem/tempfile.yml +++ b/rules/go/gosec/filesystem/tempfile.yml @@ -26,53 +26,21 @@ languages: - go metadata: description: "Permissive temporary file creation" - remediation_message: | + remediation_message: |- ## Description - The application has been observed creating files in shared system temporary directories, such as `/tmp` or `/var/tmp`, without the use of secure functions like `os.CreateTemp`. This practice is insecure because it opens up the possibility of symlink attacks, where an attacker could anticipate the temporary file name and create a symlink to a target file, leading to unauthorized file creation or overwriting when the application writes to what it believes is a temporary file. + Your application creates temporary files in shared system directories like `/tmp` or `/var/tmp` without using secure functions such as `os.CreateTemp`. This method is risky as it could lead to symlink attacks. In such attacks, an attacker predicts the name of the temporary file and creates a symlink to a target file. Consequently, when your application writes to the supposed temporary file, it could unintentionally overwrite or create unauthorized files. ## Remediations - To prevent symlink attacks and other vulnerabilities associated with the use of shared temporary directories: + - **Do** use `os.CreateTemp` for creating temporary files. This function helps in securely generating temporary files within a directory that only your application can access, significantly reducing the risk of symlink attacks. + ```go + f, err := os.CreateTemp(restrictedDir, "temp-*.txt") + ``` + - **Do not** use shared temporary directories for operations that involve sensitive data or require secure file handling. + - **Do** ensure temporary files are removed after their intended use to avoid accumulation and potential security risks. - ✅ Use Secure Temporary File Creation - - Implement `os.CreateTemp` to safely create temporary files within a directory that's restricted to the application. This reduces the risk of symlink attacks and ensures that temporary files are handled securely. - - ```go - import ( - "os" - "log" - ) - - func main() { - // Ensure the application-restricted directory exists with appropriate permissions - restrictedDir := "/opt/appdir/restricted" - if err := os.MkdirAll(restrictedDir, 0700); err != nil { - log.Fatalf("failed to create restricted directory: %s", err) - } - - // Securely create a temporary file within the restricted directory - f, err := os.CreateTemp(restrictedDir, "temp-*.txt") - if err != nil { - log.Fatalf("failed to create temporary file: %s", err) - } - defer f.Close() // Ensure the file is closed when no longer needed - - defer os.Remove(f.Name()) // Clean up the file upon exit - // Continue working with the temporary file - } - ``` - - ✅ Avoid Shared Temporary Directories for Sensitive Operations - - Do not use common temporary directories for storing sensitive information or for operations that require secure handling of files. - - ✅ Clean Up After Use - - Always remove temporary files after their use to prevent accumulation and potential misuse. - - ## Resources + ## References - [Go Documentation: os.CreateTemp](https://pkg.go.dev/os#CreateTemp) cwe_id: diff --git a/rules/go/gosec/filesystem/ziparchive.yml b/rules/go/gosec/filesystem/ziparchive.yml index 2ffe3e6de..43c64cbd2 100644 --- a/rules/go/gosec/filesystem/ziparchive.yml +++ b/rules/go/gosec/filesystem/ziparchive.yml @@ -38,102 +38,28 @@ languages: - go metadata: description: "Missing protection against 'Zip Slip' path traversal" - remediation_message: | + remediation_message: |- ## Description - The application is at risk of a path traversal vulnerability, commonly known as 'Zip Slip', when extracting files from untrusted archives. Maliciously crafted archive files can contain relative path specifications that lead to writing files outside the intended directory when extracted, potentially overwriting system files or placing unauthorized files in critical paths. + Your application is vulnerable to a 'Zip Slip' path traversal attack when it extracts files from archives that are not trusted. This occurs because malicious archives may contain files with relative paths aiming to escape the intended directory. As a result, these files could overwrite important system files or be placed in sensitive locations, leading to security breaches. ## Remediations - To safeguard against 'Zip Slip' and related exploitation techniques, follow these security practices: - - ✅ Limit Archive Size - - Implement checks to ensure the zip archive's size does not exceed a maximum threshold, preventing 'Zip Bombs'—archives that decompress to disproportionately large sizes. - - ✅ Generate Unique Filenames - - Avoid using the original filenames from the archive. If necessary, use only the base name after sanitizing or, better yet, generate a unique name to prevent intentional overwrites. - - ✅ Validate Extraction Paths - - Confirm that extracted files are written to a specified, trusted directory and do not traverse outside of this directory. - - ✅ Disallow Symbolic Links - - Only process regular files. Exclude symbolic links to prevent indirect file read/write vulnerabilities. - - ```go - import ( - "archive/zip" - "io" - "log" - "os" - "path/filepath" - "strings" - ) - - func main() { - // Open the zip file for reading - r, err := zip.OpenReader("trusted.zip") - if err != nil { - log.Fatal(err) - } - defer r.Close() - - // Set up restrictions and base path - const ( - expectedFileCount = 10 - totalAllowedSize = 10 * 1024 * 1024 // 10MB - maxFileSize = 1024 * 1024 // 1MB - basePath = "/var/restricted/" - ) - - // Calculate total size of uncompressed files - var totalSize uint64 - for _, f := range r.File { - totalSize += f.UncompressedSize64 - } - - // Check if total size exceeds the limit - if totalSize > totalAllowedSize { - log.Fatalf("archive exceeds total allowed size: %d\n", totalSize) + - **Do** implement checks to limit the zip archive's size. This prevents 'Zip Bombs', which are archives that decompress into sizes much larger than expected. For example, use `file.UncompressedSize64` to check the size of a file within a ZIP file. + - **Do** generate unique filenames for extracted files or sanitize the original filenames to avoid overwriting files intentionally. You can use `filepath.Base`, for example, to extract the filename from a path and discard any directory information. + ```go + name := filepath.Base(file.Name) + ``` + - **Do** validate the paths of extracted files to ensure they are written to a specified, trusted directory without traversing outside of it. + - **Do** process only regular files. Exclude symbolic links to prevent indirect file read/write vulnerabilities. + ```go + if !file.Mode().IsRegular() { + log.Fatal("non-regular file: %s\n", file.Name) } + ``` + - **Do** ensure directories within the zip archive are processed securely by cleaning the path and strictly validating it against the base path. - // Process files in the archive - for _, f := range r.File { - // Skip overlarge files - if f.UncompressedSize64 > maxFileSize { - log.Printf("skipping file as it exceeds maxFileSize: %s\n", f.Name) - continue - } - - // Skip if not a regular file - if !f.Mode().IsRegular() { - log.Printf("skipping non-regular file: %s\n", f.Name) - continue - } - - // Securely resolve the file path - name := filepath.Base(f.Name) - resolvedPath, err := filepath.Join(basePath, name) - if err != nil { - log.Fatal(err) - } - - // Ensure the file does not traverse outside the base path - if !strings.HasPrefix(resolvedPath, basePath) { - log.Fatal("path does not start with basePath") - } - - // Extract and process the file (omitted for brevity) - } - } - ``` - - For processing directories within the zip archive, ensure to clean the path and validate it strictly against the base path. - - ## Resources + ## References - [Go Documentation: archive/zip package](https://pkg.go.dev/archive/zip) diff --git a/rules/go/gosec/http/http_serve.yml b/rules/go/gosec/http/http_serve.yml index 39a56bd2c..44fbda939 100644 --- a/rules/go/gosec/http/http_serve.yml +++ b/rules/go/gosec/http/http_serve.yml @@ -27,50 +27,30 @@ languages: - go metadata: description: "Usage of vulnerable 'serve' function" - remediation_message: | + remediation_message: |- ## Description - The `net/http` serve functions in Go, when used with default settings, are vulnerable to resource consumption attacks. Attackers can exploit this by creating numerous connections to the server, intentionally not completing data transfers or leaving connections open, which can exhaust the server's resources and prevent it from accepting new legitimate connections. + The default `serve` functions in Go's `net/http` package are susceptible to resource consumption attacks. This vulnerability arises when attackers flood the server with incomplete or persistent connections, depleting its resources and blocking new legitimate connections. ## Remediations - To mitigate such attacks, specific server configurations are necessary: - - ❌ Avoid Default Serve Functions for Production - - Functions like `http.ListenAndServe` and `http.Serve` should not be used in a production setting as they do not allow for timeout configurations. - - ✅ Configure Timeouts on Custom `http.Server` Object - - Create a custom `http.Server` object and set appropriate timeouts to prevent resource exhaustion. - - ```go - import ( - "net/http" - "time" - "log" - ) - - func main() { - srv := &http.Server{ - Addr: "localhost:8000", - ReadHeaderTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - WriteTimeout: 10 * time.Second, - IdleTimeout: 30 * time.Second, - } - - if err := srv.ListenAndServe(); err != nil { - log.Fatal(err) - } - } - ``` - - ✅ Use `http.TimeoutHandler` for Per Request Timeouts - - To set timeouts for individual requests, use the `http.TimeoutHandler` wrapper on your handlers. This ensures that the server does not wait indefinitely for a request to complete. - - ## Resources + - **Do not** use default serve functions like `http.ListenAndServe` and `http.Serve` in production environments. You cannot set timeouts for these functions, making the server vulnerable to attacks. + ```go + http.ListenAndServe(":8080", nil) // unsafe + ``` + - **Do** create a custom `http.Server` object with configured timeouts to safeguard against resource exhaustion. Set `ReadHeaderTimeout`, `ReadTimeout`, `WriteTimeout`, and `IdleTimeout` to appropriate values. + ```go + myServer := &http.Server{ + Addr: "localhost:8000", + ReadHeaderTimeout: 15 * time.Second, + ReadTimeout: 15 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 30 * time.Second, + } + ``` + - **Do** enforce timeouts on individual requests using `http.TimeoutHandler`. This wrapper ensures that the server does not indefinitely wait for a request to finish, preventing potential denial of service. + + ## References - [http.Server Timeouts Documentation](https://pkg.go.dev/net/http#Server) - [Guide to Setting Request-Based Timeouts](https://pkg.go.dev/net/http#TimeoutHandler) diff --git a/rules/go/gosec/http/http_slowloris.yml b/rules/go/gosec/http/http_slowloris.yml index 6c4144f8c..a7133b15f 100644 --- a/rules/go/gosec/http/http_slowloris.yml +++ b/rules/go/gosec/http/http_slowloris.yml @@ -93,50 +93,29 @@ languages: - go metadata: description: "Missing protection against 'Slowloris' attack" - remediation_message: | + remediation_message: |- ## Description - The server configuration lacks a `ReadHeaderTimeout`, making it vulnerable to a Slowloris attack. This type of attack occurs when an attacker opens multiple connections to the server but sends only partial requests. The server keeps each connection open, waiting for the headers to be completed, ultimately leading to resource exhaustion. + Your server configuration is missing the `ReadHeaderTimeout` setting, making it vulnerable to a type of Distributed Denial of Service (DDoS) attack known as a Slowloris attack. In such an attack, a hacker initiates many connections to your server, sending incomplete requests. Your server then keeps each connection open, waiting for the headers to be completed. This can lead to resource exhaustion, where your server cannot handle additional (legitimate) requests. ## Remediations - To protect against such attacks, the following steps should be taken: + - **Do not** use default serve functions like `http.ListenAndServe` and `http.Serve` in production environments. You cannot set timeouts for these functions, making the server vulnerable to attacks. + ```go + http.ListenAndServe(":8080", nil) // unsafe + ``` + - **Do** create a custom `http.Server` object with configured timeouts to safeguard against resource exhaustion. For Slowloris attacks in particular, set `ReadHeaderTimeout` to an appropriate value to ensure that connections do not remain open indefinitely. + ```go + myServer := &http.Server{ + Addr: "localhost:8000", + ReadHeaderTimeout: 15 * time.Second, + ReadTimeout: 15 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 30 * time.Second, + } + ``` - ❌ Avoid Default Serve Functions for Production - - Do not use `http.ListenAndServe` and `http.Serve` in a production environment, as they do not support timeout settings. - - ✅ Configure `http.Server` with Timeouts - - Establish a custom `http.Server` instance with appropriate timeouts to prevent attackers from exploiting the lack of `ReadHeaderTimeout`. - - ```go - import ( - "net/http" - "time" - "log" - ) - - func main() { - srv := &http.Server{ - Addr: "localhost:8000", - ReadHeaderTimeout: 15 * time.Second, - ReadTimeout: 15 * time.Second, - WriteTimeout: 10 * time.Second, - IdleTimeout: 30 * time.Second, - } - - if err := srv.ListenAndServe(); err != nil { - log.Fatal(err) - } - } - ``` - - ✅ Enforce Request Timeouts - - Implement `http.TimeoutHandler` to apply timeouts to individual HTTP handlers, which starts counting down only after the headers have been read. - - ## Resources + ## References - [Configuring Timeouts in http.Server](https://pkg.go.dev/net/http#Server) - [How to Set Request-Based Timeouts](https://pkg.go.dev/net/http#TimeoutHandler) diff --git a/rules/go/gosec/injection/ssrf_injection.yml b/rules/go/gosec/injection/ssrf_injection.yml index c70f6cc2c..78d6cccc9 100644 --- a/rules/go/gosec/injection/ssrf_injection.yml +++ b/rules/go/gosec/injection/ssrf_injection.yml @@ -25,100 +25,32 @@ languages: - go metadata: description: "Unsanitized user input in HTTP request (SSRF)" - remediation_message: | + remediation_message: |- ## Description - Server-Side Request Forgery (SSRF) is a security vulnerability that occurs when a server-side application makes HTTP requests to arbitrary URLs controlled by the user. SSRF can be exploited by attackers to target internal systems behind firewalls that are otherwise inaccessible from the external network, by tricking the server into making requests to these systems. + Including unsanitized user input in HTTP requests puts your application at risk of Server-Side Request Forgery (SSRF). This is a security vulnerability that occurs when a server-side application makes HTTP requests to arbitrary URLs controlled by the user. SSRF can be exploited by attackers to target internal systems behind firewalls that are otherwise inaccessible from the external network, by tricking the server into making requests to these systems. ## Remediations - To mitigate SSRF vulnerabilities, follow these guidelines: - - ✅ Validate User Input - - Avoid using direct user input to construct URLs for backend requests. If you must use user input, validate or sanitize it rigorously. - - ✅ Restrict URLs to Known Safe Domains - - Where possible, limit requests to a predefined set of safe URLs or domains. This can be done using server-side mapping from user-supplied keys to URLs. - - ✅ Implement IP Safelists and Blocklists - - Use an HTTP client that allows customizing and blocking specific IP ranges, such as private network addresses and other non-routable IP ranges. - - ✅ Use Network-Level Security - - If the HTTP client doesn't support IP range blocking, consider running it with restricted system permissions, or within a secure network where firewall rules can block dangerous addresses. - - ✅ Leverage a Secure HTTP Proxy - - As a last resort, route all backend HTTP requests through a secure proxy that can filter out and block requests to potentially harmful addresses. - - ```go - import ( - "context" - "crypto/tls" - "errors" - "net" - "net/http" - "time" - ) - - // IsDisallowedIP checks if an IP address falls within a range of disallowed IPs. - func IsDisallowedIP(hostIP string) bool { - ip := net.ParseIP(hostIP) - // Add more checks as necessary - return ip.IsMulticast() || ip.IsUnspecified() || ip.IsLoopback() || ip.IsPrivate() - } - - // SafeTransport defines a custom transport that filters out disallowed IP addresses. - func SafeTransport(timeout time.Duration) *http.Transport { - return &http.Transport{ - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - c, err := net.DialTimeout(network, addr, timeout) - if err != nil { - return nil, err - } - ip, _, _ := net.SplitHostPort(c.RemoteAddr().String()) - if IsDisallowedIP(ip) { - c.Close() - return nil, errors.New("ip address is not allowed") - } - return c, err - }, - DialTLS: func(network, addr string) (net.Conn, error) { - dialer := &net.Dialer{Timeout: timeout} - c, err := tls.DialWithDialer(dialer, network, addr, &tls.Config{}) - if err != nil { - return nil, err - } - ip, _, _ := net.SplitHostPort(c.RemoteAddr().String()) - if IsDisallowedIP(ip) { - c.Close() - return nil, errors.New("ip address is not allowed") - } - return c, c.Handshake() - }, - TLSHandshakeTimeout: timeout, - } - } - - // httpRequest performs a secure HTTP request, filtering out disallowed IPs. - func httpRequest(requestUrl string) { - const clientConnectTimeout = time.Second * 10 - httpClient := &http.Client{ - Transport: SafeTransport(clientConnectTimeout), - } - resp, err := httpClient.Get(requestUrl) - if err != nil { - log.Fatal(err) - } - defer resp.Body.Close() - // Process response - } - ``` - - ## Resources + - **Do not** use direct user input to construct URLs for backend requests. If user input is necessary, ensure it is strictly validated or sanitized to prevent malicious manipulation. + - **Do** use a safelist or predefined mapping when incorporating user input in URLs. This ensures that your application only redirects users to safe and intended destinations. + ```go + safeURLs := map[string]string{ + "key1": "https://safe-domain1.com", + "key2": "https://safe-domain2.com", + } + requestedKey := getUserInput() + if url, ok := safeURLs[requestedKey]; ok { + // continue with request + } else { + log.Fatal("Requested URL is not allowed") + } + ``` + - **Do** implement IP safelists and blocklists to customize and block specific IP ranges, especially those that are private, loopback, or otherwise non-routable. + - **Do** use network-level security measures. If your HTTP client does not support IP range blocking, run it with restricted system permissions or within a network environment where firewall rules can effectively block requests to dangerous addresses. + - **Do** consider using a secure HTTP proxy to route all backend HTTP requests. This proxy can serve as a filter to block requests to potentially harmful addresses, acting as an additional layer of security. + + ## References - [OWASP SSRF Prevention Cheat Sheet](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery) diff --git a/rules/go/gosec/injection/subproc_injection.yml b/rules/go/gosec/injection/subproc_injection.yml index 223f59402..7c334af26 100644 --- a/rules/go/gosec/injection/subproc_injection.yml +++ b/rules/go/gosec/injection/subproc_injection.yml @@ -26,72 +26,30 @@ languages: severity: critical metadata: description: Unsanitized dynamic input in OS command - remediation_message: | + remediation_message: |- ## Description - OS command injection is a severe security vulnerability that occurs when an application incorrectly processes external input. This flaw can allow attackers to execute arbitrary commands on the host operating system, potentially leading to a full system compromise. + Using unsanitized dynamic or external input in an OS command is a critical security flaw that can enable attackers to execute unauthorized commands on the host operating system, potentially leading to a complete system takeover. ## Remediations - Prevent OS command injection by adhering to the following practices: - - ❌ Avoid Direct External Input - - Do not use externally-supplied information for constructing OS commands or command-line arguments, as this can lead to command injection vulnerabilities. - - ✅ Implement Input Validation - - Ensure that any external input is validated against a set of strict rules to ensure it does not contain malicious characters or patterns. - - ✅ Use Hardcoded Arguments - - When invoking OS commands, use a hardcoded set of arguments to ensure that external input cannot alter the command's behavior. - - ✅ Utilize Temporary Files Securely - - When dealing with files, create temporary files in a restricted directory, avoiding the use of user-supplied filenames. - - ✅ Employ Native Libraries - - Where possible, use native libraries or features of the programming language instead of invoking shell commands, which can be safer and more efficient. - - ```go - import ( - "io/ioutil" - "os/exec" - "log" - ) - - func main() { - userData := []byte("user data") - - // Create a temporary file in a secure, application-specific directory - f, err := ioutil.TempFile("/var/app/restricted", "temp-*.dat") - if err != nil { - log.Fatal(err) - } - - // Write user data to the temporary file - if _, err := f.Write(userData); err != nil { - f.Close() - log.Fatal(err) - } - - // Close the file handle - if err := f.Close(); err != nil { - log.Fatal(err) - } - - // Execute a command using the temporary file, avoiding direct external input for filenames - out, err := exec.Command("/bin/cat", f.Name()).Output() - if err != nil { - log.Fatal(err) - } - // Output can be used for further processing - } - ``` - - ## Resources + - **Do not** construct OS commands or command-line arguments using externally-supplied information. This practice can introduce command injection vulnerabilities. + ```go + cmd := exec.Command("bash", "-c", "echo " + externalInput) // unsafe + ``` + - **Do** validate all external input against a strict set of rules to ensure it does not include harmful characters or patterns. + ```go + if !regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString(externalInput) { + log.Fatal("Invalid input") + } + ``` + - **Do** use hardcoded arguments when invoking OS commands to prevent external input from altering the command's execution. + ```go + cmd := exec.Command("ls", "-l", "/var/log") + ``` + - **Do** prefer native libraries or programming language features over invoking shell commands for enhanced security and efficiency. + + ## References - [OWASP OS Command Injection Defense Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html) cwe_id: diff --git a/rules/go/gosec/injection/template_injection.yml b/rules/go/gosec/injection/template_injection.yml index dff35d512..e26aefebb 100644 --- a/rules/go/gosec/injection/template_injection.yml +++ b/rules/go/gosec/injection/template_injection.yml @@ -21,73 +21,27 @@ languages: - go metadata: description: "Unsanitized user input in web page generation (XSS)" - remediation_message: | + remediation_message: |- ## Description Cross-Site Scripting (XSS) is a vulnerability that allows attackers to run malicious scripts in the context of a trusted web application. This can happen when an application includes untrusted data without proper validation or escaping. There are several contexts where XSS can occur, each requiring specific encoding strategies to mitigate the risk. ## Remediations - To defend against XSS attacks, consider the following measures: + - **Do** encode user input based on the context it is used in, such as HTML content, HTML attributes, JavaScript, and CSS contexts. This helps prevent malicious scripts from being executed. + ```go + html.EscapeString(userInput) + ``` + - **Do** use templating engines like `html/template` that automatically encode data based on its context. + - **Do** sanitize data using libraries or functions specifically designed for this purpose, especially when inserting content into a web page. + - **Do** separate data from code by avoiding inline scripting and event handlers. Use separate JavaScript files for event handling to minimize script injection risks. + - **Do not** mix server-side and client-side templating systems, as server-side systems may not escape output safely for client-side use. + - **Do not** encode user input before storing it in a database. Any encoding should be applied when the data is output, not before storage, to ensure that it is encoded appropriately for its context. - ✅ Encode Based on Context - - When user input is reflected back in HTML, ensure it is encoded based on the context in which it is used (e.g., HTML content, HTML attributes, JavaScript context, CSS context, etc.). - - ✅ Template Safely - - Utilize templating engines that automatically encode data based on context, and be cautious not to override these safeguards. - - ✅ Sanitize Data - - Use libraries or functions designed to sanitize user input, particularly when inserting content into a web page. - - ✅ Separate Data from Code - - Avoid inline scripting and event handlers, and instead use separate JavaScript files to handle events. This reduces the risk of script injection through event attributes. - - ✅ Avoid Mixing Templating Systems - - Do not mix server-side and client-side templating systems, as server-side systems may not escape output in a way that is safe for client-side use. - - ❌ Do Not Encode Before Storing - - Avoid encoding user input before storing it in a database. The encoding should be applied when the data is output, not before storage, to ensure that it is encoded appropriately for its context. - - Here's an example of using Go’s `html/template` package to safely render HTML content: - - ```go - import ( - "html/template" - "os" - "log" - ) - - func main() { - // Define a template with a function to safely render HTML - testTemplate, err := template.New("testTemplate").Funcs(template.FuncMap{ - "SafeHTML": func() template.HTML { - const safeHTML = "
hardcoded, safe html
" - return template.HTML(safeHTML) - }, - }).Parse(`{{ SafeHTML }}`) - - if err != nil { - log.Fatal(err) - } - - // Execute the template and ensure proper encoding - if err := testTemplate.Execute(os.Stdout, nil); err != nil { - log.Fatal(err) - } - } - ``` - - ## Resources + ## References - [OWASP XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html) - [Go html/template Documentation](https://pkg.go.dev/html/template) - - [CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')](https://cwe.mitre.org/data/definitions/79.html) cwe_id: - 79 diff --git a/rules/go/gosec/leak/pprof_endpoint.yml b/rules/go/gosec/leak/pprof_endpoint.yml index 9af4fe72d..bcb6981c9 100644 --- a/rules/go/gosec/leak/pprof_endpoint.yml +++ b/rules/go/gosec/leak/pprof_endpoint.yml @@ -8,50 +8,19 @@ languages: - go metadata: description: "Usage of active debug code (pprof enabled)" - remediation_message: | + remediation_message: |- ## Description - Go's standard library includes a profiling tool that can be enabled by importing `net/http/pprof`. This tool provides a `/debug/pprof` endpoint that exposes runtime profiling data over HTTP. When enabled in a production environment, it can present a significant security risk as it lacks authentication controls and can potentially leak sensitive information about the application's runtime state and environment. + Enabling Go's `net/http/pprof` in production environments exposes runtime profiling data via a `/debug/pprof` endpoint, creating a security vulnerability. This tool is part of Go's standard library and, while useful for debugging, it does not have authentication controls. This can lead to sensitive information leaks about the application's runtime state and environment if left accessible in production. ## Remediations - To prevent unintended exposure of profiling information: + - **Do not** include `net/http/pprof` in your production code. Remove any imports of this package before deploying to ensure the profiling endpoint is not exposed. + - **Do** use build tags for conditional compilation, and only allow profiling in non-production builds. + - **Do** configure environment-specific settings to enable or disable profiling endpoints based on the deployment environment. + - **Do** implement strong authentication mechanisms if profiling must be enabled in a controlled production scenario to secure the endpoint. - ✅ Remove `net/http/pprof` in Production - - Before deploying your application to a production environment, remove any import statements for `net/http/pprof` from your codebase. Ensure that the profiling endpoint is not available in the live environment. - - ```go - // +build !production - - package main - - import ( - _ "net/http/pprof" // Ensure this line is not present in your production builds - "net/http" - ) - - func main() { - // ... your application code ... - - // Start the server (omit the pprof import and handler in production) - log.Println(http.ListenAndServe("localhost:6060", nil)) - } - ``` - - ✅ Conditional Compilation - - Use build tags to include profiling only in non-production builds. - - ✅ Use Environment Configurations - - Configure environment-specific settings to conditionally enable or disable the profiling endpoints. - - ✅ Implement Authentication - - If profiling is necessary in a controlled production scenario, secure the endpoint with strong authentication mechanisms. - - ## Resources + ## References - [Go net/http/pprof Package Documentation](https://pkg.go.dev/net/http/pprof) - [Go Build Constraints Documentation](https://pkg.go.dev/go/build#hdr-Build_Constraints) diff --git a/rules/go/gosec/memory/integer_overflow.yml b/rules/go/gosec/memory/integer_overflow.yml index aba7727b4..2aec32544 100644 --- a/rules/go/gosec/memory/integer_overflow.yml +++ b/rules/go/gosec/memory/integer_overflow.yml @@ -15,54 +15,25 @@ languages: - go metadata: description: "Possible integer overflow" - remediation_message: | + remediation_message: |- ## Description - In Go, the size of the `int` type varies with the system architecture: it's 32 bits on a 32-bit system and 64 bits on a 64-bit system. This variability can lead to integer overflow issues when a value returned from `strconv.Atoi` is cast to a smaller integer type, such as `int32` or `int16`, and the original number exceeds the maximum value that can be stored in the smaller type. Integer overflow can cause erratic behavior and potentially serious bugs. + In Go, the size of an `int` type is not fixed and depends on the system architecture (32 bits on a 32-bit system and 64 bits on a 64-bit system). This can lead to integer overflow when a value is converted from `strconv.Atoi` to a smaller integer type like `int32` or `int16`, and the value exceeds what the smaller type can hold. Integer overflow can result in unpredictable behavior and severe bugs. ## Remediations - To prevent integer overflow and ensure safe type conversion: - - ✅ Check Values Before Conversion - - Before casting an `int` to a smaller type, compare it against the maximum values that the target type can hold. - - ```go - import ( - "strconv" - "fmt" - "log" - "math" - ) - - func main() { - // Convert the string to an int - bigValue, err := strconv.Atoi("32768") - if err != nil { - log.Fatal(err) - } - - // Ensure the value does not exceed int16's maximum limit - if bigValue > math.MaxInt16 { - log.Fatal("value too large to fit in int16") + - **Do** check values before conversion to a smaller type. Ensure the value does not exceed the maximum value the target type can hold. + - **Do** always handle errors from conversion functions like `strconv.Atoi` to promptly address and manage conversion issues. + - **Do** use fixed-size types like `int32` or `int64` when possible to avoid overflow issues that arise from architecture-dependent sizes. + ```go + if intValue, err := strconv.Atoi(stringValue); err == nil { + if intValue >= math.MinInt16 && intValue <= math.MaxInt16 { + int16Value := int16(intValue) + } } + ``` - // Safely convert to int16 - value := int16(bigValue) - fmt.Println(value) - } - ``` - - ✅ Use Appropriate Types - - Where possible, use fixed-size types like `int32` or `int64` to avoid overflow issues related to architecture-dependent sizes. - - ✅ Handle Errors - - Always handle errors returned from conversion functions like `strconv.Atoi` to detect and manage conversion issues immediately. - - ## Resources + ## References - [Go math package for integer limits](https://pkg.go.dev/math#pkg-constants) cwe_id: diff --git a/rules/go/gosec/memory/math_big_rat.yml b/rules/go/gosec/memory/math_big_rat.yml index 2b0171be3..6ad9ac852 100644 --- a/rules/go/gosec/memory/math_big_rat.yml +++ b/rules/go/gosec/memory/math_big_rat.yml @@ -23,46 +23,31 @@ languages: - go metadata: description: "Possible integer overflow when converting strings" - remediation_message: | + remediation_message: |- ## Description - When converting strings to integers using `strconv.Atoi` in Go, there's a risk of integer overflow if the result is assigned to a smaller integer type such as `int16` or `int32`. The size of the default `int` type in Go is platform-dependent—64 bits on a 64-bit system and 32 bits on a 32-bit system. Overflow can occur when the value returned from `strconv.Atoi` exceeds the range of the target integer type. + When you convert strings to integers in Go using `strconv.Atoi`, you might encounter an integer overflow if you assign the result to a smaller integer type like `int16` or `int32`. This is because the size of `int` type in Go is not fixed and depends on the system architecture (32 bits on a 32-bit system and 64 bits on a 64-bit system). An overflow occurs if the `strconv.Atoi` return value is too large for the intended smaller integer type. ## Remediations - ✅ Check Before Conversion - - Always verify that the value returned from `strconv.Atoi` is within the range of the target type before conversion. - - ```go - if intValue, err := strconv.Atoi(stringValue); err == nil { + - **Do** verify the value from `strconv.Atoi` fits within the range of your target integer type before conversion. + ```go + if intValue, err := strconv.Atoi(stringValue); err == nil { if intValue >= math.MinInt16 && intValue <= math.MaxInt16 { - int16Value := int16(intValue) - // Use int16Value safely + int16Value := int16(intValue) } - } - ``` - - ✅ Use Specific Type Conversion Functions - - Use type-specific parsing functions such as `strconv.ParseInt` with the appropriate bit size to directly obtain the desired type. - - ```go - if int64Value, err := strconv.ParseInt(stringValue, 10, 16); err == nil { + } + ``` + - **Do** use type-specific parsing functions like `strconv.ParseInt` with the appropriate bit size to ensure you get the type you need. + ```go + if int64Value, err := strconv.ParseInt(stringValue, 10, 16); err == nil { int16Value := int16(int64Value) - // Use int16Value safely - } - ``` - - ❌ Avoid Blind Type Casting - - Do not cast the result of `strconv.Atoi` to a smaller integer type without validating that the value fits within the smaller type's range. - - ❌ Don't Ignore Errors - - Never ignore the error returned by `strconv.Atoi`. Always handle it to catch conversion issues, including potential overflows. + } + ``` + - **Do not** cast the result of `strconv.Atoi` to a smaller integer type without ensuring the value is within the acceptable range for that type. + - **Do not** ignore errors from `strconv.Atoi`. Always handle them to detect conversion problems, including possible overflows. - ## Resources + ## References - [Go strconv package](https://pkg.go.dev/strconv) - [Go math package for min/max constants](https://pkg.go.dev/math#pkg-constants) diff --git a/rules/go/gosec/memory/memory_aliasing.yml b/rules/go/gosec/memory/memory_aliasing.yml index 6abe64357..0ff0392d4 100644 --- a/rules/go/gosec/memory/memory_aliasing.yml +++ b/rules/go/gosec/memory/memory_aliasing.yml @@ -20,43 +20,30 @@ languages: - go metadata: description: Usage of single iteration variable in range loop - remediation_message: | + remediation_message: |- ## Description - Go's `for ... range` constructs allocate a single iteration variable for the loop's duration, which can cause confusion when addresses of this variable are stored or used beyond a single iteration. Since the iteration variable's address remains constant, subsequent iterations overwrite the previously referenced values, leading to unexpected results, particularly when using go routines or deferred functions within the loop. + In Go, using the `for ... range` loop with a single iteration variable can lead to errors. This happens because the loop uses the same memory address for the iteration variable throughout its execution. When you store or use the address of this variable across different iterations, it can overwrite values unexpectedly. This issue is especially problematic in concurrent operations or when deferring functions inside the loop. ## Remediations - ✅ Create a New Variable Inside the Loop - - Declare a new local variable within the loop's scope to hold the iteration value. This ensures a unique address is used for each iteration. - - ```go - for _, n := range []someStruct{{1}, {2}, {3}, {4}} { - localVar := n - // Use localVar instead of n - } - ``` - - ✅ Use Indexed Addressing - - Instead of the iteration variable, directly reference the indexed element within the array or slice. - - ```go - for i := range mySlice { - // Use &mySlice[i] to obtain a stable address - } - ``` - - ❌ Do Not Store the Address of the Iteration Variable - - Avoid taking the address of the iteration variable and storing it, as it leads to all references pointing to the same memory location. - - ❌ Avoid Using the Iteration Variable's Address in Goroutines - - Using the iteration variable's address directly in goroutines can cause race conditions or logical errors, as the variable's value may change before the goroutine accesses it. - - ## Resources + - **Do** create a new variable inside the loop to ensure each iteration uses a unique memory address. + ```go + for _, n := range []someStruct{{1}, {2}, {3}, {4}} { + localVar := n + // use localVar instead of n + } + ``` + - **Do** use indexed addressing to directly reference the elements in an array or slice, avoiding the shared address problem. + ```go + for i := range mySlice { + // use &mySlice[i] for a stable address + } + ``` + - **Do not** store the address of the iteration variable. This practice leads to all references pointing to the same location in memory, causing errors. + - **Do not** use the iteration variable's address in goroutines. This can result in race conditions or logical errors if the variable's value changing before the goroutine accesses it. + + ## References - [Go For Statements](https://go.dev/ref/spec#For_statements) cwe_id: diff --git a/rules/go/gosec/network/bind_to_all_interfaces.yml b/rules/go/gosec/network/bind_to_all_interfaces.yml index 9466b6b7c..68ddf4ef1 100644 --- a/rules/go/gosec/network/bind_to_all_interfaces.yml +++ b/rules/go/gosec/network/bind_to_all_interfaces.yml @@ -11,47 +11,21 @@ languages: - go metadata: description: "Permissive server network interface configuration" - remediation_message: | + remediation_message: |- ## Description - Binding to "0.0.0.0" allows a service to accept connections on all network interfaces. While this can be useful for services meant to be widely accessible, it can also unintentionally expose the service on network interfaces that are not secure or intended for such traffic, potentially leading to security vulnerabilities. + Binding a service to "0.0.0.0" makes it accessible on all network interfaces. This configuration can lead to unintended exposure over insecure or unintended network interfaces, creating potential security risks. ## Remediations - To mitigate the risks associated with binding to all network interfaces: + - **Do not** bind services to "0.0.0.0" without considering the security implications. This default setting can expose your service on all network interfaces, including those that are not secure. + - **Do** bind your service to a specific IP address or network interface to limit access and enhance security. This can be achieved through various methods: + - Specify the IP address using an environment variable for flexible and secure configuration. + - Define the IP address in a configuration file that the application reads at startup. + - Dynamically identify the appropriate network interface and bind the service to its IP address. + - **Do** implement security best practices when configuring network services. Use firewalls to control access and encrypt communication with TLS to protect data in transit. - ✅ Bind to a Specific Interface - - Configure your service to listen on a specific IP address or network interface. This can be controlled through: - - - **Environment Variable**: Use an environment variable to specify the IP address, making the configuration more flexible and secure. - - **Configuration File**: Define the IP address in a configuration file which the application reads at startup. - - **Programmatic Identification**: Programmatically determine the appropriate network interface and bind the service to its IP address. - - ```go - import ( - "net" - "os" - "log" - ) - - func main() { - // Retrieve the IP address from an environment variable - addr := os.Getenv("IP_ADDRESS") - - // Listen on the specified interface - listener, err := net.Listen("tcp", addr) - if err != nil { - log.Fatalf("Failed to listen on %s: %v", addr, err) - } - - // Continue to set up your server (e.g., http.Serve(listener, handler)) - } - ``` - - ✅ **Security Best Practices**: Always follow security best practices when configuring network services, such as using firewalls to restrict access and encrypting traffic with TLS. - - ## Resources + ## References - [Go net package](https://pkg.go.dev/net) - [Go os package for environment variables](https://pkg.go.dev/os) diff --git a/rules/go/gosec/secrets/secrets.yml b/rules/go/gosec/secrets/secrets.yml index b54c3a23e..6448ccfe4 100644 --- a/rules/go/gosec/secrets/secrets.yml +++ b/rules/go/gosec/secrets/secrets.yml @@ -50,40 +50,21 @@ languages: severity: critical metadata: description: Usage of hard-coded secret - remediation_message: | + remediation_message: |- ## Description - Storing sensitive information such as secret keys, passwords, or API tokens directly in source code can lead to security vulnerabilities. This practice makes it easy for malicious actors to access these secrets if the codebase is exposed or improperly accessed. + Storing secrets like keys, passwords, or API tokens in your source code introduces a significant security risk. If your code is exposed or accessed improperly, these secrets can be easily obtained by attackers. ## Remediations - To protect sensitive information: + - **Do** implement dynamic secret retrieval. Fetch secrets at runtime from a secure source instead of embedding them in your source files. + - **Do** use environment variables to provide secrets to your application at runtime, keeping them out of your source code. + - **Do** utilize secrets management systems. These tools securely store and handle sensitive information away from your codebase. + - **Do** store secrets in encrypted configuration files. Decrypt these secrets only within the application at runtime. + - **Do** ensure strict access control for the storage locations of your secrets to prevent unauthorized access. + - **Do** regularly audit and rotate secrets to reduce risks in case they are compromised. - ✅ Dynamic Secret Retrieval - - Implement mechanisms to retrieve secrets dynamically at runtime from a secure source rather than hardcoding them in the source files. - - ✅ Environment Variables - - Use environment variables to inject secrets into the application at runtime, keeping them out of the codebase. - - ✅ Secrets Management Systems - - Utilize dedicated secrets management tools and services that securely store and manage sensitive information. - - ✅ Encrypted Configuration Files - - Store secrets in configuration files that are encrypted and decrypt them at runtime within the application. - - ✅ Access Control - - Ensure that the storage location for secrets has strict access controls to prevent unauthorized access. - - ✅ Audit and Rotate Secrets - - Regularly audit access to secrets and rotate them to minimize the risk if they are compromised. - - ## Resources + ## References - [OWASP: Use of Hard-coded Passwords](https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password) - [OWASP: Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html#21-high-availability) diff --git a/rules/go/gosec/sql/concat_sqli.yml b/rules/go/gosec/sql/concat_sqli.yml index f53309f59..d83dbc6d6 100644 --- a/rules/go/gosec/sql/concat_sqli.yml +++ b/rules/go/gosec/sql/concat_sqli.yml @@ -126,35 +126,20 @@ languages: severity: critical metadata: description: "Unsanitized user input in SQL query" - remediation_message: | + remediation_message: |- ## Description - SQL Injection represents a severe vulnerability that can culminate in the compromise of data or entire systems. When SQL query strings are crafted dynamically based on user inputs, there's potential for malicious users to manipulate the logic of the SQL statement. Such tampering could provide adversaries unauthorized access to sensitive data or even allow them to execute system-level operations or code. + SQL Injection is a critical vulnerability that arises when SQL queries are dynamically constructed using unsanitized user input. This flaw allows attackers to alter the intended logic of SQL statements, potentially leading to unauthorized access to sensitive data or the execution of arbitrary code on the system. ## Remediations - ✅ Use Parameterized Queries + - **Do** use parameterized queries to prevent SQL injection. This method ensures that user input is treated as data, not as part of the SQL command, effectively neutralizing the threat. + ```go + db.Query("SELECT * FROM users WHERE userName = ?", userName) + ``` + - **Do not** use direct user input in dynamic queries. If you must create dynamic queries, use a predefined map or dictionary of valid values (a safelist). This approach allows you to safely include user input by translating it into safe, predefined commands or values. - Always opt for parameterized queries over dynamically generated SQL queries to prevent SQL injection. - - ```go - rows, err := db.Query("SELECT * FROM users WHERE userName = ?", userName) - if err != nil { - return nil, err - } - defer rows.Close() - for rows.Next() { - // ... process rows - } - ``` - - ✅ Avoid Direct User Input in Dynamic Queries - - If there's an absolute need to formulate dynamic queries, ensure that direct user input is never utilized. Instead, leverage a map or dictionary containing valid values and determine them through a user-provided key. - - For instance, certain database drivers do not support parameterized queries for operators like `>` or `<`. Instead of directly using user-input values, allow users to provide substitutes like `gt` for `>` and `lt` for `<`. Subsequently, use these alphabetical inputs to retrieve the actual operators for your query. Implement a similar approach for queries requiring non-parameterizable column or table names. - - ## Resources + ## References - [OWASP SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html) cwe_id: diff --git a/rules/go/gosec/subproc/subproc.yml b/rules/go/gosec/subproc/subproc.yml index b35bda49c..1366bd41d 100644 --- a/rules/go/gosec/subproc/subproc.yml +++ b/rules/go/gosec/subproc/subproc.yml @@ -56,24 +56,17 @@ languages: severity: critical metadata: description: Unsanitized external input in code execution - remediation_message: | + remediation_message: |- ## Description - Code injection is a security vulnerability where untrusted (external or user) data is injected into a program or interpreted as part of its execution flow, leading to unintended and potentially harmful consequences. + Unsanitized external input in code execution can result in code injection. This vulnerability arises when external or user-provided data is directly used in the execution flow of a program without proper sanitization, potentially leading to unauthorized actions or access. ## Remediations - Prevent code injection by adhering to the following practices: + - **Do not** pass unsanitized external input directly to execution functions. This practice can introduce code injection vulnerabilities. + - **Do** implement thorough input validation. Ensure all external input is checked against a strict set of rules to verify it does not contain harmful characters or patterns. - ❌ Never pass raw external input to - - Do not use externally supplied values when executing remote code, as this can lead to code injection vulnerabilities. - - ✅ Implement Input Validation - - Ensure that any external input is validated against a set of strict rules to ensure it does not contain malicious characters or patterns. - - ## Resources + ## References - [OWASP Code injection explained](https://owasp.org/www-community/attacks/Code_Injection) cwe_id: diff --git a/rules/go/gosec/unsafe/unsafe.yml b/rules/go/gosec/unsafe/unsafe.yml index 658baf06d..ea640e9d8 100644 --- a/rules/go/gosec/unsafe/unsafe.yml +++ b/rules/go/gosec/unsafe/unsafe.yml @@ -7,30 +7,27 @@ languages: - go metadata: description: "Usage of vulnerable 'unsafe' package" - remediation_message: | + remediation_message: |- ## Description - The Go programming language features the `unsafe` package which grants low-level memory management capabilities, inclusive of direct memory access and pointer manipulation. Though the `unsafe` package can be quite potent, its usage sidesteps the Go compiler's type safety checks. This can lead to an array of security vulnerabilities and unpredictable system behavior. + The `unsafe` package in Go allows for low-level memory management, including direct memory access and pointer manipulation. While `unsafe` is a powerful library, using it bypasses Go's type safety checks and opens the door to security vulnerabilities and unpredictable behavior in your application. ## Remediations - ✅ Avoid `unsafe` Unless Absolutely Necessary - - The overarching guidance here is to steer clear of the `unsafe` package unless there's an absolute necessity for its functions. When opting for low-level memory operations, ensure that their implications are well-understood and that their deployment is preceded by rigorous testing. - - ✅ Be Wary of Buffer Overflows - - Direct manipulation of memory can lead to buffer overflows, potentially enabling unauthorized code execution. Ensure buffer boundaries are always respected. - - ✅ Avoid Use After Free - - Accessing memory that has already been freed can result in unintended code execution or unpredictable behaviors. Ensure that once memory has been freed, it isn't accessed further. - - ✅ Prevent Information/Memory Leaks - - Unintended memory retention or unintended disclosure of information in memory can occur when using unsafe functions. This can compromise other security defenses or lead to system failures due to exhausted memory. Regularly review and audit your code to check for such leaks. - - ## Resources + - **Do not** use the `unsafe` package unless it is absolutely necessary. If you must use it, ensure you fully understand the implications and thoroughly test your code. + - **Do** ensure buffer boundaries are respected to avoid buffer overflows. This precaution helps prevent unauthorized code execution. + ```go + buffer := make([]byte, 10) + ``` + - **Do not** access memory after it has been freed to avoid use-after-free vulnerabilities, which can lead to unintended code execution or unpredictable system behavior. + ```go + unsafePointer := unsafe.Pointer(&data) + C.free(unsafePointer) + // now unsafe to access + ``` + - **Do** regularly review and audit your code to prevent memory or information leaks that could compromise security or lead to system failures due to exhausted memory. + + ## References - [Buffer Overflows - OWASP](https://owasp.org/www-community/vulnerabilities/Buffer_Overflow) - [Using Freed Memory - OWASP](https://owasp.org/www-community/vulnerabilities/Using_freed_memory) diff --git a/rules/go/lang/cookie_missing_http_only.yml b/rules/go/lang/cookie_missing_http_only.yml index 585c51a1e..0f352dd10 100644 --- a/rules/go/lang/cookie_missing_http_only.yml +++ b/rules/go/lang/cookie_missing_http_only.yml @@ -34,32 +34,25 @@ languages: - go metadata: description: Missing HTTP Only option in cookie configuration - remediation_message: | + remediation_message: |- ## Description - When set to "true", the "HttpOnly" attribute protects the cookie value from being accessed by client side JavaScript such as reading the "document.cookie" values. - By enabling this protection, a website that is vulnerable to Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing the cookie value from JavaScript. + Missing the HTTP Only option in cookie configuration exposes cookies to client-side script access. This vulnerability occurs when cookies are set without the `HttpOnly` attribute, allowing them to be accessible via JavaScript. This can lead to sensitive information being compromised, especially if the site is susceptible to Cross-Site Scripting (XSS) attacks. ## Remediations - To enhance cookie security and protect against common web exploits: - - ✅ Set the `HttpOnly` attribute for cookies to `true`. This prevents client-side scripts from accessing the cookie, reducing the risk of client-side attacks. - - ```go - http.SetCookie(w, &http.Cookie{ - Name: "session_token", - Value: sessionToken, - HttpOnly: true, // Secure the cookie from client-side scripts - // Additional flags like Secure, SameSite, etc., should be set as needed. - }) - ``` - - ✅ Alongside `HttpOnly`, consider setting `Secure`, `SameSite`, and `Domain` attributes to further secure cookies based on your application’s requirements. - - ## Resources - - For best practices on setting cookies securely, explore: + - **Do** set the `HttpOnly` attribute for cookies to `true`. This action prevents client-side scripts from accessing the cookie, significantly reducing the risk of XSS attacks. + ```go + http.SetCookie(w, &http.Cookie{ + Name: "session_token", + Value: sessionToken, + HttpOnly: true, + ... + }) + ``` + - **Do** also consider setting `Secure`, `SameSite`, and `Domain` attributes for cookies. These additional configurations help in further securing cookies against various web vulnerabilities, tailoring the protection to your application's specific needs. + + ## References - [OWASP Secure Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html) - [MDN Web Docs: HttpOnly Cookie Attribute](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) diff --git a/rules/go/lang/deserialization_of_user_input.yml b/rules/go/lang/deserialization_of_user_input.yml index 736ef8146..a9a38e151 100644 --- a/rules/go/lang/deserialization_of_user_input.yml +++ b/rules/go/lang/deserialization_of_user_input.yml @@ -39,21 +39,18 @@ languages: - go metadata: description: Unsanitized user input in deserialization method - remediation_message: | + remediation_message: |- ## Description - It is bad practice to deserialize untrusted data, such as data that comes - from external sources like user input or request parameters, without sufficient - verification. Attackers can transfer payloads or malicious code via serialized - data, and deserializing such data puts your application at risk. + Deserializing data from untrusted sources, like user inputs or request parameters, without proper verification is a security risk. Attackers can embed malicious code or payloads within serialized data. When your application deserializes this data without checks, it becomes vulnerable to attacks. ## Remediations - ❌ Do not deserialize untrusted data + - **Do not** deserialize data from untrusted sources directly. This can lead to security vulnerabilities. + - **Do** validate and sanitize all data before deserializing it. Ensure that the data is coming from a trusted source and is in the expected format. - ✅ Validate and sanitize data before attempting to (de)serialize it + ## References - ## Resources - [OWASP Deserialization cheat sheet](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html) cwe_id: - 502 diff --git a/rules/go/lang/hardcoded_mysql_database_password.yml b/rules/go/lang/hardcoded_mysql_database_password.yml index 0f6696759..8444fc511 100644 --- a/rules/go/lang/hardcoded_mysql_database_password.yml +++ b/rules/go/lang/hardcoded_mysql_database_password.yml @@ -36,12 +36,19 @@ languages: - go metadata: description: "Usage of hard-coded MySQL database password" - remediation_message: | + remediation_message: |- ## Description - Hardcoded password used in database connection string detected. Code is not a safe place to store passwords like this; use environment variables or a key-management system instead. + Your code contains a hard-coded password for MySQL database connections. Storing passwords directly in code compromises security and makes your application vulnerable to unauthorized access. + + ## Remediations + + - **Do not** embed passwords directly in your code. This practice is insecure and exposes your database to potential breaches. + - **Do** use environment variables to store sensitive information such as database passwords. This method keeps credentials out of your codebase and makes them easier to manage securely. + - **Do** consider implementing a key-management system to securely handle passwords and other sensitive information. This approach provides enhanced security measures for managing and accessing credentials. + + ## References - ## Resources - [OWASP hardcoded passwords](https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password) cwe_id: - 259 diff --git a/rules/go/lang/hardcoded_pg_database_password.yml b/rules/go/lang/hardcoded_pg_database_password.yml index 8c8da8152..54031b1dc 100644 --- a/rules/go/lang/hardcoded_pg_database_password.yml +++ b/rules/go/lang/hardcoded_pg_database_password.yml @@ -36,12 +36,19 @@ languages: - go metadata: description: "Usage of hard-coded PostgreSQL database password" - remediation_message: | + remediation_message: |- ## Description - Hardcoded password used in database connection string detected. Code is not a safe place to store passwords like this; use environment variables or a key-management system instead. + Your code contains a hard-coded password for connecting to a PostgreSQL database. Storing passwords directly in the code compromises security and makes your application vulnerable to unauthorized access. + + ## Remediations + + - **Do not** embed passwords directly in your database connection strings or code. This practice exposes your database to potential security breaches. + - **Do** use environment variables to store sensitive information such as database passwords. This method keeps credentials out of your codebase and makes them easier to manage securely. + - **Do** consider implementing a key-management system to securely handle passwords and other sensitive information. This approach provides enhanced security measures for managing and accessing credentials. + + ## References - ## Resources - [OWASP hardcoded passwords](https://owasp.org/www-community/vulnerabilities/Use_of_hard-coded_password) cwe_id: - 259 diff --git a/rules/go/lang/html_tag_injection.yml b/rules/go/lang/html_tag_injection.yml index af7e85598..f7232f73e 100644 --- a/rules/go/lang/html_tag_injection.yml +++ b/rules/go/lang/html_tag_injection.yml @@ -59,33 +59,26 @@ languages: - go metadata: description: "Missing sanitization of HTML template tags" - remediation_message: | + remediation_message: |- ## Description - Failing to sanitize user input can allow attackers to inject HTML tags (like `