如何执行基本的Spring Boot应用安全配置。

huangapple go评论60阅读模式
英文:

How to perform a basic Spring Boot application security

问题

我期待在生产环境中部署我的Spring应用程序,并且我想包含一些基本且可靠的安全措施

首先,我将WebSecurityConfigurerAdapter扩展到了我的SecurityConfiguration.java中:

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Autowired
	UserDetailsService userDetailsService ;

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

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable().authorizeRequests()
			.antMatchers("/admin").hasAuthority("ADMIN")
			.antMatchers("/ekab").hasAuthority("EKAB")
			.antMatchers("/dimos").hasAuthority("DIMOS")
			.antMatchers("/", "/users/**", "/aeds/**", "/events/**", "/reports/**", "/static/**").permitAll()
			.anyRequest().authenticated()
			.and()
			.formLogin().loginPage("/login")
			.defaultSuccessUrl("/dashboard", true)
			.permitAll()
			.and()
			.logout()
			.permitAll();
	}

	@Bean
	public PasswordEncoder getPasswordEncoder() {
		return NoOpPasswordEncoder.getInstance();
	}
}

在生产环境中应启用CSRF,尽管目前我不处理任何csrf令牌。

  • GET端点:请注意,/users/**包含一些包含用户信息GET端点,我可以限制谁可以访问它们吗?

  • POST端点:我还发现一些通过使用JSON Web Token来保护POST的方法,这是最佳实践吗?

Spring还提供了OAuth2.0RSALDAP等依赖项以增强安全性。

我应该使用哪一个?它们是否可以防止DDOS攻击以及暴力破解攻击?

我是否需要在应用程序的部署环境中进行修改?

英文:

I'm looking forward to deploying my Spring Application on a production environment and i'd like to include some basic and solid security measures.

First things first, i extended WebSecurityConfigurerAdapter into my SecurityConfiguration.java

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Autowired
	UserDetailsService userDetailsService ;
	
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		// TODO Auto-generated method stub
		auth.userDetailsService(userDetailsService);
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// TODO Auto-generated method stub
		http.csrf().disable().authorizeRequests()
        .antMatchers("/admin").hasAuthority("ADMIN")
        .antMatchers("/ekab").hasAuthority("EKAB")
        .antMatchers("/dimos").hasAuthority("DIMOS")
        .antMatchers("/","/users/**","/aeds/**","/events/**","/reports/**","*/static/**").permitAll()
        .anyRequest().authenticated()
		.and()
	.formLogin().loginPage("/login")
	.defaultSuccessUrl("/dashboard",true)
		.permitAll()
		.and()
	.logout()
		.permitAll();
	}
	
	@Bean
    public PasswordEncoder getPasswordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

	
}


On a production environment CSRF should be enabled, although i don't handle any csrf tokens for now

  • GET Endpoints: Note that /users/** contains some GET endpoints containing User Information, can i apply limitations to who visits them?

  • POST Endpoints: I've also found some ways to secure POST by using
    a JSON Web Token , is it a best practice?

Spring also provides OAuth2.0 , RSA, LDAP, dependencies to enhance security.

Which one should i use? Does these prevent DDOS attacks as well as brute force attacks?

Do i have to make modifications in the application's deployment environment?

答案1

得分: 9

Spring Security提供了各种默认的安全攻击实现,以确保应用程序的安全性。

**由于您要求包括一些基本且可靠的安全措施。**以下是我认为可以改进一些的一些想法。

  1. 正如您所说,您已禁用了'CSRF令牌',这在您认为应用程序应该高度安全时是不好的。通常,大多数人在演示代码中禁用它,因为他们无法使用GET方法调用/logout URL,因为它要求您通过POST提交带有_csrf令牌的表单。很高兴您已在生产中照顾到了这一点。

  2. **会话固定攻击:**这是一种攻击类型,可以通过提供同一网站的URL并将JSESSIONID附加到URL中来窃取当前会话。Spring Security框架已默认处理此问题,并在用户登录后迁移会话。相应的配置如下:

    http.sessionManagement()
        .sessionFixation().migrateSession()
    
  3. **保护会话Cookie:**恶意脚本可以从浏览器端读取您的Cookie信息,因此您需要确保您的Cookie是安全的,并且可以通过服务器端代码访问它们,方法是将它们设置为HttpOnly。为此,您可以在应用程序的application.properties中使用以下配置:

    server.servlet.session.cookie.http-only=true
    
  4. **在Https上运行您的应用程序:**确保在生产中使用Https,而且在这种情况下,您可以通过在application.properties中添加以下配置来强制仅通过Https协议传输Cookie:

    server.servlet.session.cookie.secure=true
    

    并且为了强制使用Https连接,在configure()方法中添加以下行(不过这还不够,因为您还需要设置公钥/私钥):

    http.requiresChannel().requiresSecure();
    
  5. **应用内容安全策略 (CSP):**用户内容安全策略,以避免任何XSS攻击。Spring Security默认提供了各种安全头。但它不会添加内容安全策略头,您可以在您的安全配置文件中添加它们,如下所示:

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.headers().contentSecurityPolicy("script-src 'self' https://myclientscriptlocation.example.com; object-src https://myclientsideplugins.example.com; report-uri /cspreport-endpoint/");
        }
    }
    
  6. **密码哈希:**您的安全配置中未使用密码哈希。在将密码存储到数据库中时,您必须保持密码哈希化。

  7. **保护您的application.properties文件:**安全性不仅应该防御外部攻击,还应该防御内部攻击。例如,加密和解密数据库密码或其他配置密码。参考这里了解如何保护您的application.properties

GET端点:请注意,/users/** 包含一些GET端点,包含用户信息,我可以对访问它们的人应用限制吗?

是的,您可以应用限制,但这取决于您的要求,您想要什么。我可以想到的一个示例是IP地址过滤。例如,如果您只希望美国的用户能够访问,或者如果您知道用户的IP范围等。

.antMatchers("/foos/**").hasIpAddress("xx.xxx.xxx.xx")

POST端点:我也发现了一些通过使用JSON Web Token来保护POST的方法,这是最佳实践吗?

JWT主要用于RESTful Web服务。如果您的应用程序暴露REST端点并需要经过身份验证的访问,那么JWT是最佳选择。

Spring还提供了OAuth2.0、RSA、LDAP、增强安全性的依赖项。

这些是不同的身份验证和授权方式。其中一些具有多种身份验证和授权流程,但当外部用户访问它们时,将应用相同的安全因素。

完全取决于您的项目需求是否需要它们。例如,如果您正在为内部组织使用开发应用程序,用户/员工在组织级别设置了一切,并且您希望每个人都能访问此应用程序,那么LDAP集成更好。OAuth2.0在有多个微服务并且需要任何社交登录实现(如“使用Google登录”或“使用Facebook登录”)时更合适。

这些是否防止DDOS攻击和暴力攻击?

不,这应该通过调整各种安全参数来处理,如限制会话时间、检查安全头、处理内存泄漏、为POST请求设置超时以防止任何人提交大量请求负载等。您必须付出一些努力来减轻这些安全攻击。

PS:从安全配置中删除permitAll()

.defaultSuccessUrl("/dashboard", true)
.permitAll()
英文:

Spring Security provides various default security attack implementation to make sure the application is secured.

Since you asked to include some basic and solid security measures. Below are a few of my thoughts which can improve a bit.

  1. As you told, You have disabled 'CSRF token' which is not good when you think your application should be highly secured. Usually, most of the people disable(in demo code) because they won't be able to call /logout URL with the GET method as it requires you to submit it via POST with _csrf token. Good that you have taken care of in production.

  2. Session Fixation Attack: This is the type of attack where one can steal your current session by offering their URL of the same website and append JSESSIONID into URL, with the URL rewrite approach. Spring Security Framework has taken care of this by default and it migrates the session once the user logs in. The corresponding configuration would be -

    http.sessionManagement()
      .sessionFixation().migrateSession()
    
  3. Securing session cookie: Malicious script can read your cookie information from the browser end so you need to make sure that your cookie is secured and are accessible by server-side code by making them HttpOnly. For that, you can use the below config in your application.properties -

    server.servlet.session.cookie.http-only=true
    
  4. Running your app on Https: Make sure that you use https in production and also in that case you can force your cookies to travel over https protocol only by adding below config in your application.properties.

     server.servlet.session.cookie.secure=true
    

    and to force https connection add below lines in configure() method (this won't be enough though because you have to get your public/private key setup also using keytool)

       http.requiresChannel().requiresSecure();
    
  5. Applying CSP: User Content security policy to avoid any XSS attacks. Spring security by default provides various security headers. But it does not add Content security policy headers you can add them in your security config file like below

     @EnableWebSecurity
     public class WebSecurityConfig extends
     WebSecurityConfigurerAdapter {
     @Override
     protected void configure(HttpSecurity http)
     throws Exception {
     http.headers().contentSecurityPolicy("script-src
    'self' https://myclientscriptlocation.example.com; object-src
     https://myclientsideplugins.example.com; report-uri /cspreport-endpoint/");
    }
    

    }

  6. Password hashing: Which you are not using your security config. You have to keep password hashed while storing them into the database.

  7. Securing your application.properties' Security should be applied not only from outsiders, but it should also be protected from insiders as well. Like encryption and decryption of database passwords or any other config passwords. Follow here on how to secure your application properties.

> GET Endpoints: Note that /users/** contains some GET endpoints
> containing User Information, can I apply limitations to who visits
> them?

Yes, you can apply. But that depends on your requirement what you want here. One example that I can think of is, IP Address filtering. Like if you want only those users can access which are in the US or if you know the IP range of user etc.

  .antMatchers("/foos/**").hasIpAddress("xx.xxx.xxx.xx")

> POST Endpoints: I've also found some ways to secure POST by using a
> JSON Web Token , is it a best practice?

JWT mostly used in RESTful web services. If your application is exposing rest endpoints and requires authenticated access then JWT is the best option.

> Spring also provides OAuth2.0, RSA, LDAP, dependencies to enhance
> security.

These are different ways of authentication and authorization. Some of them has multiple flows to do authentication and authorization but The same security factors would be applied to these when they are accessed by outside the users.

It totally depends on your project requirement whether you need them or not. For example, if you are developing an application for internal organization use where user/employee has everything set up at the organization level and you want everyone to access this application then LDAP integration is better.

OAuth2.0 is better when you have multiple microservices + you want any social login implementation like Login with Google or Login with Facebook then you can follow OAuth2.0 integration

> Does these prevent DDOS attacks as well as brute force attacks?

No. This should be taken care of by tuning various security parameters like limiting the session time, checking security headers, handling memory leaks, applying timeout for POST requests so that no one could post a huge request payload, etc. You have to do a bit of leg work to mitigate such security attacks.

PS: Remove permitAll() from security configuration.

.defaultSuccessUrl("/dashboard",true)
    .permitAll()

huangapple
  • 本文由 发表于 2020年5月30日 02:14:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/62092295.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定