Test login form for authentication vulnerabilities
Preconditions (2)
✅ Expected Result: The login form should reject invalid credentials, empty passwords, SQL injection attempts, and overly long inputs without granting access or crashing.
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import unittest class TestAuthenticationVulnerabilities(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.get('https://example.com/login') self.wait = WebDriverWait(self.driver, 10) def tearDown(self): self.driver.quit() def login(self, username, password): username_field = self.wait.until(EC.presence_of_element_located((By.ID, 'username'))) password_field = self.driver.find_element(By.ID, 'password') login_button = self.driver.find_element(By.ID, 'loginBtn') username_field.clear() username_field.send_keys(username) password_field.clear() password_field.send_keys(password) login_button.click() def test_invalid_password(self): self.login('validUser', 'wrongPass') error = self.wait.until(EC.visibility_of_element_located((By.ID, 'errorMsg'))) self.assertIn('Invalid credentials', error.text) def test_empty_password(self): self.login('validUser', '') error = self.wait.until(EC.visibility_of_element_located((By.ID, 'errorMsg'))) self.assertIn('Password cannot be empty', error.text) def test_sql_injection(self): self.login('validUser', "' OR '1'='1") error = self.wait.until(EC.visibility_of_element_located((By.ID, 'errorMsg'))) self.assertIn('Invalid credentials', error.text) # Also verify URL did not change to dashboard self.assertNotIn('/dashboard', self.driver.current_url) def test_long_password(self): long_password = 'a' * 1000 self.login('validUser', long_password) error = self.wait.until(EC.visibility_of_element_located((By.ID, 'errorMsg'))) self.assertTrue(error.is_displayed()) # Verify page is still responsive self.assertIn('/login', self.driver.current_url) if __name__ == '__main__': unittest.main()
The setUp method opens the browser and navigates to the login page before each test.
The login helper method fills the username and password fields and clicks the login button, making tests cleaner.
Each test method covers one vulnerability scenario: invalid password, empty password, SQL injection, and long input.
Explicit waits ensure elements are ready before interacting or asserting.
Assertions check that error messages appear and no unauthorized access occurs.
The tearDown method closes the browser after each test to keep tests isolated.
Now add data-driven testing with 3 different invalid username and password combinations
authentication vulnerability testing?attempts = 0
while attempts < 5:
login('user', 'wrongpass')
attempts += 1
result = login('user', 'correctpass')result be if the system locks the account after 5 failed attempts?login('user', 'correctpass')
// skip MFA step
access = check_access()Pass the test and this pattern moves unknown