pwned
3 TopicsPwned Passwords Check
Problem this snippet solves: This snippet makes it possible to use Troy Hunt’s ‘Pwned Passwords’ API. By using this API one can check if the password being used was exposed in earlier data breaches. You can use this information to deny access to highly secure resources or to force a user to first change it’s password to one that isn’t known to be exposed to earlier data breaches. Or you could choose to just to inform a user that it would be wise to change it’s password. It’s good to note that the password itself will not be shared while using this API. This snippet uses a mathematical property called k-anonymity. For more information about k-anonymity and Troy Hunt’s ‘Pwned Passwords’ API see: https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/ This snippet also uses Patt-tom McDonnell’s hibp-checker node package. How to use this snippet: Prepare the BIG-IP Provision the BIG-IP with iRuleLX. Create LX Workspace: hibp Add iRule: hibp-irule Add Extension: hibp-extension Add LX Plugin: hibp-plugin -> From Workspace: hibp Install the node.js hibp-checker module # cd /var/ilx/workspaces/Common/hibp/extensions/hibp-extension/ # npm install hibp-checker --save /var/ilx/workspaces/Common/hibp/extensions/hibp-extension └── hibp-checker@1.0.0 # irule To make it works, you need to install the irule on the Virtual Server that publish your application with APM authentication. access profile If you already have an existing access profile, you will need to modify it and include some additionnal configuration in your VPE. If you have no access profile, you can starts building your own based on the description we provide below. Configuring the Visual Policy Editor The printscreen below is an example Visual Policy Editor on how you can use the Pnwed Password snippet. VA – Force Password Change This is a Variable Assignment agent that triggers APM to show a Change Password window. Set variable: session.logon.last.change_password to Custom Expression: expr { 1 } VA – Get Password This is a Variable Assignment agent that copies the password to a session variable that can be read by the hibp irule. Set variable: session.custom.hibp.password to Custom Expression: return [mcget -secure {session.logon.last.password}] IE - HIBP This is an irule event with the ID set to ‘hibp’. This will trigger the hibp_irule to come into action. EA – HIBP Verdict This is an Empty Action with two branches. The branch named "Not Pwned" contains the following expression : expr { [mcget -nocache {session.custom.hibp.status} ] == 0 } MB – Exposed Password This is a message box that will inform the user that it’s password was exposed in earlier data breaches and a password change is needed. The message could be something like this: The password you are using was found in %{session.custom.hibp.status} data breaches. In order to be compliant with our security policy, you must change your password. hibp_irule when ACCESS_POLICY_AGENT_EVENT { if { [ACCESS::policy agent_id ] eq "hibp" } { set password [ACCESS::session data get session.custom.hibp.password] set failonerror 0 if { $password eq "" } { log local0. "Error: no password set" ACCESS::session data set session.custom.hibp.status $failonerror return } set rpc_handle [ ILX::init hibp-plugin hibp-extension ] if {[ catch { ILX::call $rpc_handle -timeout 12000 hibpCheck $password } result ] } { log local0. "hibpCheck failed. ILX failure: $result" ACCESS::session data set session.custom.hibp.status $failonerror return } ACCESS::session data set session.custom.hibp.status [expr { $result }] } } Code : var f5 = require('f5-nodejs'); const checkPassword = require('hibp-checker'); // Create a new rpc server for listening to TCL iRule calls. var ilx = new f5.ILXServer(); ilx.addMethod('hibpCheck', function(req, res) { var password = req.params()[0]; var breachCount = checkPassword(password); breachCount.then(function(result) { return res.reply(result); }, function(err) { return res.reply(err); }); }); // Start listening for ILX::call and ILX::notify events. ilx.listen(); Tested this on version: 13.01.7KViews3likes15CommentsAdd Pwned Passwords HTTP Headers
Problem this snippet solves: This is an example snippet which uses Troy Hunt’s ‘Pwned Passwords’ API that can be used to intercept a request passing the BIG-IP. It looks at POST requests and extracts a field called password and checks it against Troy Hunt’s service. It then adds an HTTP request header F5-Password-Pwned , with either the value Yes or No depending on whether the password being handled is found in the database or not. It also adds an additional HTTP header F5-Password-Pwned-Score . This header will hold an integer that represents the number of different date breaches in which this password was found. The POST request is then passed on to the origin server for handling, with the extra headers inserted. This could, for example, be used on a signup page to check whether the password a user is hoping to use has already been found in a leak. The server would simply look at the header. It’s good to note that the password itself will not be shared while using this API. This snippet uses a mathematical property called k-anonymity. For more information about k-anonymity and Troy Hunt’s ‘Pwned Passwords’ API see: https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/ This idea for making this example snippet was inspired by this blog article by John Graham-Cumming: https://blog.cloudflare.com/using-cloudflare-workers-to-identify-pwned-passwords/ This snippet also uses Patt-tom McDonnell’s hibp-checker node package. Examples In the example below you see that the 'topsecret' password has been found in the database. $ curl -X POST -d 'password=topsecret' http://10.23.98.35/headers.php HTTP headers received: User-Agent: curl/7.40.0 Host: 10.23.98.35 Accept: */* Content-Length: 18 Content-Type: application/x-www-form-urlencoded X-Forwarded-For: 10.23.92.2 F5-Password-Pwned: Yes F5-Password-Pwned-Score: 15279 $ The next example shows a more secure password that isn't in the database. $ curl -X POST -d 'password=llo5lFvXCEc4ZYruQmmt' http://10.23.98.35/headers.php HTTP headers received: User-Agent: curl/7.40.0 Host: 10.23.98.35 Accept: */* Content-Length: 29 Content-Type: application/x-www-form-urlencoded X-Forwarded-For: 10.23.92.2 F5-Password-Pwned: No F5-Password-Pwned-Score: 0 $ How to use this snippet: Prepare the BIG-IP Provision the BIG-IP with iRuleLX. Create LX Workspace: Local Traffic > LX Workspaces Name: workspace_hibp-headers Add Extension: extension_hibp-headers Create LX Plugin: Local Traffic > iRules > LX Plugins Name: plugin_hibp-headers From Workspace: workspace_hibp-headers Create iRules LX Profile: Local Traffic > Profiles > Other > iRules LX Name: ilx_hibp-headers Plugin: plugin_hibp-headers Install the node.js hibp-checker, querystring and utf8 module # cd /var/ilx/workspaces/Common/workspace_hibp-headers/extensions/extension_hibp-headers/ # npm install hibp-checker querystring utf8 --save /var/ilx/workspaces/Common/workspace_hibp-headers/extensions/extension_hibp-headers/ ├── hibp-checker@1.0.0 ├── querystring@0.2.0 └── utf8@3.0.0 # Add iRules LX Profile to Virtual Server Select Virtual Server: Local Traffic > Virtual Servers > some_vs Select Advanced Configuration. Select ilx_http-headers as iRule LX Profile. Code : var f5 = require('f5-nodejs'); var plugin = new f5.ILXPlugin(); var qs = require('querystring'); var utf8 = require('utf8'); var hibpChecker = require('hibp-checker'); plugin.on("connect", function(flow) { var hibpEngineEnable = 0; var body = ''; flow.client.on("requestStart", function(request) { if ((request.params.method == "POST") && (request.params.headers['content-length'] > 0) && (request.params.headers['content-length'] <= 1048576)) { hibpEngineEnable = 1; } }); flow.client.on("readable", function() { while (true) { var buffer = flow.client.read(); if (buffer !== null) { if (hibpEngineEnable == 1) { body += buffer; } else { flow.server.write(buffer); } } else { break; } } }); flow.client.on("requestComplete", function(request) { if ( hibpEngineEnable == 1 ) { var post = qs.parse(body); if( post.password ) { const password = utf8.encode(post.password); var breachCount = hibpChecker(password); breachCount.then(function(result) { if(result > 0) { request.setHeader('F5-Password-Pwned', 'Yes'); } else { request.setHeader('F5-Password-Pwned', 'No'); } request.setHeader('F5-Password-Pwned-Score', result); flow.server.write(body); request.complete(); }, function(err) { console.log('ERROR: ' + err); flow.server.write(body); request.complete(); }); } } else { request.complete(); } }); // Register callbacks for error events. Errors events must be caught. flow.client.on("error", function(errorText) { console.log("client error event: " + errorText); }); flow.server.on("error", function(errorText) { console.log("server error event: " + errorText); }); flow.on("error", function(errorText) { console.log("flow error event: " + errorText); }); }); // Start listening for new flows. var options = new f5.ILXPluginOptions(); options.handleServerData = false; options.handleServerResponse = false; plugin.start(options); Tested this on version: 13.0279Views1like0CommentsThe DevCentral Chronicles Volume 1, Issue 4
If you missed our initial issues of the DC Chronicles, you can catch up with the links at the bottom. The Chronicles are intended to keep you updated on DevCentral happenings and highlight some of the cool content you may have missed since the last issue. Welcome! Like last month, we’re digging the OWASP Top 10 #Lightboard series from @JohnWagnon. He wrapped it up this month with numbers 9 & 10 - Using Components With Known Vulnerabilities and Insufficient Logging and Monitoring. To give you a sense of how these have been received, YouTube viewer Sanket Kamath says, ‘Thank you for the excellent overview for all of the OWASP Top 10 2017! John made it really easy to understand each of the 10 attacks with his explanation!’ Check out the entire playlist! Speaking of LightBoard Lessons, we had a few fantastic ones this past month. John took on lighting up the GitHub DDoS Attack and Explaining the Spectre and Meltdown Vulnerabilities while Jason gave us the OSI and TCP/IP Models and What Are Containers? I added SAML IdP and SP on One BIG-IP to round out our videos. On the Security front, we had a bunch of great articles covering a mess, and I mean a mess of stuff. The mess was some new vulnerabilities and our Security Researchers had the mitigations for many including Spring Framework Spring-Messaging Remote Code Execution (CVE-2018-1270), Drupal Core SA-CORE-2018-002 Remote Code Execution Vulnerability and Jackson-Databind - A Story of Blacklisting Java Deserialization Gadgets. We also learned how to Protect your AWS API Gateway with F5 BIG-IP WAF, how to configure F5 BIG-IP as an Explicit Forward Web Proxy Using Secure Web Gateway (SWG) and how to set up ADFS Proxy Replacement on F5 BIG-IP. The Cloud folks will love Lori’s Three Types of Load Balancing You Meet in the Cloud, DNS Admins will dig Eric’s Unbreaking the Internet and Converting Protocols and Coders will enjoy Jason’s Debugging API calls with the python sdk and Satoshi’s iControl REST Fine-Grained Role Based Access Control. And, we couldn’t let this Chronicle pass without mentioning an awesome @haveibeenpwned #Pwned Passwords Check #CodeShare from MVP Niels van Sluis. This snippet makes it possible to use @troyhunt ‘Pwned Passwords’ API to check if the password has been exposed. See it here: http://bit.ly/2GOhi1y And wrapping up, a wonderful contributor Daniel Varela is DevCentral's Featured Member for April and F5 Agility is coming to Boston, MA this August! As always, You can stay engaged with @DevCentral by following us on Twitter, joining our LinkedIn Group or subscribing to our YouTube Channel. Look forward to hearing about your BIG-IP adventures. ps Previous Volume 1, Issue 1 Volume 1, Issue 2 Volume 1, Issue 3380Views0likes0Comments