-
Notifications
You must be signed in to change notification settings - Fork 738
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new check for weak RSA keys and padding modes
Fixes #1736
- Loading branch information
1 parent
985a289
commit e330aad
Showing
4 changed files
with
185 additions
and
1 deletion.
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,77 @@ | ||
require 'brakeman/checks/base_check' | ||
|
||
class Brakeman::CheckWeakRSAKey < Brakeman::BaseCheck | ||
Brakeman::Checks.add_optional self | ||
|
||
@description = "Checks for weak uses RSA keys" | ||
|
||
def run_check | ||
tracker.find_call(targets: [:'OpenSSL::PKey::RSA'], method: [:new, :generate], nested: true).each do |result| | ||
check_key_size(result) | ||
end | ||
|
||
tracker.find_call(targets: [:'OpenSSL::PKey::RSA.new'], method: [:public_encrypt, :public_decrypt, :private_encrypt, :private_decrypt], nested: true).each do |result| | ||
check_padding(result) | ||
end | ||
end | ||
|
||
def check_key_size result | ||
return unless original? result | ||
|
||
first_arg = result[:call].first_arg | ||
|
||
if number? first_arg | ||
key_size = first_arg.value | ||
|
||
if key_size < 1024 | ||
confidence = :high | ||
message = msg("RSA key with size ", msg_code(key_size.to_s), " is considered very weak. Use at least 2048 bit key size") | ||
elsif key_size < 2048 | ||
confidence = :medium | ||
message = msg("RSA key with size ", msg_code(key_size.to_s), " is considered weak. Use at least 2048 bit key size") | ||
else | ||
return | ||
end | ||
|
||
warn result: result, | ||
warning_type: "Weak Cryptography", | ||
warning_code: :small_rsa_key_size, | ||
message: message, | ||
confidence: confidence, | ||
user_input: first_arg, | ||
cwe_id: [326] | ||
end | ||
end | ||
|
||
PKCS1_PADDING = s(:const, :PKCS1_PADDING).freeze | ||
NO_PADDING = s(:const, :NO_PADDING).freeze | ||
|
||
def check_padding result | ||
return unless original? result | ||
|
||
padding_arg = result[:call].second_arg | ||
|
||
case padding_arg | ||
when PKCS1_PADDING, nil | ||
message = "Use of insecure padding mode PKCS1 (default if not specified), which is known to be insecure" | ||
|
||
warn result: result, | ||
warning_type: "Weak Cryptography", | ||
warning_code: :insecure_rsa_padding_mode, | ||
message: message, | ||
confidence: :high, | ||
user_input: padding_arg, | ||
cwe_id: [780] | ||
when NO_PADDING | ||
message = "No padding mode used for RSA key. A safe padding mode should be specified for RSA keys" | ||
|
||
warn result: result, | ||
warning_type: "Weak Cryptography", | ||
warning_code: :missing_rsa_padding_mode, | ||
message: message, | ||
confidence: :high, | ||
user_input: padding_arg, | ||
cwe_id: [780] | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
class SomeLib | ||
def some_rsa_encrypting | ||
public_key = OpenSSL::PKey::RSA.new("grab the public 4096 bit key") | ||
encrypted = Base64.encode64(public_key.public_encrypt(payload.to_json)) # Weak padding mode default | ||
public_key.private_decrypt(Base64.decode64(encrypted)) # Weak padding mode default | ||
end | ||
|
||
def some_more_rsa_padding_modes | ||
public_key = OpenSSL::PKey::RSA.new("grab the public 4096 bit key") | ||
public_key.public_decrypt(data, PKCS1_PADDING) | ||
public_key.private_encrypt(data, NO_PADDING) | ||
public_key.private_encrypt(data, SSLV23_PADDING) | ||
end | ||
|
||
def small_rsa_keys | ||
OpenSSL::PKey::RSA.generate(512) # Very weak | ||
OpenSSL::PKey::RSA.new(1024) # Weak | ||
OpenSSL::PKey::RSA.new(2048) # Okay | ||
end | ||
end |
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