Created
March 30, 2017 23:32
-
-
Save adr0sen/a7cb448f6f9639a7bce31ec23b89bf0f to your computer and use it in GitHub Desktop.
Load Impact Lua script sample: Advanced login w dynamic data extraction/correlation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- For more details, see http://support.loadimpact.com/knowledgebase/articles/389413-advanced-login-w-dynamic-data-extraction-correlati | |
-- | |
-- Dynamic data correlation/extraction example user scenario | |
-- | |
-- This user scenario code demonstrates how to look for certain data in an HTTP response | |
-- using regular expression matching. The extracted data can then be used in future requests, | |
-- typically to simulate CSRF (cross-site request forgery) tokens, session keys or similar | |
-- dynamic data the server wants included in requests for security or other reasons. | |
-- | |
-- In this particular example, we load the Load Impact main HTML page, where there is | |
-- a cross-site request forgery token that we need to extract and include in later requests | |
-- in order to be able to do many things on the Load Impact site. We then issue a login request | |
-- without and then with the token, to demonstrate how the login works when the token | |
-- is present, but not when it isn't. | |
-- Step 1: First we issue an HTTP request to get some HTML content with the token in it | |
-- | |
-- Note the use of 'response_body_bytes' to make sure we save the body content | |
-- | |
log.info('Step 1: Executing GET http://loadimpact.com/') | |
local response = http.get({ url="http://loadimpact.com/", response_body_bytes=1000000 }) | |
-- Step 2: Using the regex module to find the data we're interested in | |
-- | |
-- Within the HTML, we want to find a CSRF token that looks like this: | |
-- CSRF_TOKEN='a14f956c63e19d35c2272d5d1e1a15cff1ba1f01' | |
-- To find it, we perform a regular expression search in the HTML, looking for "CSRF_TOKEN='x'" | |
-- where "x" is allowed to be any number of a-z characters or the numbers 0-9 | |
-- | |
local m = regex.match("CSRF_TOKEN='([a-z,0-9]+)'", response.body) | |
-- Print out some debug information | |
-- | |
log.info('Step 2: Full string matched by regex: ' .. m:capture(1)) | |
log.info('Step 2: CSRF token was: ' .. m:capture(2)) | |
-- Step 3: Store the extracted string in a local variable for later use | |
-- | |
local csrf_token = m:capture(2) | |
-- Step 4-5: build and send a login request. | |
-- | |
-- We login as user "[email protected]" with password "test" | |
-- | |
local login_url = 'https://loadimpact.com/account/signin' | |
local username = '[email protected]' | |
local password = 'test1234' | |
-- Step 4: First we build a request that does NOT include the CSRF token, to see what happens | |
-- | |
local post_data = 'email=' .. url.escape(username) .. '&password=' .. url.escape(password) | |
-- Then we send it | |
local response = http.post({ | |
url=login_url, | |
data=post_data, | |
response_body_bytes = 1000000 | |
}) | |
-- Print out some debug info | |
-- | |
log.info('Step 4: First POST returned status code ' .. tostring(response.status_code)) | |
log.info('Step 4: Content-length is ' .. tostring(response.body_size)) | |
-- When logged in at loadimpact.com, you get a "Sign out" link at the top of the page | |
-- This means we can verify if the login operation worked, by seeing if the returned | |
-- HTML contains the string "Sign out" or not | |
-- | |
if string.find(response.body, 'Sign out') == nil then | |
log.info('Step 4: Login failed on our first attempt') | |
else | |
log.info('Step 4: Login succeeded on our first attempt') | |
end | |
-- Step 5: Then we build a request that includes the CSRF token | |
-- | |
local post_data = 'email=' .. url.escape(username) .. '&password=' .. url.escape(password) .. | |
'&csrf=' .. csrf_token | |
-- Then we send it | |
local response = http.post({ | |
url=login_url, | |
data=post_data, | |
response_body_bytes = 1000000 | |
}) | |
-- Print out some debug info | |
-- | |
log.info('Step 5: Second POST returned status code ' .. tostring(response.status_code)) | |
log.info('Step 5: Content-length is ' .. tostring(response.body_size)) | |
-- And check if we are logged on or not | |
-- | |
if string.find(response.body, 'Sign out') == nil then | |
log.info('Step 5: Login failed on our second attempt') | |
else | |
log.info('Step 5: Login succeeded on our second attempt') | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment