diff --git a/webgoat-lessons/pom.xml b/webgoat-lessons/pom.xml
index 9513eab7c..f652b9a1e 100644
--- a/webgoat-lessons/pom.xml
+++ b/webgoat-lessons/pom.xml
@@ -86,6 +86,11 @@
encoder
1.2
+
+ com.nulab-inc
+ zxcvbn
+ 1.2.5
+
com.thoughtworks.xstream
diff --git a/webgoat-lessons/secure-passwords/src/main/java/org/owasp/webgoat/plugin/SecurePasswordsAssignment.java b/webgoat-lessons/secure-passwords/src/main/java/org/owasp/webgoat/plugin/SecurePasswordsAssignment.java
new file mode 100644
index 000000000..071befc49
--- /dev/null
+++ b/webgoat-lessons/secure-passwords/src/main/java/org/owasp/webgoat/plugin/SecurePasswordsAssignment.java
@@ -0,0 +1,65 @@
+package org.owasp.webgoat.plugin;
+
+
+import com.nulabinc.zxcvbn.Strength;
+import com.nulabinc.zxcvbn.Zxcvbn;
+import org.jruby.RubyProcess;
+import org.owasp.webgoat.assignments.AssignmentEndpoint;
+import org.owasp.webgoat.assignments.AssignmentHints;
+import org.owasp.webgoat.assignments.AssignmentPath;
+import org.owasp.webgoat.assignments.AttackResult;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+
+import javax.tools.*;
+import java.io.IOException;
+import java.net.URI;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@AssignmentPath("SecurePasswords/assignment")
+//@AssignmentHints(value = {"xss-mitigation-3-hint1", "xss-mitigation-3-hint2", "xss-mitigation-3-hint3", "xss-mitigation-3-hint4"})
+public class SecurePasswordsAssignment extends AssignmentEndpoint {
+
+ @RequestMapping(method = RequestMethod.POST)
+ @ResponseBody
+ public AttackResult completed(@RequestParam String password) {
+ Zxcvbn zxcvbn = new Zxcvbn();
+ Strength strength = zxcvbn.measure(password);
+ StringBuffer output = new StringBuffer();
+ DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
+ df.setMaximumFractionDigits(340);
+
+ output.append("Your Password: " + password + "");
+ output.append("Length: " + password.length()+ "");
+ output.append("Estimated guesses needed to crack your password: " + df.format(strength.getGuesses())+ "");
+ output.append("Score: " + strength.getScore()+ "/5 ");
+ output.append("Estimated cracking time in seconds: " + calculateTime((long) strength.getCrackTimeSeconds().getOnlineNoThrottling10perSecond()));
+
+ if(strength.getScore() >= 4)
+ return trackProgress(success().feedback("securepassword-success").output(output.toString()).build());
+ else
+ return trackProgress(failed().feedback("securepassword-failed").output(output.toString()).build());
+ }
+
+ public static String calculateTime(long seconds) {
+ int day = (int) TimeUnit.SECONDS.toDays(seconds);
+ int year = day/365;
+ day = day % 365;
+ long hours = TimeUnit.SECONDS.toHours(seconds) - (day *24);
+ long minute = TimeUnit.SECONDS.toMinutes(seconds) - (TimeUnit.SECONDS.toHours(seconds)* 60);
+ long second = TimeUnit.SECONDS.toSeconds(seconds) - (TimeUnit.SECONDS.toMinutes(seconds) *60);
+
+ return (year + " years " + day + " days " + hours + " hours " + minute + " minutes " + second + " seconds");
+
+ }
+}
\ No newline at end of file
diff --git a/webgoat-lessons/secure-passwords/src/main/resources/html/SecurePasswords.html b/webgoat-lessons/secure-passwords/src/main/resources/html/SecurePasswords.html
index f64694f41..a965e00dc 100644
--- a/webgoat-lessons/secure-passwords/src/main/resources/html/SecurePasswords.html
+++ b/webgoat-lessons/secure-passwords/src/main/resources/html/SecurePasswords.html
@@ -14,6 +14,30 @@
+
+
diff --git a/webgoat-lessons/secure-passwords/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/secure-passwords/src/main/resources/i18n/WebGoatLabels.properties
index 72e901870..2e2877bc2 100644
--- a/webgoat-lessons/secure-passwords/src/main/resources/i18n/WebGoatLabels.properties
+++ b/webgoat-lessons/secure-passwords/src/main/resources/i18n/WebGoatLabels.properties
@@ -1 +1,3 @@
-secure-passwords.title=Secure Passwords
\ No newline at end of file
+secure-passwords.title=Secure Passwords
+securepassword-success=You have succeded! The password is secure enough.
+securepassword-failed=You have failed! Try to enter a secure password.
\ No newline at end of file
diff --git a/webgoat-lessons/secure-passwords/src/main/resources/lessonPlans/en/SecurePasswords_assignment_introduction.adoc b/webgoat-lessons/secure-passwords/src/main/resources/lessonPlans/en/SecurePasswords_assignment_introduction.adoc
new file mode 100644
index 000000000..5ffcc154f
--- /dev/null
+++ b/webgoat-lessons/secure-passwords/src/main/resources/lessonPlans/en/SecurePasswords_assignment_introduction.adoc
@@ -0,0 +1,3 @@
+== How long could it take to brute force your password?
+
+In this assignment you have to type in a password which is strong enough (at least 4/5 or 5/5).
\ No newline at end of file