diff --git a/precli/rules/go/stdlib/crypto/weak_cipher.py b/precli/rules/go/stdlib/crypto/weak_cipher.py new file mode 100644 index 00000000..84a59f72 --- /dev/null +++ b/precli/rules/go/stdlib/crypto/weak_cipher.py @@ -0,0 +1,171 @@ +# Copyright 2023 Secure Saurce LLC +r""" +================================================================== +Use of a Broken or Risky Cryptographic Algorithm in Crypto Package +================================================================== + +Using weak ciphers for cryptographic algorithms can pose significant security +risks, and it's generally advised to avoid them in favor of stronger, more +secure algorithms. Here's some guidance that advises against using weak +ciphers like DES and RC4: + +1. **NIST Recommendations**: The National Institute of Standards and +Technology (NIST) is a widely recognized authority on cryptographic standards. +NIST advises against using weak ciphers in their Special Publication +800-175B: "Guide to Secure Web Services." They recommend the use of stronger +ciphers like AES (Advanced Encryption Standard) and SHA-256 for cryptographic +purposes. + +2. **IETF Standards**: The Internet Engineering Task Force (IETF) publishes +standards and guidelines for secure network communication. IETF has deprecated +or discouraged the use of weak ciphers in various RFCs (Request for +Comments). For example, RFC 7465 advises against using SSLv3 and RC4 due to +their vulnerabilities. + +3. **OWASP Guidelines**: The Open Web Application Security Project (OWASP) +provides guidelines for secure web applications. Their guidance explicitly +recommends avoiding weak ciphers, including DES and RC4 due to known security +weaknesses. + +4. **PCI DSS Compliance**: The Payment Card Industry Data Security Standard +(PCI DSS) mandates the use of strong cryptographic algorithms. Using weak +ciphers is discouraged and can lead to non-compliance with PCI DSS +requirements. + +5. **Industry Best Practices**: Various cybersecurity experts and +organizations, such as SANS Institute, CERT/CC (Computer Emergency Response +Team Coordination Center), and security vendors, provide guidance on best +practices for cryptographic algorithms. These resources typically recommend +avoiding the use of weak ciphers. + +6. **Security Research**: Academic papers and security research often +highlight the vulnerabilities of weak ciphers like DES and RC4. These +findings reinforce the importance of avoiding these ciphers in +security-critical applications. + +7. **Compliance Standards**: Depending on your industry and location, +there may be specific regulatory requirements that prohibit the use of +weak ciphers. Ensure compliance with applicable regulations by using strong, +approved cryptographic algorithms. + +8. **TLS/SSL Configuration**: If you are configuring web servers or other +network services that use TLS/SSL for encryption, it's essential to configure +your server to support only strong ciphersuites and protocols. Weak ciphers, +such as RC4, have known vulnerabilities and should be disabled. + +In summary, there is a consensus among reputable standards organizations, +industry experts, and security professionals that weak ciphers like DES and +RC4 should be avoided due to their known vulnerabilities and weaknesses. +Instead, it is advisable to use stronger, more secure cryptographic algorithms +and adhere to industry best practices and regulatory requirements for +encryption and security. + +------- +Example +------- + +.. code-block:: python + :linenos: + :emphasize-lines: 14 + + package main + + import ( + "crypto/des" + ) + + func main() { + ede2Key := []byte("example key 1234") + + var tripleDESKey []byte + tripleDESKey = append(tripleDESKey, ede2Key[:16]...) + tripleDESKey = append(tripleDESKey, ede2Key[:8]...) + + _, err := des.NewTripleDESCipher(tripleDESKey) + if err != nil { + panic(err) + } + } + +----------- +Remediation +----------- + +It is advisable to use stronger, more secure cryptographic algorithms such as +AES. + +.. code-block:: python + :linenos: + :emphasize-lines: 4,14 + + package main + + import ( + "crypto/aes" + ) + + func main() { + aesKey := []byte("example key 1234") + + _, err := aes.NewCipher(aesKey) + if err != nil { + panic(err) + } + } + +.. seealso:: + + - `Use of a Broken or Risky Cryptographic Algorithm in Crypto Package `_ + - `des package - crypto_des - Go Packages `_ + - `rc4 package - crypto_rc4 - Go Packages `_ + - `CWE-327: Use of a Broken or Risky Cryptographic Algorithm `_ + +.. versionadded:: 1.0.0 + +""" # noqa: E501 +from precli.core.config import Config +from precli.core.level import Level +from precli.core.location import Location +from precli.core.result import Result +from precli.rules import Rule + + +class WeakCipher(Rule): + def __init__(self, id: str): + super().__init__( + id=id, + name="use_of_a_broken_or_risky_cryptographic_algorithm", + full_descr=__doc__, + cwe_id=327, + message="Weak ciphers like {} should be avoided due to their " + "known vulnerabilities and weaknesses.", + targets=("call"), + wildcards={}, + config=Config(enabled=False), + ) + + def analyze(self, context: dict, **kwargs: dict) -> Result: + call = kwargs.get("call") + + if call.name_qualified in [ + "crypto/des.NewCipher", + "crypto/des.NewTripleDESCipher", + "crypto/rc4.NewCipher", + ]: + fixes = Rule.get_fixes( + context=context, + deleted_location=Location(node=call.function_node), + description="It is advisable to use a stronger, more " + "secure cryptographic algorithm like AES.", + inserted_content="aes.NewCipher", + ) + return Result( + rule_id=self.id, + location=Location( + file_name=context["file_name"], + node=call.function_node, + ), + level=Level.ERROR, + message=self.message.format(call.name), + fixes=fixes, + ) diff --git a/precli/rules/go/stdlib/crypto/weak_hash.py b/precli/rules/go/stdlib/crypto/weak_hash.py index d44d9fbb..761a50c4 100644 --- a/precli/rules/go/stdlib/crypto/weak_hash.py +++ b/precli/rules/go/stdlib/crypto/weak_hash.py @@ -64,7 +64,7 @@ .. seealso:: - - `Reversible One Way Hash in Crypto Package `_ + - `Reversible One Way Hash in Crypto Package `_ - `md5 package - crypto_md5 - Go Packages `_ - `sha1 package - crypto_sha1 - Go Packages `_ - `CWE-328: Use of Weak Hash `_ @@ -97,9 +97,34 @@ def analyze(self, context: dict, **kwargs: dict) -> Result: if call.name_qualified in [ "crypto/md5.New", + "crypto/sha1.New", + ]: + fixes = Rule.get_fixes( + context=context, + deleted_location=Location(node=call.function_node), + description="Use a more secure hashing algorithm like sha256.", + inserted_content="sha256.New", + ) + return Result( + rule_id=self.id, + location=Location( + file_name=context["file_name"], + node=call.function_node, + ), + level=Level.ERROR, + message=self.message.format(call.name_qualified), + fixes=fixes, + ) + elif call.name_qualified in [ "crypto/md5.Sum", - "crypto/sha1.New" "crypto/sha1.Sum", + "crypto/sha1.Sum", ]: + fixes = Rule.get_fixes( + context=context, + deleted_location=Location(node=call.function_node), + description="Use a more secure hashing algorithm like sha256.", + inserted_content="sha256.Sum", + ) return Result( rule_id=self.id, location=Location( @@ -108,4 +133,5 @@ def analyze(self, context: dict, **kwargs: dict) -> Result: ), level=Level.ERROR, message=self.message.format(call.name_qualified), + fixes=fixes, ) diff --git a/setup.cfg b/setup.cfg index 4c9717e6..7d61624d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,8 +33,11 @@ precli.parsers = python = precli.parsers.python:Python precli.rules.go = + # precli/rules/go/stdlib/crypto/weak_cipher.py + GO001 = precli.rules.go.stdlib.crypto.weak_cipher:WeakCipher + # precli/rules/go/stdlib/crypto/weak_hash.py - GO001 = precli.rules.go.stdlib.crypto.weak_hash:WeakHash + GO002 = precli.rules.go.stdlib.crypto.weak_hash:WeakHash # precli/rules/go/golang_org_x_crypto/ssh_insecure_ignore_hostkey.py GO501 = precli.rules.go.golang_org_x_crypto.ssh_insecure_ignore_hostkey:SshInsecureIgnoreHostKey diff --git a/tests/unit/rules/go/stdlib/crypto/examples/weak_cipher_des.go b/tests/unit/rules/go/stdlib/crypto/examples/weak_cipher_des.go new file mode 100644 index 00000000..9878a560 --- /dev/null +++ b/tests/unit/rules/go/stdlib/crypto/examples/weak_cipher_des.go @@ -0,0 +1,18 @@ +package main + +import ( + "crypto/des" +) + +func main() { + ede2Key := []byte("example key 1234") + + var tripleDESKey []byte + tripleDESKey = append(tripleDESKey, ede2Key[:16]...) + tripleDESKey = append(tripleDESKey, ede2Key[:8]...) + + _, err := des.NewTripleDESCipher(tripleDESKey) + if err != nil { + panic(err) + } +} diff --git a/tests/unit/rules/go/stdlib/crypto/examples/weakhash_md5.go b/tests/unit/rules/go/stdlib/crypto/examples/weak_hash_md5_new.go similarity index 100% rename from tests/unit/rules/go/stdlib/crypto/examples/weakhash_md5.go rename to tests/unit/rules/go/stdlib/crypto/examples/weak_hash_md5_new.go diff --git a/tests/unit/rules/go/stdlib/crypto/examples/weak_hash_sha1_new.go b/tests/unit/rules/go/stdlib/crypto/examples/weak_hash_sha1_new.go new file mode 100644 index 00000000..b7a1b6e0 --- /dev/null +++ b/tests/unit/rules/go/stdlib/crypto/examples/weak_hash_sha1_new.go @@ -0,0 +1,12 @@ +package main + +import ( + "crypto/sha1" + "fmt" +) + +func main() { + h := sha1.New() + h.Write([]byte("hello world\n")) + fmt.Printf("%x", h.Sum(nil)) +}