Skip to content

Instantly share code, notes, and snippets.

@artem-smotrakov
artem-smotrakov / TimingAttackAgainstSignature.ql
Created Aug 15, 2021
CodeQL query for detecting timing attacks in Java code
View TimingAttackAgainstSignature.ql
from DataFlow::PathNode source, DataFlow::PathNode sink, NonConstantTimeCryptoComparisonConfig conf
where
conf.hasFlowPath(source, sink) and
(
source.getNode().(CryptoOperationSource).includesUserInput() and
sink.getNode().(NonConstantTimeComparisonSink).includesUserInput()
)
select sink.getNode(), source, sink, "Timing attack against $@ validation.", source,
source.getNode().(CryptoOperationSource).getCall().getResultType()
@artem-smotrakov
artem-smotrakov / NonConstantTimeCryptoComparisonConfig.ql
Created Aug 15, 2021
A data flow tracking config for detecting timing attacks in Java code
View NonConstantTimeCryptoComparisonConfig.ql
class NonConstantTimeCryptoComparisonConfig extends TaintTracking::Configuration {
NonConstantTimeCryptoComparisonConfig() { this = "NonConstantTimeCryptoComparisonConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof CryptoOperationSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink }
}
@artem-smotrakov
artem-smotrakov / PossibleTimingAttackAgainstSignature.ql
Created Aug 15, 2021
CodeQL query for detecting possible timing attacks in Java applications
View PossibleTimingAttackAgainstSignature.ql
from DataFlow::PathNode source, DataFlow::PathNode sink, NonConstantTimeCryptoComparisonConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "Possible timing attack against $@ validation.", source,
source.getNode().(CryptoOperationSource).getCall().getResultType()
@artem-smotrakov
artem-smotrakov / SafeMACValidationExample.java
Created Aug 15, 2021
Using constant-time algorithm for validating a MAC
View SafeMACValidationExample.java
public boolean validate(HttpRequest request, SecretKey key) throws Exception {
byte[] message = getMessageFrom(request);
byte[] signature = getSignatureFrom(request);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(key.getEncoded(), "HmacSHA256"));
byte[] actual = mac.doFinal(message);
return MessageDigest.isEqual(signature, actual);
}
@artem-smotrakov
artem-smotrakov / TimingAttackExample.java
Created Aug 15, 2021
Possible timing attack against MAC validation
View TimingAttackExample.java
public boolean validate(HttpRequest request, SecretKey key) throws Exception {
byte[] message = getMessageFrom(request);
byte[] signature = getSignatureFrom(request);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(key.getEncoded(), "HmacSHA256"));
byte[] actual = mac.doFinal(message);
return Arrays.equals(signature, actual);
}
@artem-smotrakov
artem-smotrakov / UnsafeRmiObject.ql
Created Jun 2, 2021
Taint-tracking configuration for unsafe RMI objects
View UnsafeRmiObject.ql
private class BindingUnsafeRemoteObjectConfig extends TaintTracking::Configuration {
BindingUnsafeRemoteObjectConfig() { this = "BindingUnsafeRemoteObjectConfig" }
override predicate isSource(DataFlow::Node source) {
exists(ConstructorCall cc | cc = source.asExpr() |
hasVulnerableMethod(cc.getConstructedType().getASupertype*())
)
}
override predicate isSink(DataFlow::Node sink) {
@artem-smotrakov
artem-smotrakov / SaferRmiObject.java
Created Jun 2, 2021
Example of a deserialization filter for an unsafe RMI object
View SaferRmiObject.java
public class Server {
public void bindRemoteObject(Registry registry) throws Exception {
ObjectInputFilter filter = info -> {
if (info.serialClass().getCanonicalName().startsWith("com.safe.package.")) {
return ObjectInputFilter.Status.ALLOWED;
}
return ObjectInputFilter.Status.REJECTED;
};
registry.bind("unsafe", UnicastRemoteObject.exportObject(new RemoteObjectImpl(), 12345, filter));
@artem-smotrakov
artem-smotrakov / UnsafeRmiObject.java
Last active Jun 2, 2021
Example of a vulnerable RMI object
View UnsafeRmiObject.java
public class Server {
public void bindRemoteObject(Registry registry) throws Exception {
registry.bind("unsafe", UnicastRemoteObject.exportObject(new RemoteObjectImpl()));
}
}
interface RemoteObject extends Remote {
// this remote method is vulnerable because it accepts a complex parameter
void action(Object obj) throws RemoteException;
@artem-smotrakov
artem-smotrakov / SaferExpressionEvaluationWithJuel.java
Last active Apr 14, 2021
Restricting Jakarta EL expressions to avoid RCE
View SaferExpressionEvaluationWithJuel.java
void handle(HttpRequest request) {
if (request.hasParameter("questionToBackend")) {
String input = request.getParameter("questionToBackend"));
String pattern = "(inside|outside)\\.(temperature|humidity)";
if (!input.matches(pattern)) {
throw new IllegalArgumentException("Unexpected expression");
}
String expression = "${" + input + "}";
ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
ELContext context = new de.odysseus.el.util.SimpleContext();
View JakartaExpressionLanguageInjection.java
void handle(HttpRequest request) {
if (request.hasParameter("questionToBackend")) {
String expression = request.getParameter("questionToBackend"));
ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
ELContext context = new de.odysseus.el.util.SimpleContext();
ValueExpression e = factory.createValueExpression(context, expression, Object.class);
Object object = e.getValue(context);
handleResult(object);
} else {
callNextHandler(request);