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

What's hot (20)

PPTX
Kubernetes Security
Karthik Gaekwad
 
PPTX
Kubernetes
Henry He
 
PPTX
Introduction to kubernetes
Rishabh Indoria
 
PDF
OpenShift Meetup - Tokyo - Service Mesh and Serverless Overview
María Angélica Bracho
 
PDF
Introducing Vault
Ramit Surana
 
PDF
mastering the curl command line.pdf
DanielStenberg7
 
PDF
Kubernetes API - deep dive into the kube-apiserver
Stefan Schimanski
 
PDF
In-depth forensic analysis of Windows registry files
Maxim Suhanov
 
PDF
Csw2017 bazhaniuk exploring_yoursystemdeeper_updated
CanSecWest
 
PDF
Tools kali
ketban0702
 
PDF
Boot process: BIOS vs UEFI
Alea Soluciones, S.L.
 
PDF
Namespaces and cgroups - the basis of Linux containers
Kernel TLV
 
PDF
Elastic Kubernetes Services (EKS)
sriram_rajan
 
ODP
Secureboot Survival Guide
lcplcp1
 
PDF
Linux device driver
chatsiri
 
PDF
Anthos - Oxford - AI - Cloud and edge implementations.pdf
AntonioGulli2
 
PPTX
VMware Tanzu Kubernetes Connect
VMware Tanzu
 
PPTX
Backstage at CNCF Madison.pptx
BrandenTimm1
 
PPTX
Red Hat Openshift Fundamentals.pptx
ssuser18b1c6
 
Kubernetes Security
Karthik Gaekwad
 
Kubernetes
Henry He
 
Introduction to kubernetes
Rishabh Indoria
 
OpenShift Meetup - Tokyo - Service Mesh and Serverless Overview
María Angélica Bracho
 
Introducing Vault
Ramit Surana
 
mastering the curl command line.pdf
DanielStenberg7
 
Kubernetes API - deep dive into the kube-apiserver
Stefan Schimanski
 
In-depth forensic analysis of Windows registry files
Maxim Suhanov
 
Csw2017 bazhaniuk exploring_yoursystemdeeper_updated
CanSecWest
 
Tools kali
ketban0702
 
Boot process: BIOS vs UEFI
Alea Soluciones, S.L.
 
Namespaces and cgroups - the basis of Linux containers
Kernel TLV
 
Elastic Kubernetes Services (EKS)
sriram_rajan
 
Secureboot Survival Guide
lcplcp1
 
Linux device driver
chatsiri
 
Anthos - Oxford - AI - Cloud and edge implementations.pdf
AntonioGulli2
 
VMware Tanzu Kubernetes Connect
VMware Tanzu
 
Backstage at CNCF Madison.pptx
BrandenTimm1
 
Red Hat Openshift Fundamentals.pptx
ssuser18b1c6
 

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

PDF
What Every Software Engineer Should Know About Security and Encryption
All Things Open
 
PPTX
Django cryptography
Erik LaBianca
 
PDF
apidays LIVE Australia 2020 - WT* is JWT? by Maciej Treder
apidays
 
PDF
apidays LIVE New York - WT* is JWT? by Maciej Treder
apidays
 
PDF
apidays LIVE Paris - WT* is JWT? by Maciej Treder
apidays
 
PDF
apidays LIVE LONDON - WT* is JWT? by Maciej Treder
apidays
 
PDF
apidays LIVE Hong Kong - WT* is JWT? by Maciej Treder
apidays
 
PPTX
Crypt-Oh No!
Zach Grace
 
PPTX
Flaws of password-based authentication
sluge
 
PDF
UVic Startup Slam September 2014 (Kiind)
sendwithus
 
PDF
Privacy is a UX problem (David Dahl)
Future Insights
 
PDF
Java script and web cryptography (cf.objective)
ColdFusionConference
 
PDF
Designing Secure APIs
Steven Chen
 
PDF
Comptia Security+ Exam Notes
Vijayanand Yadla
 
PDF
Crypto Strikes Back! (Google 2009)
Nate Lawson
 
PDF
6 ways to hack your JavaScript application by Viktor Turskyi
OdessaJS Conf
 
PDF
API SECURITY
Tubagus Rizky Dharmawan
 
PPT
Securing RESTful API
Muhammad Zbeedat
 
PDF
Encryption Boot Camp at JavaZone 2010
Matthew McCullough
 
What Every Software Engineer Should Know About Security and Encryption
All Things Open
 
Django cryptography
Erik LaBianca
 
apidays LIVE Australia 2020 - WT* is JWT? by Maciej Treder
apidays
 
apidays LIVE New York - WT* is JWT? by Maciej Treder
apidays
 
apidays LIVE Paris - WT* is JWT? by Maciej Treder
apidays
 
apidays LIVE LONDON - WT* is JWT? by Maciej Treder
apidays
 
apidays LIVE Hong Kong - WT* is JWT? by Maciej Treder
apidays
 
Crypt-Oh No!
Zach Grace
 
Flaws of password-based authentication
sluge
 
UVic Startup Slam September 2014 (Kiind)
sendwithus
 
Privacy is a UX problem (David Dahl)
Future Insights
 
Java script and web cryptography (cf.objective)
ColdFusionConference
 
Designing Secure APIs
Steven Chen
 
Comptia Security+ Exam Notes
Vijayanand Yadla
 
Crypto Strikes Back! (Google 2009)
Nate Lawson
 
6 ways to hack your JavaScript application by Viktor Turskyi
OdessaJS Conf
 
Securing RESTful API
Muhammad Zbeedat
 
Encryption Boot Camp at JavaZone 2010
Matthew McCullough
 
Ad

More from FestGroup (10)

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

Recently uploaded (20)

PPTX
Latest Features in Odoo 18 - Odoo slides
Celine George
 
PPTX
How to Configure Lost Reasons in Odoo 18 CRM
Celine George
 
PPTX
How to Configure Storno Accounting in Odoo 18 Accounting
Celine George
 
PPTX
ASRB NET 2023 PREVIOUS YEAR QUESTION PAPER GENETICS AND PLANT BREEDING BY SAT...
Krashi Coaching
 
PPTX
Views on Education of Indian Thinkers J.Krishnamurthy..pptx
ShrutiMahanta1
 
PPTX
Capitol Doctoral Presentation -July 2025.pptx
CapitolTechU
 
PPTX
How to Define Translation to Custom Module And Add a new language in Odoo 18
Celine George
 
PDF
CONCURSO DE POESIA “POETUFAS – PASSOS SUAVES PELO VERSO.pdf
Colégio Santa Teresinha
 
PPTX
Growth and development and milestones, factors
BHUVANESHWARI BADIGER
 
PDF
Federal dollars withheld by district, charter, grant recipient
Mebane Rash
 
PDF
IMP NAAC REFORMS 2024 - 10 Attributes.pdf
BHARTIWADEKAR
 
PPTX
PPT on the Development of Education in the Victorian England
Beena E S
 
PPTX
ROLE OF ANTIOXIDANT IN EYE HEALTH MANAGEMENT.pptx
Subham Panja
 
PPTX
HEAD INJURY IN CHILDREN: NURSING MANAGEMENGT.pptx
PRADEEP ABOTHU
 
PPSX
Health Planning in india - Unit 03 - CHN 2 - GNM 3RD YEAR.ppsx
Priyanshu Anand
 
PPTX
LEGAL ASPECTS OF PSYCHIATRUC NURSING.pptx
PoojaSen20
 
PDF
CEREBRAL PALSY: NURSING MANAGEMENT .pdf
PRADEEP ABOTHU
 
PPTX
Accounting Skills Paper-I, Preparation of Vouchers
Dr. Sushil Bansode
 
PDF
Zoology (Animal Physiology) practical Manual
raviralanaresh2
 
PPSX
HEALTH ASSESSMENT (Community Health Nursing) - GNM 1st Year
Priyanshu Anand
 
Latest Features in Odoo 18 - Odoo slides
Celine George
 
How to Configure Lost Reasons in Odoo 18 CRM
Celine George
 
How to Configure Storno Accounting in Odoo 18 Accounting
Celine George
 
ASRB NET 2023 PREVIOUS YEAR QUESTION PAPER GENETICS AND PLANT BREEDING BY SAT...
Krashi Coaching
 
Views on Education of Indian Thinkers J.Krishnamurthy..pptx
ShrutiMahanta1
 
Capitol Doctoral Presentation -July 2025.pptx
CapitolTechU
 
How to Define Translation to Custom Module And Add a new language in Odoo 18
Celine George
 
CONCURSO DE POESIA “POETUFAS – PASSOS SUAVES PELO VERSO.pdf
Colégio Santa Teresinha
 
Growth and development and milestones, factors
BHUVANESHWARI BADIGER
 
Federal dollars withheld by district, charter, grant recipient
Mebane Rash
 
IMP NAAC REFORMS 2024 - 10 Attributes.pdf
BHARTIWADEKAR
 
PPT on the Development of Education in the Victorian England
Beena E S
 
ROLE OF ANTIOXIDANT IN EYE HEALTH MANAGEMENT.pptx
Subham Panja
 
HEAD INJURY IN CHILDREN: NURSING MANAGEMENGT.pptx
PRADEEP ABOTHU
 
Health Planning in india - Unit 03 - CHN 2 - GNM 3RD YEAR.ppsx
Priyanshu Anand
 
LEGAL ASPECTS OF PSYCHIATRUC NURSING.pptx
PoojaSen20
 
CEREBRAL PALSY: NURSING MANAGEMENT .pdf
PRADEEP ABOTHU
 
Accounting Skills Paper-I, Preparation of Vouchers
Dr. Sushil Bansode
 
Zoology (Animal Physiology) practical Manual
raviralanaresh2
 
HEALTH ASSESSMENT (Community Health Nursing) - GNM 1st Year
Priyanshu Anand
 

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 protected]'
  • 39. Let’s do that again… curl 'http://webgoat-cloud.net/create-password-reset-link' -H'Host: attacker.com' --data-raw '[email protected]'
  • 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