Upgrade to Pro — share decks privately, control downloads, hide ads and more …

10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Morocco 2019

Matt Raible
November 13, 2019

10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Morocco 2019

Spring Boot is an excellent way to build Java applications with the Spring Framework. If you’re developing apps that handle sensitive data, you should make sure they’re secure.

This session will cover HTTPS, dependency checking, CSRF, using a CSP to prevent XSS, OIDC, password hashing, and much more!

You’ll learn how to add these features to a real application, using the Java language you know and love.

* Blog post: https://developer.okta.com/blog/2018/07/30/10-ways-to-secure-spring-boot
* Cheat sheet: https://snyk.io/blog/spring-boot-security-best-practices/

Matt Raible

November 13, 2019
Tweet

More Decks by Matt Raible

Other Decks in Programming

Transcript

  1. @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void

    configure(HttpSecurity http) throws Exception { http.requiresChannel().anyRequest().requiresSecure(); } }
  2. @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void

    configure(HttpSecurity http) throws Exception { http.requiresChannel() .requestMatchers(r -> r.getHeader("X-Forwarded-Proto") != null) .requiresSecure(); } }
  3. 'use strict'; const fetch = require('node-fetch'); const AWS = require('aws-sdk');

    // eslint-disable-line import/no-extraneous-dependencies const s3 = new AWS.S3(); module.exports.save = (event, context, callback) => { fetch(event.image_url) .then((response) => { if (response.ok) { return response; } return Promise.reject(new Error( `Failed to fetch ${response.url}: ${response.status} ${response.statusText}`)); }) .then(response => response.buffer()) .then(buffer => ( s3.putObject({ Bucket: process.env.BUCKET, Key: event.key, Body: buffer, }).promise() )) .then(v => callback(null, v), callback); };
  4. 'use strict'; const fetch = require('node-fetch'); const AWS = require('aws-sdk');

    // eslint-disable-line import/no-extraneous-dependencies const s3 = new AWS.S3(); module.exports.save = (event, context, callback) => { fetch(event.image_url) .then((response) => { if (response.ok) { return response; } return Promise.reject(new Error( `Failed to fetch ${response.url}: ${response.status} ${response.statusText}`)); }) .then(response => response.buffer()) .then(buffer => ( s3.putObject({ Bucket: process.env.BUCKET, Key: event.key, Body: buffer, }).promise() )) .then(v => callback(null, v), callback); }; { "dependencies": { "aws-sdk": "^2.7.9", "node-fetch": "^1.6.3" } }
  5. 'use strict'; const fetch = require('node-fetch'); const AWS = require('aws-sdk');

    // eslint-disable-line import/no-extraneous-dependencies const s3 = new AWS.S3(); module.exports.save = (event, context, callback) => { fetch(event.image_url) .then((response) => { if (response.ok) { return response; } return Promise.reject(new Error( `Failed to fetch ${response.url}: ${response.status} ${response.statusText}`)); }) .then(response => response.buffer()) .then(buffer => ( s3.putObject({ Bucket: process.env.BUCKET, Key: event.key, Body: buffer, }).promise() )) .then(v => callback(null, v), callback); }; { "dependencies": { "aws-sdk": "^2.7.9", "node-fetch": "^1.6.3" } }
  6. 'use strict'; const fetch = require('node-fetch'); const AWS = require('aws-sdk');

    // eslint-disable-line import/no-extraneous-dependencies const s3 = new AWS.S3(); module.exports.save = (event, context, callback) => { fetch(event.image_url) .then((response) => { if (response.ok) { return response; } return Promise.reject(new Error( `Failed to fetch ${response.url}: ${response.status} ${response.statusText}`)); }) .then(response => response.buffer()) .then(buffer => ( s3.putObject({ Bucket: process.env.BUCKET, Key: event.key, Body: buffer, }).promise() )) .then(v => callback(null, v), callback); }; { "dependencies": { "aws-sdk": "^2.7.9", "node-fetch": "^1.6.3" } }
  7. 23

  8. @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void

    configure(HttpSecurity http) throws Exception { http .csrf() .csrfTokenRepository( CookieCsrfTokenRepository.withHttpOnlyFalse()); } }
  9. Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Content-Type-Options:

    nosniff Strict-Transport-Security: max-age=31536000; includeSubDomains X-Frame-Options: DENY X-XSS-Protection: 1; mode=block
  10. @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void

    configure(HttpSecurity http) throws Exception { http.headers() .contentSecurityPolicy("script-src 'self' " + "https://trustedscripts.example.com; " + "object-src https://trustedplugins.example.com; " + "report-uri /csp-report-endpoint/"); } }
  11. spring: security: oauth2: client: registration: okta: client-id: {clientId} client-secret: {clientSecret}

    provider: okta: issuer-uri: https://{yourOktaDomain}/oauth2/default
  12. 68