Yon Labs http://www.yonlabs.com Yon Labs Wed, 07 Sep 2022 01:26:13 +0000 en-US hourly 1 https://wordpress.org/?v=6.2 http://www.yonlabs.com/wp-content/uploads/2021/01/yonita-square.png Yon Labs http://www.yonlabs.com 32 32 Performance of Fetching Data with JPQL http://www.yonlabs.com/2021/09/performance-of-fetching-data-with-jpql/ http://www.yonlabs.com/2021/09/performance-of-fetching-data-with-jpql/#respond Wed, 08 Sep 2021 13:05:00 +0000 http://www.yonlabs.com/?p=374 Read more

]]>
Jakarta Persistence API (formerly Java Persistence API) is a standard approach to access a database in the Java world. Even though its usage is simple, developers sometimes struggle to achieve best performance. In this blog post, I’m going to showcase different JPQL techniques in fetching aggregated data along with their execution times.

Example JPA Model

In our example we focus on Employee and how to calculate a sum of salaries of employees by country.

@Entity 
class Employee {
    @Id @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;
    private BigDecimal salary;
    @OneToOne @JoinColumn(name = "address_id")
    private Address address;
    @Temporal(TemporalType.DATE)
    private Date startDate;
    @Temporal(TemporalType.DATE)
    private Date endDate;
    @ManyToOne @JoinColumn(name = "manager_id")
    private Employee manager;  
    // …
}

Sum of Salaries by Country – Select All

TypedQuery<Employee> query = em.createQuery(
    "SELECT e FROM Employee e", Employee.class);
List<Employee> list = query.getResultList();

// calculate sum of salaries by country
// map: country->sum
Map<String, BigDecimal> results = new HashMap<>();
for (Employee e : list) {    
    String country = e.getAddress().getCountry();    
    BigDecimal total = results.get(country);    
    if (total == null) total = BigDecimal.ZERO;    
    total = total.add(e.getSalary());    
    results.put(country, total);
}

Sum of Salaries by Country – Select Join Fetch

TypedQuery<Employee> query = em.createQuery(
    "SELECT e FROM Employee e 
     JOIN FETCH e.address", Employee.class);
List<Employee> list = query.getResultList();

// calculate sum of salaries by country
// map: country->sum
Map<String, BigDecimal> results = new HashMap<>();
for (Employee e : list) {    
    String country = e.getAddress().getCountry();    
    BigDecimal total = results.get(country);    
    if (total == null) total = BigDecimal.ZERO;    
    total = total.add(e.getSalary());    
    results.put(country, total);
}

Sum of Salaries by Country – Projection

Query query = em.createQuery(
    "SELECT e.salary, e.address.country 
     FROM Employee e");
List<Object[]> list = (List<Object[]>) query.getResultList();

// calculate sum of salaries by country
// map: country->sum
Map<String, BigDecimal> results = new HashMap<>();
for (Object[] e : list) {    
    String country = (String) e[1];    
    BigDecimal total = results.get(country);    
    if (total == null) total = BigDecimal.ZERO;    
    total = total.add((BigDecimal) e[0]);    
    results.put(country, total);
}

Sum of Salaries by Country – Aggregation JPQL

Query query = em.createQuery(
    "SELECT SUM(e.salary), e.address.country 
     FROM Employee e 
     GROUP BY e.address.country");
List<Object[]> list = (List<Object[]>) query.getResultList();

// already calculated!

Performance Comparison

For our performance comparison we use databases populated with 100000 employees and databases are located in different regions to illustrate the impact of latency on the execution times.

Local DB
(ping: ~0.05ms)
North California
(ping: ~38ms
)
EU Frankfurt
(ping: ~420ms)
(1) Select All 
(N+1 Problem!)
26756ms~2-3 hours~20-24 hours
(2) Select Join Fetch4854ms18027ms25096ms
(3) Projection653ms2902ms5006ms
(4) Aggregation JPQL182ms353ms1198ms
]]>
http://www.yonlabs.com/2021/09/performance-of-fetching-data-with-jpql/feed/ 0
How to Detect Long Running Queries in Hibernate? http://www.yonlabs.com/2021/08/how-to-detect-long-running-queries-in-hibernate/ http://www.yonlabs.com/2021/08/how-to-detect-long-running-queries-in-hibernate/#respond Wed, 18 Aug 2021 00:28:00 +0000 http://www.yonlabs.com/?p=368 Read more

]]>
Most Java applications use Jakarta Persistence API (formerly Java Persistence API) to access databases. Hibernate is the most popular ORM framework for Java. It is a straightforward and easy-to-use implementation of JPA. However, its simplicity of usage often becomes mischievous to developers and leads to serious performance issues in Hibernate-based applications. How to detect such issues? The answer might lay in smart logging.

Logging Slow Queries

Hibernate supports logging queries that run longer than a specified amount of time in miliseconds. To configure this feature you need to use parameter hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS. This parameter can be very helpful in detecting bottlenecks in production systems without producing excessive number of logs.

Example:

hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS=1000

Logging Queries with Parameters

When we tune or debug our applications, it often happens that we are interested not only in executed SQL/JPQL/HQL queries but also in parameters bound for a given query. Actually, that may be a crucial piece of information! Unfortunately, the widely-known show-sql logs only SQL queries without bound parameters.

In order to log queries along with bound parameters, you can use:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

]]>
http://www.yonlabs.com/2021/08/how-to-detect-long-running-queries-in-hibernate/feed/ 0
How to Map PostgreSQL BIT with Hibernate http://www.yonlabs.com/2021/07/how-to-map-postgresql-bit-with-hibernate/ http://www.yonlabs.com/2021/07/how-to-map-postgresql-bit-with-hibernate/#respond Thu, 22 Jul 2021 20:41:00 +0000 https://www.yonlabs.com/?p=323 Unfortunately, Jakarta Persistence API (formerly Java Persistence API aka JPA) does not support BIT having a parametrised length. Fortunately, hibernate (one of the implementation of JPA) supports custom types, thus you can define your own BIT type with a parametrised length.

Custom Definition of BIT

First, you need to create BitStringTypeBitStringJavaDescriptor, and BitStringSqlDescriptor:

public class BitStringType extends AbstractSingleColumnStandardBasicType<String> {

    public static final BitStringType INSTANCE = new BitStringType();

    public BitStringType() {
        super(VarcharTypeDescriptor.INSTANCE, BitStringJavaDescriptor.INSTANCE);
    }

    @Override
    public String getName() {
        return "BitString";
    }

}
public class BitStringJavaDescriptor extends AbstractTypeDescriptor<String> {

    public static final BitStringJavaDescriptor INSTANCE = new BitStringJavaDescriptor();

    public BitStringJavaDescriptor() {
        super(String.class, ImmutableMutabilityPlan.INSTANCE);
    }

    @Override
    public String fromString(String string) {
        return string;
    }

    @Override
    public <X> X unwrap(String value, Class<X> type, WrapperOptions options) {
        if (value == null)
            return null;
        if (String.class.isAssignableFrom(type))
            return (X) value;
        throw unknownUnwrap(type);
    }

    @Override
    public <X> String wrap(X value, WrapperOptions options) {
        if (value == null)
            return null;
        if (String.class.isInstance(value))
            return (String) value;
        throw unknownWrap(value.getClass());
    }

}
    @Override
    public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicBinder<X>(javaTypeDescriptor, this) {
            @Override
            protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
                st.setObject(index, javaTypeDescriptor.unwrap(value, String.class, options), Types.OTHER);
            }
            @Override
            protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) throws SQLException {
                st.setObject(name, javaTypeDescriptor.unwrap(value, String.class, options), Types.OTHER);
            }
        };
    }

    @Override
    public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
        return new BasicExtractor<X>(javaTypeDescriptor, this) {
            @Override
            protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(rs.getString(name), options);
            }
            @Override
            protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(statement.getString(index), options);
            }
            @Override
            protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
                return javaTypeDescriptor.wrap(statement.getString(name), options);
            }
        };
    }

}

Use Your Custom BIT Type

Having those classes, you can define a type for your field. Please, use the correct package (in my case I’ve used the one from my demo com.yonlabs.jpa):

    @Column
    @Type(type = "com.yonlabs.jpa.BitStringType")
    private String bits;

You can also register this type with hibernate to use a registered name instead of a fully qualified Java class.

]]>
http://www.yonlabs.com/2021/07/how-to-map-postgresql-bit-with-hibernate/feed/ 0
Exploit ‘none’ Algorithm in JWT http://www.yonlabs.com/2021/07/exploit-none-algorithm-in-jwt/ http://www.yonlabs.com/2021/07/exploit-none-algorithm-in-jwt/#respond Thu, 01 Jul 2021 17:31:00 +0000 https://www.yonlabs.com/?p=316 Read more

]]>
What is none algorithm in JWT?

JWT RFC describes unsecured JWTs where there is no signature present. Such unsecured tokens have a header alg parameter set to none.

{"alg":"none"}

How to create a JWT token with the none algorithm?

To create a JWT token, you can use any programming language and any JWT library you like.

In my example I use Java and io.jsonwebtoken JJWT library. Please, note that I don’t use signWith method anywhere in my code, thus the generated token will not have any signing algorithm set up, implicitly having none algorithm configured.

Jwts.builder()
    .setSubject(subject)
    .setIssuedAt(Date.from(now()))
    .setIssuer("jwt-demo")
    .setExpiration(Date.from(now().plus(ofDays(1))))
    .compact();

When is an application vulnerable?

An application is vulnerable when it doesn’t verify the signature nor algorithm set in a token. It may happen due to a misleading library design where decode and verify functions are not properly distinguished. Unfortunately, that’s the case of io.jsonwebtoken JJWT. The library provides two methods parse and parseClaimsJws. The parse method decodes a token but doesn’t verify its signature. The parseClaimsJws method decodes a token and verifies its signature.

The below code is vulnerable:

Jwts.parser()
    .setSigningKey(secretKey)
    .parse(token);
]]>
http://www.yonlabs.com/2021/07/exploit-none-algorithm-in-jwt/feed/ 0
Hashcat to Crack JWT http://www.yonlabs.com/2020/10/hashcat-to-crack-jwt/ http://www.yonlabs.com/2020/10/hashcat-to-crack-jwt/#comments Mon, 26 Oct 2020 19:35:00 +0000 https://www.yonlabs.com/?p=314 Read more

]]>
Introduction

In this article, I’m going to explain what hashcat is and how you can use it to crack an HS256 JSON Web Token using a brute-force attack.

With a weak JWT, your applications become vulnerable to identity theft as a hacker can impersonate any user he wants once the JWT is cracked and the HS256 secret is revealed.

Hashcat

hashcat is a password cracker, or, officially, a password recovery tool. It’s one of the most advanced tools, supporting five attack modes and over 300 hashing algorithms.

hashcat is highly optimized and is able to make use of CPUs, GPUs, and other hardware accelerators on Linux, Windows, and macOS. That makes hashcat supposedly the world’s fastest tool in its kind, and definitely the fastest among freely available ones.

HS256 JSON Web Token

JWT

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for transmitting information between parties as a JSON object. JWT is widely used in modern applications as a stateless authorization mechanism where a token represents a self-contained session of a logged-in user.

JWT can be encrypted, but it usually is only digitally signed. Such a JWT guarantees integrity (it can’t be modified) but not confidentiality (the information is open to the public).

Structure

If you see a JWT, it usually is a long string of letters and numbers with occasional dots. You can decode such a token at one of the online tools, like jwt.io, and see its structure:

  • header
  • payload
  • signature.

HS256

The header part of a JWT contains the algorithm used to sign a token. HS256 stands for HMAC with SHA-256.

HMAC (hash-based message authentication code) is a type of message authentication code involving a cryptographic hash function and a secret cryptographic key. HMAC is a symmetric algorithm that uses a shared secret for the generation and verification of signatures. HMAC can be used in combination with various hash functions. One of them is SHA-256.

JWT Cracking

Installation

You can install hashcat via a package manager available on your system or directly from binaries or sources.

Using a package manager on macOS:

brew install hashcat

Using a package manager on Ubuntu:

sudo apt-get install hashcat

Unfortunately, this way you will usually get an older version of hashcat. To install the newest version, download and install the latest binaries.

Vulnerable Token and Demo

To crack a JWT, we need a JWT, preferably a vulnerable JWT. I have prepared a vulnerable application available at demo.yonlabs.com. The demo is hosted in Oracle Cloud and you can use it any time you want, not only for password cracking but to exploit other vulnerabilities as well!

How to obtain a vulnerable token?
  1. Register a new account at demo.yonlabs.com.
  2. Log in to the application.
  3. Use a developer tool in your browser to see application session storage and access a token.

In the Chrome browser, you open their developer tools via View > Developer > Developer Tool. Then you go to the Application tab, followed by opening the Session Storage:

Cracking

If you have the hashcat installed and if you have copied a vulnerable token, it’s time to start cracking.

The minimal number of options for hashcat is:

  • attack mode: -a
  • hash mode: -m

There are five main attack modes:

  • dictionary attack (mode 0)
  • combinator attack (mode 1)
  • brute-force and mask-attack (mode 3)
  • hybrid attack combining wordlists+masks (mode 6)
  • hybrid attack combining masks+wordlists (mode 7).

There are literally hundreds of hash types supported by hashcat, starting from MD5 (hash mode 0) to SHA family to GOST family, and many more, including JWT (mode 16500).

The basic command to start cracking in a brute-force mode for JWT is:

hashcat -m 16500 -a 3 <your_token_here>

You should see a verbose output of hashcat looking like this:

In our case, hashcat should be able to find the secret fairly quickly. Though it may take a lot of time to crack hashes for other cases or even it may never end.

Once hashcat stops, it means your token has been cracked. hashcat does not display a found secret at once, it stores the found secret in a potfile. To display the found secret, you need to call hashcat as:

hashcat -m 16500 -a 3 <your_token_here> --show

Conclusion

You have just learned what hashcat is and how easily you can use it to crack a weak JWT.

In your applications, make sure you use a strong secret for your JWT tokens.

A key of the same size as the hash output (for instance, 256 bits for HS256) or larger MUST be used with this algorithm.

RFC7518

The recommended secret size for the HS family is at least the size of the hash output. So, for HS256 it means at least 256 bits (32 bytes).

This is just the tip of an iceberg when it comes to hashcat features! Stay tuned!

]]>
http://www.yonlabs.com/2020/10/hashcat-to-crack-jwt/feed/ 3
Moving to Oracle Cloud http://www.yonlabs.com/2020/09/moving-to-oracle-cloud/ http://www.yonlabs.com/2020/09/moving-to-oracle-cloud/#respond Tue, 01 Sep 2020 17:59:14 +0000 https://www.yonlabs.com/?p=276 Read more

]]>
It’s time to move to a new environment! I’m happy to announce that as of today, my security demos will be available 24/7 in Oracle Cloud! 🙂

How did I start my hacker’s guide demos? When did it start? And how have I moved to Oracle Cloud?

Security Demos

My first conference presentation about security was at JavaOne in 2014 titled Building secure application with Java EE. It was a 90-minute deep-dive session, more challenging due to being a featured speaker.

I didn’t want to bore attendees, so I decided to showcase security theory in practice. I developed a couple of demos to illustrate common authentication and session management problems interactively. I mean, live hacking!

I’m truly glad that the audience liked my demos!

Since that time, the security demos grew into a series ‘The Hacker’s Guide to …’, including session hijacking, XSS, NoSQL, and, most recently, JWT security.

And I’m even more glad the audiences still like my demos!

Hosting

To present live demos and interactive hacking with audience, I needed:

  • a vulnerable application
  • a public server to deploy my vulnerable application to be available to audience
Vulnerable application

That part was easy! 🙂 I developed a series of demos myself, showcasing:

  • security vulnerabilities in authentication and session management using Java EE and Glassfish
  • cross-site scripting (XSS) vulnerabilities using node.js
  • NoSQL injections using node.js and mongodb
  • JWT security vulnerabilities using angular and REST services in Java
Public server

Back in 2014, I decided to use AWS and its micro instance. It worked pretty well, especially when the instance was free. However, soon the bills started to pile up. I decided to turn my demos on only for my conferences, training, and workshops. Other times, it was disabled. It was not very convenient because participants often wanted to explore the demos in detail later on.

Oracle Cloud

Thanks to becoming Oracle Grounbreaker Ambassador, I’m allowed to use Oracle Cloud resources within a certain quota. It’s a great news! Now my demos can be online 24/7.

Today, I have officially moved my JWT security demos to Oracle Cloud. They are available at demo.yonlabs.com. My first conference appearance with new demos will be at JavaZone on September 9th, 2020.

Enjoy my demos and Oracle Cloud!

]]>
http://www.yonlabs.com/2020/09/moving-to-oracle-cloud/feed/ 0
I’m Oracle Groundbreaker Ambassador! http://www.yonlabs.com/2020/08/oracle-groundbreaker-ambassador/ http://www.yonlabs.com/2020/08/oracle-groundbreaker-ambassador/#comments Fri, 07 Aug 2020 15:30:54 +0000 https://www.yonlabs.com/?p=1 Read more

]]>
Wow! It’s official now! I have become an Oracle Groundbreaker Ambassador.

Oracle Groundbreaker Ambassadors have expertise in modern development areas such as cloud, microservices, containers, Java, DevOps, continuous delivery, open-source technologies, and SQL/NoSQL databases. These professionals are contributors to open source projects, authors on contemporary development approaches, and speakers at top industry conferences such as DeveloperWeek, DevNexus, Devoxx, Oracle Code and Oracle Code One, QCon, and Velocity. Besides presenting, writing, or contributing to open source projects, Oracle Groundbreaker Ambassadors may also play a leadership role in user groups, answer questions in forums, and provide Oracle product management with feedback.

https://developer.oracle.com/ambassador/

I am truly honored to be recognized by such a reputable company that stands by my beloved Java, the famous Oracle Database, and the exciting Oracle Cloud.

I am even more excited because I am planning to explore Oracle Cloud in detail. The first step will be to move my security demos to a new, hopefully, very friendly, hosting environment!

Stay tuned!

]]>
http://www.yonlabs.com/2020/08/oracle-groundbreaker-ambassador/feed/ 1