-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add golang_org_x_weak_cipher and testing
Signed-off-by: Eric Brown <eric.brown@securesauce.dev>
- Loading branch information
Showing
12 changed files
with
405 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# Copyright 2024 Secure Saurce LLC | ||
r""" | ||
==================================================================== | ||
Use of a Broken or Risky Cryptographic Algorithm in X 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 Blowfish, CAST5, TEA/XTEA, and Twofish: | ||
Blowfish: Developed in 1993, Blowfish is a block cipher known for its | ||
simplicity. However, its small block size of 64 bits makes it susceptible to | ||
birthday attacks in modern contexts. This vulnerability is significant when | ||
encrypting large amounts of data, which is common in current applications. | ||
CAST5 (CAST-128): CAST5, a symmetric encryption algorithm, suffers from | ||
similar issues as Blowfish due to its 64-bit block size. While it was | ||
considered secure for its time, modern applications typically require | ||
algorithms with larger block sizes for enhanced security. | ||
TEA/XTEA: The Tiny Encryption Algorithm (TEA) and its successor, eXtended | ||
TEA (XTEA), are lightweight block ciphers. They are notable for their | ||
simplicity and ease of implementation but have known vulnerabilities, | ||
including susceptibility to differential cryptanalysis. These weaknesses | ||
make them less suitable for applications where strong security is a priority. | ||
Twofish: As a finalist in the Advanced Encryption Standard (AES) competition, | ||
Twofish is a respected algorithm. However, it was not selected as the | ||
standard, and over time, AES has become the more tested and trusted choice | ||
in most cryptographic applications. | ||
In summary, there is a consensus among reputable standards organizations, | ||
industry experts, and security professionals that weak ciphers like Blowfish, | ||
CAST5, TEA/XTEA, and Twofish 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: 11 | ||
package main | ||
import ( | ||
"log" | ||
"golang.org/x/crypto/twofish" | ||
) | ||
func main() { | ||
key := []byte("examplekey123456") | ||
_, err := twofish.NewCipher(key) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} | ||
----------- | ||
Remediation | ||
----------- | ||
It is advisable to use stronger, more secure cryptographic algorithms such as | ||
AES. | ||
.. code-block:: python | ||
:linenos: | ||
:emphasize-lines: 5,11 | ||
package main | ||
import ( | ||
"log" | ||
"crypto/aes" | ||
) | ||
func main() { | ||
key := []byte("examplekey123456") | ||
_, err := aes.NewCipher(key) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} | ||
.. seealso:: | ||
- `Use of a Broken or Risky Cryptographic Algorithm in Crypto Package <https://docs.securesauce.dev/rules/GO502>`_ | ||
- `blowfish package - golang.org_x_crypto_twofish - Go Packages <https://pkg.go.dev/golang.org/x/crypto/blowfish>`_ | ||
- `cast5 package - golang.org_x_crypto_twofish - Go Packages <https://pkg.go.dev/golang.org/x/crypto/cast5>`_ | ||
- `tea package - golang.org_x_crypto_twofish - Go Packages <https://pkg.go.dev/golang.org/x/crypto/tea>`_ | ||
- `twofish package - golang.org_x_crypto_twofish - Go Packages <https://pkg.go.dev/golang.org/x/crypto/twofish>`_ | ||
- `xtea package - golang.org_x_crypto_twofish - Go Packages <https://pkg.go.dev/golang.org/x/crypto/xtea>`_ | ||
- `CWE-327: Use of a Broken or Risky Cryptographic Algorithm <https://cwe.mitre.org/data/definitions/327.html>`_ | ||
.. 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 [ | ||
"golang.org/x/crypto/blowfish.NewCipher", | ||
"golang.org/x/crypto/blowfish.NewSaltedCipher", | ||
"golang.org/x/crypto/cast5.NewCipher", | ||
"golang.org/x/crypto/tea.NewCipher", | ||
"golang.org/x/crypto/tea.NewCipherWithRounds", | ||
"golang.org/x/crypto/twofish.NewCipher", | ||
"golang.org/x/crypto/xtea.NewCipher", | ||
]: | ||
# TODO: Need to remove arguments for NewSaltedCipher and | ||
# NewCipherWithRounds | ||
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, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
tests/unit/rules/go/golang_org_x_crypto/examples/weak_cipher_blowfish.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// level: ERROR | ||
// start_line: 17 | ||
// end_line: 17 | ||
// start_column: 14 | ||
// end_column: 32 | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"golang.org/x/crypto/blowfish" | ||
) | ||
|
||
func main() { | ||
key := []byte("examplekey123456") | ||
|
||
_, err := blowfish.NewCipher(key) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
tests/unit/rules/go/golang_org_x_crypto/examples/weak_cipher_blowfish_new_salted_cipher.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// level: ERROR | ||
// start_line: 18 | ||
// end_line: 18 | ||
// start_column: 14 | ||
// end_column: 38 | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"golang.org/x/crypto/blowfish" | ||
) | ||
|
||
func main() { | ||
key := []byte("examplekey123456") | ||
salt := []byte("1234567890abcdef") | ||
|
||
_, err := blowfish.NewSaltedCipher(key, salt) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
tests/unit/rules/go/golang_org_x_crypto/examples/weak_cipher_cast5.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// level: ERROR | ||
// start_line: 17 | ||
// end_line: 17 | ||
// start_column: 14 | ||
// end_column: 29 | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"golang.org/x/crypto/cast5" | ||
) | ||
|
||
func main() { | ||
key := []byte("examplekey123456") | ||
|
||
_, err := cast5.NewCipher(key) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
tests/unit/rules/go/golang_org_x_crypto/examples/weak_cipher_tea.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// level: ERROR | ||
// start_line: 17 | ||
// end_line: 17 | ||
// start_column: 14 | ||
// end_column: 27 | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"golang.org/x/crypto/tea" | ||
) | ||
|
||
func main() { | ||
key := []byte("examplekey123456") | ||
|
||
_, err := tea.NewCipher(key) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
tests/unit/rules/go/golang_org_x_crypto/examples/weak_cipher_tea_new_cipher_with_rounds.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// level: ERROR | ||
// start_line: 17 | ||
// end_line: 17 | ||
// start_column: 14 | ||
// end_column: 37 | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"golang.org/x/crypto/tea" | ||
) | ||
|
||
func main() { | ||
key := []byte("examplekey123456") | ||
|
||
_, err := tea.NewCipherWithRounds(key, 64) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
tests/unit/rules/go/golang_org_x_crypto/examples/weak_cipher_twofish.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// level: ERROR | ||
// start_line: 35 | ||
// end_line: 35 | ||
// start_column: 18 | ||
// end_column: 35 | ||
package main | ||
|
||
import ( | ||
"crypto/cipher" | ||
"encoding/hex" | ||
"fmt" | ||
"golang.org/x/crypto/twofish" | ||
"log" | ||
) | ||
|
||
// pkcs7Pad pads the plaintext to be a multiple of the block size | ||
func pkcs7Pad(plaintext []byte, blockSize int) []byte { | ||
padding := blockSize - len(plaintext)%blockSize | ||
padtext := bytes.Repeat([]byte{byte(padding)}, padding) | ||
return append(plaintext, padtext...) | ||
} | ||
|
||
// pkcs7Unpad removes the padding from the plaintext | ||
func pkcs7Unpad(plaintext []byte) []byte { | ||
length := len(plaintext) | ||
padLen := int(plaintext[length-1]) | ||
return plaintext[:(length - padLen)] | ||
} | ||
|
||
func main() { | ||
// Twofish key (can be 16, 24, or 32 bytes) | ||
key := []byte("examplekey123456") // 16 bytes for a 128-bit key | ||
|
||
// Create a new Twofish cipher block with the key | ||
block, err := twofish.NewCipher(key) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
|
||
// The plaintext that needs to be encrypted | ||
plaintext := []byte("Hello, Twofish!") | ||
|
||
// Pad plaintext to be a multiple of the block size | ||
paddedPlaintext := pkcs7Pad(plaintext, twofish.BlockSize) | ||
|
||
ciphertext := make([]byte, len(paddedPlaintext)) | ||
for i := 0; i < len(paddedPlaintext); i += twofish.BlockSize { | ||
block.Encrypt(ciphertext[i:i+twofish.BlockSize], paddedPlaintext[i:i+twofish.BlockSize]) | ||
} | ||
|
||
fmt.Printf("Ciphertext: %x\n", ciphertext) | ||
|
||
// Decrypting the ciphertext | ||
decrypted := make([]byte, len(ciphertext)) | ||
for i := 0; i < len(ciphertext); i += twofish.BlockSize { | ||
block.Decrypt(decrypted[i:i+twofish.BlockSize], ciphertext[i:i+twofish.BlockSize]) | ||
} | ||
|
||
// Remove padding | ||
decrypted = pkcs7Unpad(decrypted) | ||
|
||
fmt.Printf("Decrypted: %s\n", decrypted) | ||
} |
21 changes: 21 additions & 0 deletions
21
tests/unit/rules/go/golang_org_x_crypto/examples/weak_cipher_xtea.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// level: ERROR | ||
// start_line: 17 | ||
// end_line: 17 | ||
// start_column: 14 | ||
// end_column: 28 | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"golang.org/x/crypto/xtea" | ||
) | ||
|
||
func main() { | ||
key := []byte("examplekey123456") | ||
|
||
_, err := xtea.NewCipher(key) | ||
if err != nil { | ||
log.Fatalf("Failed to create cipher: %v", err) | ||
} | ||
} |
Oops, something went wrong.