0
0
Testing Fundamentalstesting~15 mins

OWASP Top 10 awareness in Testing Fundamentals - Build an Automation Script

Choose your learning style9 modes available
Verify OWASP Top 10 security risks are checked in web application
Preconditions (3)
Step 1: Open the web application login page
Step 2: Attempt to enter a SQL injection payload in the username field
Step 3: Verify the application does not execute the injection and shows an error or sanitizes input
Step 4: Attempt to enter a script tag in the comment or input fields to test for Cross-Site Scripting (XSS)
Step 5: Verify the script is not executed and input is sanitized or escaped
Step 6: Check if the application uses HTTPS by verifying the URL scheme
Step 7: Attempt to access a restricted page without logging in
Step 8: Verify the application redirects to login or shows an access denied message
Step 9: Check for security headers in the HTTP response (e.g., Content-Security-Policy, X-Frame-Options)
Step 10: Verify that sensitive data like passwords are not visible in URLs or error messages
✅ Expected Result: The application properly handles all OWASP Top 10 security risks tested: input is sanitized, unauthorized access is blocked, secure protocols and headers are used, and sensitive data is protected.
Automation Requirements - Selenium with Python
Assertions Needed:
Verify no SQL injection is successful
Verify no XSS script executes
Verify HTTPS is used
Verify unauthorized access is blocked
Verify security headers are present
Verify sensitive data is not exposed
Best Practices:
Use explicit waits for page elements
Use Page Object Model to organize selectors
Use assertions that clearly state expected vs actual
Avoid hardcoded waits or brittle locators
Log test steps and results for traceability
Automated Solution
Testing Fundamentals
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
import requests

class TestOWASPTop10(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.wait = WebDriverWait(self.driver, 10)
        self.base_url = "https://example.com"  # Replace with actual URL

    def test_sql_injection(self):
        self.driver.get(f"{self.base_url}/login")
        username = self.wait.until(EC.presence_of_element_located((By.ID, "username")))
        password = self.driver.find_element(By.ID, "password")
        login_button = self.driver.find_element(By.ID, "loginBtn")

        # Attempt SQL injection payload
        username.clear()
        username.send_keys("' OR '1'='1")
        password.clear()
        password.send_keys("password")
        login_button.click()

        # Verify login failed or input sanitized
        error_msg = self.wait.until(EC.presence_of_element_located((By.ID, "errorMessage")))
        self.assertIn("Invalid", error_msg.text, "SQL Injection should not succeed")

    def test_xss(self):
        self.driver.get(f"{self.base_url}/comment")
        comment_box = self.wait.until(EC.presence_of_element_located((By.ID, "commentBox")))
        submit_btn = self.driver.find_element(By.ID, "submitComment")

        # Attempt XSS payload
        xss_payload = "<script>alert('XSS')</script>"
        comment_box.clear()
        comment_box.send_keys(xss_payload)
        submit_btn.click()

        # Verify alert does not appear and input is sanitized
        page_source = self.driver.page_source
        self.assertNotIn(xss_payload, page_source, "XSS payload should be sanitized")

    def test_https_used(self):
        self.driver.get(self.base_url)
        current_url = self.driver.current_url
        self.assertTrue(current_url.startswith("https://"), "Site should use HTTPS")

    def test_unauthorized_access(self):
        self.driver.get(f"{self.base_url}/admin")
        # Should redirect to login or show access denied
        self.assertTrue(
            "login" in self.driver.current_url or
            "access denied" in self.driver.page_source.lower(),
            "Unauthorized access should be blocked"
        )

    def test_security_headers(self):
        response = requests.get(self.base_url)
        headers = response.headers
        self.assertIn("Content-Security-Policy", headers, "CSP header should be present")
        self.assertIn("X-Frame-Options", headers, "X-Frame-Options header should be present")

    def test_sensitive_data_not_exposed(self):
        self.driver.get(f"{self.base_url}/error")
        page_source = self.driver.page_source.lower()
        self.assertNotIn("password", page_source, "Passwords should not be visible in error messages")

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()

This test script uses Selenium with Python's unittest framework to automate checks for OWASP Top 10 security risks.

setUp: Initializes the browser and sets the base URL.

test_sql_injection: Tries a common SQL injection string in the login username field and asserts that login fails with an error message.

test_xss: Inputs a script tag in a comment box and verifies the script does not appear in the page source, meaning it is sanitized.

test_https_used: Checks that the site URL starts with https:// to ensure secure communication.

test_unauthorized_access: Attempts to access a restricted admin page without login and verifies redirection or access denial.

test_security_headers: Uses requests library to check HTTP response headers for security headers like Content-Security-Policy and X-Frame-Options.

test_sensitive_data_not_exposed: Checks error pages do not show sensitive data like passwords.

tearDown: Closes the browser after tests.

Explicit waits ensure elements are loaded before interaction. Assertions clearly check expected security behavior. This structure follows best practices for maintainable and reliable tests.

Common Mistakes - 5 Pitfalls
Using hardcoded sleeps instead of explicit waits
Using brittle XPath selectors that break easily
Not verifying the actual security headers in HTTP responses
Not cleaning up or closing the browser after tests
Testing only positive scenarios and ignoring security attack vectors
Bonus Challenge

Now add data-driven testing with 3 different SQL injection payloads and 3 different XSS payloads to verify robustness.

Show Hint