Two queries for timing attacks

This commit is contained in:
Fosstars
2021-07-25 11:40:35 +02:00
parent e3b6ceade5
commit ad54c9d937
16 changed files with 569 additions and 391 deletions

View File

@@ -1,50 +0,0 @@
edges
| NonConstantTimeCheckOnSignature.java:21:32:21:48 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:23:47:23:55 | actualMac |
| NonConstantTimeCheckOnSignature.java:33:32:33:44 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:35:88:35:96 | actualMac : byte[] |
| NonConstantTimeCheckOnSignature.java:35:88:35:96 | actualMac : byte[] | NonConstantTimeCheckOnSignature.java:35:70:35:97 | castToObjectArray(...) |
| NonConstantTimeCheckOnSignature.java:46:25:46:33 | actualMac : byte[] | NonConstantTimeCheckOnSignature.java:48:47:48:55 | actualMac |
| NonConstantTimeCheckOnSignature.java:71:32:71:44 | sign(...) : byte[] | NonConstantTimeCheckOnSignature.java:73:44:73:52 | signature |
| NonConstantTimeCheckOnSignature.java:85:25:85:33 | signature : byte[] | NonConstantTimeCheckOnSignature.java:87:44:87:52 | signature |
| NonConstantTimeCheckOnSignature.java:111:26:111:45 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:113:49:113:51 | tag |
| NonConstantTimeCheckOnSignature.java:128:28:128:30 | tag : byte[] | NonConstantTimeCheckOnSignature.java:130:44:130:46 | tag |
| NonConstantTimeCheckOnSignature.java:146:56:146:58 | tag : ByteBuffer | NonConstantTimeCheckOnSignature.java:148:44:148:46 | tag : ByteBuffer |
| NonConstantTimeCheckOnSignature.java:148:44:148:46 | tag : ByteBuffer | NonConstantTimeCheckOnSignature.java:148:44:148:54 | array(...) |
| NonConstantTimeCheckOnSignature.java:160:56:160:58 | tag : ByteBuffer | NonConstantTimeCheckOnSignature.java:162:53:162:55 | tag |
| NonConstantTimeCheckOnSignature.java:185:26:185:50 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:187:44:187:46 | tag |
| NonConstantTimeCheckOnSignature.java:220:34:220:50 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:223:26:223:36 | computedTag |
nodes
| NonConstantTimeCheckOnSignature.java:21:32:21:48 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCheckOnSignature.java:23:47:23:55 | actualMac | semmle.label | actualMac |
| NonConstantTimeCheckOnSignature.java:33:32:33:44 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCheckOnSignature.java:35:70:35:97 | castToObjectArray(...) | semmle.label | castToObjectArray(...) |
| NonConstantTimeCheckOnSignature.java:35:88:35:96 | actualMac : byte[] | semmle.label | actualMac : byte[] |
| NonConstantTimeCheckOnSignature.java:46:25:46:33 | actualMac : byte[] | semmle.label | actualMac : byte[] |
| NonConstantTimeCheckOnSignature.java:48:47:48:55 | actualMac | semmle.label | actualMac |
| NonConstantTimeCheckOnSignature.java:71:32:71:44 | sign(...) : byte[] | semmle.label | sign(...) : byte[] |
| NonConstantTimeCheckOnSignature.java:73:44:73:52 | signature | semmle.label | signature |
| NonConstantTimeCheckOnSignature.java:85:25:85:33 | signature : byte[] | semmle.label | signature : byte[] |
| NonConstantTimeCheckOnSignature.java:87:44:87:52 | signature | semmle.label | signature |
| NonConstantTimeCheckOnSignature.java:111:26:111:45 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCheckOnSignature.java:113:49:113:51 | tag | semmle.label | tag |
| NonConstantTimeCheckOnSignature.java:128:28:128:30 | tag : byte[] | semmle.label | tag : byte[] |
| NonConstantTimeCheckOnSignature.java:130:44:130:46 | tag | semmle.label | tag |
| NonConstantTimeCheckOnSignature.java:146:56:146:58 | tag : ByteBuffer | semmle.label | tag : ByteBuffer |
| NonConstantTimeCheckOnSignature.java:148:44:148:46 | tag : ByteBuffer | semmle.label | tag : ByteBuffer |
| NonConstantTimeCheckOnSignature.java:148:44:148:54 | array(...) | semmle.label | array(...) |
| NonConstantTimeCheckOnSignature.java:160:56:160:58 | tag : ByteBuffer | semmle.label | tag : ByteBuffer |
| NonConstantTimeCheckOnSignature.java:162:53:162:55 | tag | semmle.label | tag |
| NonConstantTimeCheckOnSignature.java:185:26:185:50 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCheckOnSignature.java:187:44:187:46 | tag | semmle.label | tag |
| NonConstantTimeCheckOnSignature.java:220:34:220:50 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| NonConstantTimeCheckOnSignature.java:223:26:223:36 | computedTag | semmle.label | computedTag |
#select
| NonConstantTimeCheckOnSignature.java:23:47:23:55 | actualMac | NonConstantTimeCheckOnSignature.java:21:32:21:48 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:23:47:23:55 | actualMac | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:21:32:21:48 | doFinal(...) : byte[] | MAC |
| NonConstantTimeCheckOnSignature.java:35:70:35:97 | castToObjectArray(...) | NonConstantTimeCheckOnSignature.java:33:32:33:44 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:35:70:35:97 | castToObjectArray(...) | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:33:32:33:44 | doFinal(...) : byte[] | MAC |
| NonConstantTimeCheckOnSignature.java:48:47:48:55 | actualMac | NonConstantTimeCheckOnSignature.java:46:25:46:33 | actualMac : byte[] | NonConstantTimeCheckOnSignature.java:48:47:48:55 | actualMac | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:46:25:46:33 | actualMac : byte[] | MAC |
| NonConstantTimeCheckOnSignature.java:73:44:73:52 | signature | NonConstantTimeCheckOnSignature.java:71:32:71:44 | sign(...) : byte[] | NonConstantTimeCheckOnSignature.java:73:44:73:52 | signature | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:71:32:71:44 | sign(...) : byte[] | signature |
| NonConstantTimeCheckOnSignature.java:87:44:87:52 | signature | NonConstantTimeCheckOnSignature.java:85:25:85:33 | signature : byte[] | NonConstantTimeCheckOnSignature.java:87:44:87:52 | signature | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:85:25:85:33 | signature : byte[] | signature |
| NonConstantTimeCheckOnSignature.java:113:49:113:51 | tag | NonConstantTimeCheckOnSignature.java:111:26:111:45 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:113:49:113:51 | tag | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:111:26:111:45 | doFinal(...) : byte[] | ciphertext |
| NonConstantTimeCheckOnSignature.java:130:44:130:46 | tag | NonConstantTimeCheckOnSignature.java:128:28:128:30 | tag : byte[] | NonConstantTimeCheckOnSignature.java:130:44:130:46 | tag | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:128:28:128:30 | tag : byte[] | ciphertext |
| NonConstantTimeCheckOnSignature.java:148:44:148:54 | array(...) | NonConstantTimeCheckOnSignature.java:146:56:146:58 | tag : ByteBuffer | NonConstantTimeCheckOnSignature.java:148:44:148:54 | array(...) | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:146:56:146:58 | tag : ByteBuffer | ciphertext |
| NonConstantTimeCheckOnSignature.java:162:53:162:55 | tag | NonConstantTimeCheckOnSignature.java:160:56:160:58 | tag : ByteBuffer | NonConstantTimeCheckOnSignature.java:162:53:162:55 | tag | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:160:56:160:58 | tag : ByteBuffer | ciphertext |
| NonConstantTimeCheckOnSignature.java:187:44:187:46 | tag | NonConstantTimeCheckOnSignature.java:185:26:185:50 | doFinal(...) : byte[] | NonConstantTimeCheckOnSignature.java:187:44:187:46 | tag | Using a non-constant-time method for cheching a $@. | NonConstantTimeCheckOnSignature.java:185:26:185:50 | doFinal(...) : byte[] | ciphertext |

View File

@@ -0,0 +1,15 @@
edges
| Test.java:14:28:14:44 | doFinal(...) : byte[] | Test.java:15:43:15:51 | actualMac |
| Test.java:30:28:30:40 | sign(...) : byte[] | Test.java:31:40:31:48 | signature |
| Test.java:47:22:47:46 | doFinal(...) : byte[] | Test.java:48:40:48:42 | tag |
nodes
| Test.java:14:28:14:44 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| Test.java:15:43:15:51 | actualMac | semmle.label | actualMac |
| Test.java:30:28:30:40 | sign(...) : byte[] | semmle.label | sign(...) : byte[] |
| Test.java:31:40:31:48 | signature | semmle.label | signature |
| Test.java:47:22:47:46 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| Test.java:48:40:48:42 | tag | semmle.label | tag |
#select
| Test.java:15:43:15:51 | actualMac | Test.java:14:28:14:44 | doFinal(...) : byte[] | Test.java:15:43:15:51 | actualMac | Using a non-constant-time method for checking a $@. | Test.java:14:28:14:44 | doFinal(...) : byte[] | MAC |
| Test.java:31:40:31:48 | signature | Test.java:30:28:30:40 | sign(...) : byte[] | Test.java:31:40:31:48 | signature | Using a non-constant-time method for checking a $@. | Test.java:30:28:30:40 | sign(...) : byte[] | signature |
| Test.java:48:40:48:42 | tag | Test.java:47:22:47:46 | doFinal(...) : byte[] | Test.java:48:40:48:42 | tag | Using a non-constant-time method for checking a $@. | Test.java:47:22:47:46 | doFinal(...) : byte[] | ciphertext |

View File

@@ -0,0 +1,59 @@
import java.security.Key;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.Mac;
public class Test {
// BAD: compare MACs using a not-constant time method
public boolean unsafeMacCheck(byte[] expectedMac, byte[] data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
byte[] actualMac = mac.doFinal(data);
return Arrays.equals(expectedMac, actualMac);
}
// GOOD: compare MACs using a constant time method
public boolean saferMacCheck(byte[] expectedMac, byte[] data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
byte[] actualMac = mac.doFinal(data);
return MessageDigest.isEqual(expectedMac, actualMac);
}
// BAD: compare signatures using a not-constant time method
public boolean unsafeCheckSignatures(byte[] expected, byte[] data, PrivateKey key) throws Exception {
Signature engine = Signature.getInstance("SHA256withRSA");
engine.initSign(key);
engine.update(data);
byte[] signature = engine.sign();
return Arrays.equals(expected, signature);
}
// GOOD: compare signatures using a constant time method
public boolean saferCheckSignatures(byte[] expected, byte[] data, PrivateKey key) throws Exception {
Signature engine = Signature.getInstance("SHA256withRSA");
engine.initSign(key);
engine.update(data);
byte[] signature = engine.sign();
return MessageDigest.isEqual(expected, signature);
}
// BAD: compare ciphertexts using a not-constant time method
public boolean unsafeCheckCustomMac(byte[] expected, byte[] plaintext, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] tag = cipher.doFinal(plaintext);
return Arrays.equals(expected, tag);
}
// GOOD: compare ciphertexts using a constant time method
public boolean saferCheckCustomMac(byte[] expected, byte[] plaintext, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] tag = cipher.doFinal(plaintext);
return MessageDigest.isEqual(expected, tag);
}
}

View File

@@ -0,0 +1,50 @@
edges
| Test.java:21:32:21:48 | doFinal(...) : byte[] | Test.java:23:47:23:55 | actualMac |
| Test.java:33:32:33:44 | doFinal(...) : byte[] | Test.java:35:88:35:96 | actualMac : byte[] |
| Test.java:35:88:35:96 | actualMac : byte[] | Test.java:35:70:35:97 | castToObjectArray(...) |
| Test.java:46:25:46:33 | actualMac : byte[] | Test.java:48:47:48:55 | actualMac |
| Test.java:71:32:71:44 | sign(...) : byte[] | Test.java:73:44:73:52 | signature |
| Test.java:85:25:85:33 | signature : byte[] | Test.java:87:44:87:52 | signature |
| Test.java:111:26:111:45 | doFinal(...) : byte[] | Test.java:113:49:113:51 | tag |
| Test.java:128:28:128:30 | tag : byte[] | Test.java:130:44:130:46 | tag |
| Test.java:146:56:146:58 | tag : ByteBuffer | Test.java:148:44:148:46 | tag : ByteBuffer |
| Test.java:148:44:148:46 | tag : ByteBuffer | Test.java:148:44:148:54 | array(...) |
| Test.java:160:56:160:58 | tag : ByteBuffer | Test.java:162:53:162:55 | tag |
| Test.java:186:26:186:50 | doFinal(...) : byte[] | Test.java:188:44:188:46 | tag |
| Test.java:221:34:221:50 | doFinal(...) : byte[] | Test.java:224:26:224:36 | computedTag |
nodes
| Test.java:21:32:21:48 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| Test.java:23:47:23:55 | actualMac | semmle.label | actualMac |
| Test.java:33:32:33:44 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| Test.java:35:70:35:97 | castToObjectArray(...) | semmle.label | castToObjectArray(...) |
| Test.java:35:88:35:96 | actualMac : byte[] | semmle.label | actualMac : byte[] |
| Test.java:46:25:46:33 | actualMac : byte[] | semmle.label | actualMac : byte[] |
| Test.java:48:47:48:55 | actualMac | semmle.label | actualMac |
| Test.java:71:32:71:44 | sign(...) : byte[] | semmle.label | sign(...) : byte[] |
| Test.java:73:44:73:52 | signature | semmle.label | signature |
| Test.java:85:25:85:33 | signature : byte[] | semmle.label | signature : byte[] |
| Test.java:87:44:87:52 | signature | semmle.label | signature |
| Test.java:111:26:111:45 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| Test.java:113:49:113:51 | tag | semmle.label | tag |
| Test.java:128:28:128:30 | tag : byte[] | semmle.label | tag : byte[] |
| Test.java:130:44:130:46 | tag | semmle.label | tag |
| Test.java:146:56:146:58 | tag : ByteBuffer | semmle.label | tag : ByteBuffer |
| Test.java:148:44:148:46 | tag : ByteBuffer | semmle.label | tag : ByteBuffer |
| Test.java:148:44:148:54 | array(...) | semmle.label | array(...) |
| Test.java:160:56:160:58 | tag : ByteBuffer | semmle.label | tag : ByteBuffer |
| Test.java:162:53:162:55 | tag | semmle.label | tag |
| Test.java:186:26:186:50 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| Test.java:188:44:188:46 | tag | semmle.label | tag |
| Test.java:221:34:221:50 | doFinal(...) : byte[] | semmle.label | doFinal(...) : byte[] |
| Test.java:224:26:224:36 | computedTag | semmle.label | computedTag |
#select
| Test.java:23:47:23:55 | actualMac | Test.java:21:32:21:48 | doFinal(...) : byte[] | Test.java:23:47:23:55 | actualMac | Timing attack against $@ validation. | Test.java:21:32:21:48 | doFinal(...) : byte[] | MAC |
| Test.java:35:70:35:97 | castToObjectArray(...) | Test.java:33:32:33:44 | doFinal(...) : byte[] | Test.java:35:70:35:97 | castToObjectArray(...) | Timing attack against $@ validation. | Test.java:33:32:33:44 | doFinal(...) : byte[] | MAC |
| Test.java:48:47:48:55 | actualMac | Test.java:46:25:46:33 | actualMac : byte[] | Test.java:48:47:48:55 | actualMac | Timing attack against $@ validation. | Test.java:46:25:46:33 | actualMac : byte[] | MAC |
| Test.java:73:44:73:52 | signature | Test.java:71:32:71:44 | sign(...) : byte[] | Test.java:73:44:73:52 | signature | Timing attack against $@ validation. | Test.java:71:32:71:44 | sign(...) : byte[] | signature |
| Test.java:87:44:87:52 | signature | Test.java:85:25:85:33 | signature : byte[] | Test.java:87:44:87:52 | signature | Timing attack against $@ validation. | Test.java:85:25:85:33 | signature : byte[] | signature |
| Test.java:113:49:113:51 | tag | Test.java:111:26:111:45 | doFinal(...) : byte[] | Test.java:113:49:113:51 | tag | Timing attack against $@ validation. | Test.java:111:26:111:45 | doFinal(...) : byte[] | ciphertext |
| Test.java:130:44:130:46 | tag | Test.java:128:28:128:30 | tag : byte[] | Test.java:130:44:130:46 | tag | Timing attack against $@ validation. | Test.java:128:28:128:30 | tag : byte[] | ciphertext |
| Test.java:148:44:148:54 | array(...) | Test.java:146:56:146:58 | tag : ByteBuffer | Test.java:148:44:148:54 | array(...) | Timing attack against $@ validation. | Test.java:146:56:146:58 | tag : ByteBuffer | ciphertext |
| Test.java:162:53:162:55 | tag | Test.java:160:56:160:58 | tag : ByteBuffer | Test.java:162:53:162:55 | tag | Timing attack against $@ validation. | Test.java:160:56:160:58 | tag : ByteBuffer | ciphertext |
| Test.java:188:44:188:46 | tag | Test.java:186:26:186:50 | doFinal(...) : byte[] | Test.java:188:44:188:46 | tag | Timing attack against $@ validation. | Test.java:186:26:186:50 | doFinal(...) : byte[] | ciphertext |

View File

@@ -10,7 +10,7 @@ import java.util.Objects;
import javax.crypto.Cipher;
import javax.crypto.Mac;
public class NonConstantTimeCheckOnSignature {
public class Test {
// BAD: compare MACs using a non-constant-time method
public boolean unsafeMacCheckWithArrayEquals(Socket socket) throws Exception {
@@ -177,6 +177,7 @@ public class NonConstantTimeCheckOnSignature {
}
// GOOD: compare ciphertexts using a constant-time method, but no user input
// but NonConstantTimeCheckOnSignature.ql still detects it
public boolean noUserInputWhenCheckingCiphertext(Socket socket, Key key) throws Exception {
try (InputStream is = socket.getInputStream()) {
byte[] plaintext = is.readNBytes(100);

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-208/TimingAttackAgainstSignature.ql