SlideShare a Scribd company logo
SECURITY FOR DEVELOPERS
Nanne Baars
About me
¨ Java developer
¨ Developer à Security consultant à Developer
¨ Project lead of WebGoat à
https://github.com/WebGoat/
WebGoat is…
¨ A deliberately vulnerable web application maintained
by OWASP designed to teach web application security lessons.
¨ In each lesson, users must demonstrate their understanding of a
security issue by exploiting a real vulnerability in the WebGoat
application
https://webgoat.github.io/WebGoat/
Learn in 3 steps
JavaFest. Nanne Baars. Web application security for developers
JavaFest. Nanne Baars. Web application security for developers
JavaFest. Nanne Baars. Web application security for developers
JavaFest. Nanne Baars. Web application security for developers
JavaFest. Nanne Baars. Web application security for developers
- Examples
- Background
- How to prevent
https://www.pentestpartners.com/security-blog/hacking-ski-helmet-audio/
https://www.pentestpartners.com/security-blog/hacking-ski-helmet-audio/
JavaFest. Nanne Baars. Web application security for developers
Secret management
Still a problem
https://darkport.co.uk/blog/ahh-shhgit!/
https://darkport.co.uk/blog/ahh-shhgit!/
JavaFest. Nanne Baars. Web application security for developers
https://blog.milessteele.com/posts/2013-07-07-hiding-djangos-secret-key.html
JavaFest. Nanne Baars. Web application security for developers
Within projects as developers…
¨ Make sure secrets do not end up in Git
¤ Encrypt your secrets (for example like Travis CI)
¤ More fancy use Vault, KeyCloak etc
¨ Use tooling to scan your repository
¨ Define a policy what should be done in case it happens
¤ Git history
As a team…
¨ Think about what to do when a team member leaves…
¤ Think about how many systems you have access to, is the access to AWS,
Kubernetes, Github, Gitlab, Jira etc centrally provided?
¨ Again, have a clear policy in place
Easy to automate
Cryptography
private static final byte[] ENCRYPT_IV = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
public static String encrypt(String dataPassword, String cleartext) throws Exception
{
IvParameterSpec zeroIv = new IvParameterSpec(ENCRYPT_IV);
SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
…
}
private static final byte[] ENCRYPT_IV = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
public static String encrypt(String dataPassword, String cleartext) throws Exception
{
IvParameterSpec zeroIv = new IvParameterSpec(ENCRYPT_IV);
SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
…
}
Cryptography vs developers
“In this post I will show you how to use RSA in Java…..”
public static String encrypt(String plainText, PublicKey publicKey) {
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(UTF_8));
return Base64.getEncoder().encodeToString(cipherText);
}
public static void main(String [] args) throws Exception {
// generate public and private keys
…
// sign the message
byte [] signed = encrypt(privateKey, "This is a secret message");
System.out.println(new String(signed)); // <<signed message>>
// verify the message
byte[] verified = decrypt(pubKey, encrypted);
System.out.println(new String(verified)); // This is a secret message
}
public static byte[] encrypt(PrivateKey privateKey, String message) {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(message.getBytes());
}
public static byte[] decrypt(PublicKey publicKey, byte [] encrypted) {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(encrypted);
}
JavaFest. Nanne Baars. Web application security for developers
Solution - Libsodium or Google Tink
https://github.com/google/tink
Path traversal
¨ A path(directory) traversal is a vulnerability where an attacker is able
to access or store files and directories outside the location where the
application is running.
¨ For example: http://example.com/file=report.pdf
¨ Change into: http://example.com/file=../../../../../etc/passwd
¨ In case of a file upload you might be able to overwrite other files
https://hackerone.com/reports/827052
https://snyk.io/research/zip-slip-vulnerability
Mitigation in file upload
var multiPartFile = ...
var targetFile = new File("/tmp", multiPartFile.getOriginalName());
var canonicalPath = targetFile.getCanonicalPath();
if (!canonicalPath.startWith("/tmp") {
throw new IllegalArgumentException("Invalid filename");
}
IOUtils.copy(multiPartFile.getBytes(), targetFile);
Input validation
¨ Check for ../
¨ Be aware of encoding: %2e%2e/%2f
¨ Spring Security has: StrictHttpFirewall which automatically drops a
request if the path variable contains ../
@Getter("/f")
public void f(@RequestParam("name") String name) {
//name is automatically decoded so %2E%2E%2F%2E%2E%2Ftest
//will become ../../test
}
@Getter("/g")
public void g(HttpServletRequest request) {
var queryString = request.getQueryString();
// will return %2E%2E%2F%2E%2E%2Ftest
}
@Getter("/h")
public void h(HttpServletRequest request) {
var name = request.getParam("name");
//will return ../../test
Host-Header Injection
¨ In web applications, developers use the HTTP Host header available in
HTTP request
¨ A remote attacker can exploit this by sending a fake header with a
domain name under the attackers control.
Often found during password reset
curl 'https://webgoat-cloud.net/create-password-reset-link' --data-raw 'email=test1234@webgoat-cloud.net'
Let’s do that again…
curl 'http://webgoat-cloud.net/create-password-reset-link'
-H'Host: attacker.com'
--data-raw 'email=test1234@webgoat.org'
JavaFest. Nanne Baars. Web application security for developers
JavaFest. Nanne Baars. Web application security for developers
Example 2: Azure Authentication / Spring Boot
Example.com
Easy to setup
¨ Standard Spring Boot / Azure auto configuration provided
1. Register your application with your Azure Active Directory Tenant
2. Configure application.properties
spring.security.oauth2.client.registration.azure.client-id=xxxxxx-your-client-id-xxxxxx
spring.security.oauth2.client.registration.azure.client-secret=xxxxxx-your-client-secret-xxxxxx
azure.activedirectory.tenant-id=xxxxxx-your-tenant-id-xxxxxx
azure.activedirectory.active-directory-groups=group1, group2
Spring Boot configuration
¨ We enabled this setting in the application.properties:
server.use-forward-headers=true
curl -i http://localhost:8080
HTTP/1.1 302 Found
Location: http://localhost:8080/oauth2/authorization/azure
curl -i http://localhost:8080/oauth2/authorization/azure
HTTP/1.1 302 Found
Location:
https://login.microsoftonline.com/common/oauth2/authorize?response_type=code
https://graph.microsoft.com/user.read&state=&
redirect_uri=http://localhost:8080/login/oauth2/code/azure
Now let’s try
curl -i -H"X-Forwarded-Host: attacker.com" http://localhost:8080/
HTTP/1.1 302 Found
Location: http://attacker.com/oauth2/authorization/azure
But wait how does the redirect_uri work?
curl -i http://localhost:8080/oauth2/authorization/azure
HTTP/1.1 302 Found
Location:
https://login.microsoftonline.com/common/oauth2/authorize?response_type=codehttps://graph.
microsoft.com/user.read&state=&redirect_uri=http://localhost:8080/login/oauth2/code/azure
spring.security.oauth2.client.registration.azure.redirect-uri-template={baseUrl}/login/oauth2/code/{registrationId}
curl -i -H"X-Forwarded-Host: attacker.com" http://localhost:8080/oauth2/authorization/azure
HTTP/1.1 302 Found
Location:
https://login.microsoftonline.com/common/oauth2/authorize?response_type=code
https://graph.microsoft.com/user.read&state=&
redirect_uri=http://attacker.com/login/oauth2/code/azure
(Un)fortunately this does not work J
https://tools.ietf.org/html/rfc6749#section-10.6
JavaFest. Nanne Baars. Web application security for developers
Recap
¨ This is not a bug in Spring security
¨ Something which happened because we added:
server.use-forward-headers=true
Solution
/**
* <p>
* Determines which hostnames should be allowed. The default is to allow any
* hostname.
* </p>
*
* @param allowedHostnames the predicate for testing hostnames
* @since 5.2
*/
public void setAllowedHostnames(Predicate<String> allowedHostnames) {
if (allowedHostnames == null) {
throw new IllegalArgumentException("allowedHostnames cannot be null");
}
this.allowedHostnames = allowedHostnames;
}
@Bean
public HttpFirewall firewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowedHttpMethods(Arrays.asList("GET", "POST"));
firewall.setAllowedHostnames(s -> s.equals("localhost"));
curl -i -H"X-Forwarded-Host: attacker.com" http://localhost:8080/
java.lang.RuntimeException: org.springframework.security.web.firewall.RequestRejectedException:
The request was rejected because the domain attacker.com is untrusted.
at io.undertow.servlet.spec.RequestDispatcherImpl.error(RequestDispatcherImpl.java:507)
at io.undertow.servlet.spec.RequestDispatcherImpl.error(RequestDispatcherImpl.java:427)
Solution
¨ As developers we are responsible to validate those headers
¨ Verify all headers you can receive from the outside.
¤ This includes: X-Forwarded-For, X-Forwarded-Host etc
¨ Do not rely on thinking reversed proxy will solve this!
¨ Check to see whether the framework has built in protection
Where to start...
1. Make developers security aware
n Code review
n Practice / learn / adapt
2. Adopt a security guideline in your team
3. Test your own application
4. Start using tools to find to most obvious mistakes

More Related Content

DOCX
MISE EN PLACE DE SERVICES RESEAUX ET OPTIMISATION DE LA SECURITE AU SEIN DE l...
PDF
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
PPTX
Secure Coding for NodeJS
PDF
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
PDF
Step-by-step Development of an Application for the Java Card Connected Platform
PDF
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
PDF
Securing Cassandra for Compliance
PDF
Hardening cassandra q2_2016
MISE EN PLACE DE SERVICES RESEAUX ET OPTIMISATION DE LA SECURITE AU SEIN DE l...
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
Secure Coding for NodeJS
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Step-by-step Development of an Application for the Java Card Connected Platform
Continuous Delivery with Maven, Puppet and Tomcat - ApacheCon NA 2013
Securing Cassandra for Compliance
Hardening cassandra q2_2016

Similar to JavaFest. Nanne Baars. Web application security for developers (20)

PDF
Service Worker - Reliability bits
PPTX
Building Your Own IoT Platform using FIWARE GEis
PDF
AWS Study Group - Chapter 03 - Elasticity and Scalability Concepts [Solution ...
PDF
Hta t07-did-you-read-the-news-http-request-hijacking
PDF
FIWARE Wednesday Webinars - How to Secure IoT Devices
PDF
DevSecOps: Let's Write Security Unit Tests
PDF
Fun With Spring Security
PDF
PHP SA 2014 - Releasing Your Open Source Project
PDF
I/O Extended 2019 WebTech - New capabilities for the web
PDF
Burn down the silos! Helping dev and ops gel on high availability websites
PDF
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
PDF
Deploying Django with Ansible
PDF
2020-02-20 - HashiCorpUserGroup Madring - Integrating HashiCorp Vault and Kub...
PPTX
Azure from scratch part 4
PDF
Cloud 101: Hands-on Heroku & AWS
PPT
General Principles of Web Security
PDF
Nko workshop - node js crud & deploy
ODP
Rapid JCR Applications Development with Sling
PDF
Greach 2019 - Creating Micronaut Configurations
PDF
Securing Prometheus exporters using HashiCorp Vault
Service Worker - Reliability bits
Building Your Own IoT Platform using FIWARE GEis
AWS Study Group - Chapter 03 - Elasticity and Scalability Concepts [Solution ...
Hta t07-did-you-read-the-news-http-request-hijacking
FIWARE Wednesday Webinars - How to Secure IoT Devices
DevSecOps: Let's Write Security Unit Tests
Fun With Spring Security
PHP SA 2014 - Releasing Your Open Source Project
I/O Extended 2019 WebTech - New capabilities for the web
Burn down the silos! Helping dev and ops gel on high availability websites
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
Deploying Django with Ansible
2020-02-20 - HashiCorpUserGroup Madring - Integrating HashiCorp Vault and Kub...
Azure from scratch part 4
Cloud 101: Hands-on Heroku & AWS
General Principles of Web Security
Nko workshop - node js crud & deploy
Rapid JCR Applications Development with Sling
Greach 2019 - Creating Micronaut Configurations
Securing Prometheus exporters using HashiCorp Vault
Ad

More from FestGroup (10)

PPTX
JavaFest. Барух Садогурский. DevOps для разработчиков (или против них?!)
PDF
JavaFest. Виктор Полищук. Legacy: как победить в гонке
PDF
JavaFest. Cedrick Lunven. Build APIS with SpringBoot - REST, GRPC, GRAPHQL wh...
PDF
JavaFest. Philipp Krenn. Scale Elasticsearch for Your Java Applications
PDF
JavaFest. Grzegorz Piwowarek. Hazelcast - Hitchhiker’s Guide
PDF
JavaFest. Денис Макогон. 6 заблуждений относительно современной Java
PDF
JavaFest. Taras Boychuk. There is always a choice. Spring Data JDBC vs. Hiber...
PDF
JavaFest. Вадим Казулькин. Projects Valhalla, Loom and GraalVM
PDF
JavaFest. Антон Лемешко. Model-Driven Development in the Open Java Universe
PDF
JavaFest. Дмитрий Сергеев. Data processing with Kafka Streams and Spring Fram...
JavaFest. Барух Садогурский. DevOps для разработчиков (или против них?!)
JavaFest. Виктор Полищук. Legacy: как победить в гонке
JavaFest. Cedrick Lunven. Build APIS with SpringBoot - REST, GRPC, GRAPHQL wh...
JavaFest. Philipp Krenn. Scale Elasticsearch for Your Java Applications
JavaFest. Grzegorz Piwowarek. Hazelcast - Hitchhiker’s Guide
JavaFest. Денис Макогон. 6 заблуждений относительно современной Java
JavaFest. Taras Boychuk. There is always a choice. Spring Data JDBC vs. Hiber...
JavaFest. Вадим Казулькин. Projects Valhalla, Loom and GraalVM
JavaFest. Антон Лемешко. Model-Driven Development in the Open Java Universe
JavaFest. Дмитрий Сергеев. Data processing with Kafka Streams and Spring Fram...
Ad

Recently uploaded (20)

PDF
TR - Agricultural Crops Production NC III.pdf
PDF
Business Ethics Teaching Materials for college
PDF
RMMM.pdf make it easy to upload and study
PDF
O5-L3 Freight Transport Ops (International) V1.pdf
PPTX
Renaissance Architecture: A Journey from Faith to Humanism
PDF
Basic Mud Logging Guide for educational purpose
PDF
O7-L3 Supply Chain Operations - ICLT Program
PDF
Origin of periodic table-Mendeleev’s Periodic-Modern Periodic table
PPTX
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
PDF
102 student loan defaulters named and shamed – Is someone you know on the list?
PPTX
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
PPTX
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
PPTX
Cell Types and Its function , kingdom of life
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
PPTX
master seminar digital applications in india
PPTX
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx
PPTX
Pharma ospi slides which help in ospi learning
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PPTX
Week 4 Term 3 Study Techniques revisited.pptx
PDF
Classroom Observation Tools for Teachers
TR - Agricultural Crops Production NC III.pdf
Business Ethics Teaching Materials for college
RMMM.pdf make it easy to upload and study
O5-L3 Freight Transport Ops (International) V1.pdf
Renaissance Architecture: A Journey from Faith to Humanism
Basic Mud Logging Guide for educational purpose
O7-L3 Supply Chain Operations - ICLT Program
Origin of periodic table-Mendeleev’s Periodic-Modern Periodic table
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
102 student loan defaulters named and shamed – Is someone you know on the list?
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
Cell Types and Its function , kingdom of life
human mycosis Human fungal infections are called human mycosis..pptx
master seminar digital applications in india
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx
Pharma ospi slides which help in ospi learning
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
Week 4 Term 3 Study Techniques revisited.pptx
Classroom Observation Tools for Teachers

JavaFest. Nanne Baars. Web application security for developers

  • 2. About me ¨ Java developer ¨ Developer à Security consultant à Developer ¨ Project lead of WebGoat à https://github.com/WebGoat/
  • 3. WebGoat is… ¨ A deliberately vulnerable web application maintained by OWASP designed to teach web application security lessons. ¨ In each lesson, users must demonstrate their understanding of a security issue by exploiting a real vulnerability in the WebGoat application
  • 10. - Examples - Background - How to prevent
  • 20. Within projects as developers… ¨ Make sure secrets do not end up in Git ¤ Encrypt your secrets (for example like Travis CI) ¤ More fancy use Vault, KeyCloak etc ¨ Use tooling to scan your repository ¨ Define a policy what should be done in case it happens ¤ Git history
  • 21. As a team… ¨ Think about what to do when a team member leaves… ¤ Think about how many systems you have access to, is the access to AWS, Kubernetes, Github, Gitlab, Jira etc centrally provided? ¨ Again, have a clear policy in place
  • 24. private static final byte[] ENCRYPT_IV = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; public static String encrypt(String dataPassword, String cleartext) throws Exception { IvParameterSpec zeroIv = new IvParameterSpec(ENCRYPT_IV); SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv); … } private static final byte[] ENCRYPT_IV = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; public static String encrypt(String dataPassword, String cleartext) throws Exception { IvParameterSpec zeroIv = new IvParameterSpec(ENCRYPT_IV); SecretKeySpec key = new SecretKeySpec(dataPassword.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv); … }
  • 26. “In this post I will show you how to use RSA in Java…..” public static String encrypt(String plainText, PublicKey publicKey) { Cipher encryptCipher = Cipher.getInstance("RSA"); encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] cipherText = encryptCipher.doFinal(plainText.getBytes(UTF_8)); return Base64.getEncoder().encodeToString(cipherText); }
  • 27. public static void main(String [] args) throws Exception { // generate public and private keys … // sign the message byte [] signed = encrypt(privateKey, "This is a secret message"); System.out.println(new String(signed)); // <<signed message>> // verify the message byte[] verified = decrypt(pubKey, encrypted); System.out.println(new String(verified)); // This is a secret message } public static byte[] encrypt(PrivateKey privateKey, String message) { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(message.getBytes()); } public static byte[] decrypt(PublicKey publicKey, byte [] encrypted) { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(encrypted); }
  • 29. Solution - Libsodium or Google Tink
  • 31. Path traversal ¨ A path(directory) traversal is a vulnerability where an attacker is able to access or store files and directories outside the location where the application is running. ¨ For example: http://example.com/file=report.pdf ¨ Change into: http://example.com/file=../../../../../etc/passwd ¨ In case of a file upload you might be able to overwrite other files
  • 34. Mitigation in file upload var multiPartFile = ... var targetFile = new File("/tmp", multiPartFile.getOriginalName()); var canonicalPath = targetFile.getCanonicalPath(); if (!canonicalPath.startWith("/tmp") { throw new IllegalArgumentException("Invalid filename"); } IOUtils.copy(multiPartFile.getBytes(), targetFile);
  • 35. Input validation ¨ Check for ../ ¨ Be aware of encoding: %2e%2e/%2f ¨ Spring Security has: StrictHttpFirewall which automatically drops a request if the path variable contains ../
  • 36. @Getter("/f") public void f(@RequestParam("name") String name) { //name is automatically decoded so %2E%2E%2F%2E%2E%2Ftest //will become ../../test } @Getter("/g") public void g(HttpServletRequest request) { var queryString = request.getQueryString(); // will return %2E%2E%2F%2E%2E%2Ftest } @Getter("/h") public void h(HttpServletRequest request) { var name = request.getParam("name"); //will return ../../test
  • 37. Host-Header Injection ¨ In web applications, developers use the HTTP Host header available in HTTP request ¨ A remote attacker can exploit this by sending a fake header with a domain name under the attackers control.
  • 38. Often found during password reset curl 'https://webgoat-cloud.net/create-password-reset-link' --data-raw 'email=test1234@webgoat-cloud.net'
  • 39. Let’s do that again… curl 'http://webgoat-cloud.net/create-password-reset-link' -H'Host: attacker.com' --data-raw 'email=test1234@webgoat.org'
  • 42. Example 2: Azure Authentication / Spring Boot Example.com
  • 43. Easy to setup ¨ Standard Spring Boot / Azure auto configuration provided 1. Register your application with your Azure Active Directory Tenant 2. Configure application.properties spring.security.oauth2.client.registration.azure.client-id=xxxxxx-your-client-id-xxxxxx spring.security.oauth2.client.registration.azure.client-secret=xxxxxx-your-client-secret-xxxxxx azure.activedirectory.tenant-id=xxxxxx-your-tenant-id-xxxxxx azure.activedirectory.active-directory-groups=group1, group2
  • 44. Spring Boot configuration ¨ We enabled this setting in the application.properties: server.use-forward-headers=true
  • 45. curl -i http://localhost:8080 HTTP/1.1 302 Found Location: http://localhost:8080/oauth2/authorization/azure curl -i http://localhost:8080/oauth2/authorization/azure HTTP/1.1 302 Found Location: https://login.microsoftonline.com/common/oauth2/authorize?response_type=code https://graph.microsoft.com/user.read&state=& redirect_uri=http://localhost:8080/login/oauth2/code/azure
  • 46. Now let’s try curl -i -H"X-Forwarded-Host: attacker.com" http://localhost:8080/ HTTP/1.1 302 Found Location: http://attacker.com/oauth2/authorization/azure
  • 47. But wait how does the redirect_uri work? curl -i http://localhost:8080/oauth2/authorization/azure HTTP/1.1 302 Found Location: https://login.microsoftonline.com/common/oauth2/authorize?response_type=codehttps://graph. microsoft.com/user.read&state=&redirect_uri=http://localhost:8080/login/oauth2/code/azure spring.security.oauth2.client.registration.azure.redirect-uri-template={baseUrl}/login/oauth2/code/{registrationId}
  • 48. curl -i -H"X-Forwarded-Host: attacker.com" http://localhost:8080/oauth2/authorization/azure HTTP/1.1 302 Found Location: https://login.microsoftonline.com/common/oauth2/authorize?response_type=code https://graph.microsoft.com/user.read&state=& redirect_uri=http://attacker.com/login/oauth2/code/azure
  • 49. (Un)fortunately this does not work J https://tools.ietf.org/html/rfc6749#section-10.6
  • 51. Recap ¨ This is not a bug in Spring security ¨ Something which happened because we added: server.use-forward-headers=true
  • 52. Solution /** * <p> * Determines which hostnames should be allowed. The default is to allow any * hostname. * </p> * * @param allowedHostnames the predicate for testing hostnames * @since 5.2 */ public void setAllowedHostnames(Predicate<String> allowedHostnames) { if (allowedHostnames == null) { throw new IllegalArgumentException("allowedHostnames cannot be null"); } this.allowedHostnames = allowedHostnames; }
  • 53. @Bean public HttpFirewall firewall() { StrictHttpFirewall firewall = new StrictHttpFirewall(); firewall.setAllowedHttpMethods(Arrays.asList("GET", "POST")); firewall.setAllowedHostnames(s -> s.equals("localhost")); curl -i -H"X-Forwarded-Host: attacker.com" http://localhost:8080/ java.lang.RuntimeException: org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the domain attacker.com is untrusted. at io.undertow.servlet.spec.RequestDispatcherImpl.error(RequestDispatcherImpl.java:507) at io.undertow.servlet.spec.RequestDispatcherImpl.error(RequestDispatcherImpl.java:427)
  • 54. Solution ¨ As developers we are responsible to validate those headers ¨ Verify all headers you can receive from the outside. ¤ This includes: X-Forwarded-For, X-Forwarded-Host etc ¨ Do not rely on thinking reversed proxy will solve this! ¨ Check to see whether the framework has built in protection
  • 55. Where to start... 1. Make developers security aware n Code review n Practice / learn / adapt 2. Adopt a security guideline in your team 3. Test your own application 4. Start using tools to find to most obvious mistakes