, ,

Securing SpringBoot Maven APIs and Prevent SQL Injection

Posted by

SpringBoot is one of the best frameworks to build RESTful APIs.Data breaches are becoming more common and it is high time for us developers to secure our APIs. It comes with handy ways to secure the services by applying some of the principles we will be discussing today on how to secure your Spring Boot Maven APIs and prevent SQL injection.

SQL Injection Explained is an attack where an attacker introduces a malicious SQL code to a database query that grants them access/modify the data in the DB. This usually happens when input is not correctly validated before implementing the query

SQL Injection Prevention

Use Prepared Statements

Prepared statements are a parameterized query that separates the SQL code from the user input. This prevents the user input from being interpreted as SQL code. Prepared statements can be used with JDBC or JPA.

Here’s an example of using a prepared statement with JDBC:

String sql = "SELECT * FROM users WHERE username =? AND password = ?";
PreparedStatement statement = connection.prepareStatement(SQL);
statement.setString(1, username);
statement.setString(2, password);
ResultSet result = statement.executeQuery();

Implement Object-Relational Mapping (ORM)

ORM frameworks like Hibernate and Spring Data JPA provide a way to map Java objects to database tables. the SQL code will not be written manually hence eliminating the risk of SQL injection due to fewer human interactions.
Here’s an example of using Spring Data JPA:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsernameAndPassword(String username, String password);
}

3. User Input validation

Sanitizing user input involves removing or encoding characters that can be interpreted as SQL code. an example is using the libraries like OWASPJava Encoder or ESAPI.

OWASP Java Encoder Example:

String encodedUsername = ESAPI.encoder().encodeForSQL(new MySQLCodec(MySQLCodec.Mode.STANDARD), username);
String encodedPassword = ESAPI.encoder().encodeForSQL(new MySQLCodec(MySQLCodec.Mode.STANDARD), password);

4. Remove unrequired Database Permissions

Limiting database permissions reduces the impact of a successful SQL injection attack. It’s essential to give each user only the necessary permissions to perform their tasks. For example, users who only need to read data from a table should not have write permissions.

How to Secure Spring Boot Maven APIs?

1.Use HTTPS

HTTPS encrypts data in transit, preventing attackers from intercepting sensitive information. we can make use of the self-signed certificate provided by Springboot another alternative is to use one from a trusted authority.

Here’s an example of enabling HTTPS in Spring Boot:

```properties
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-alias=tomcat

2.Use Authentication and Authorization

Authentication allows us to verify user identity, whereas authorization refers to what actions the user is allowed to perform. Spring Security provides the most reliable options to implement Authorization and authentication

using Spring Security example:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .anyRequest().authenticated()
            .and().formLogin();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

3.Usage Rate Limiting

Rate limiting limits the number of requests a user can make within a certain period of time. This prevents attackers from overwhelming your API with requests and helps maintain the availability of your API.

Here’s an example of using Spring Boot Rate Limit:

@Configuration
public class RateLimitConfig {
    @Bean
    public RateLimiter rateLimiter() {
        return RateLimiter.of("user", 10, Duration.ofMinutes(1));
    }

    @Bean
    public KeyResolver keyResolver() {
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
    }

    @Bean
    public RedisRateLimiter redisRateLimiter(RedisConnectionFactory connectionFactory) {
        return new RedisRateLimiter(rateLimiter(), keyResolver(), connectionFactory);
    }
}

Conclusion

By using prepared statements, ORM frameworks, sanitizing user input, limiting database permissions, HTTPS, authentication and authorization, and rate limiting, you can significantly reduce the risk of a successful attack.

Leave a Reply

Your email address will not be published. Required fields are marked *