

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456 # Python Identification and Authentication Failures Standards (OWASP A07:2021)78This rule enforces security best practices to prevent identification and authentication failures in Python applications, as defined in OWASP Top 10:2021-A07.910<rule>11name: python_authentication_failures12description: Detect and prevent identification and authentication failures in Python applications as defined in OWASP Top 10:2021-A0713filters:14 - type: file_extension15 pattern: "\\.(py|ini|cfg|yml|yaml|json|toml)$"16 - type: file_path17 pattern: ".*"1819actions:20 - type: enforce21 conditions:22 # Pattern 1: Weak password validation23 - pattern: "password\\s*=\\s*['\"][^'\"]{1,7}['\"]|min_length\\s*=\\s*[1-7]"24 message: "Weak password policy detected. Passwords should be at least 8 characters long and include complexity requirements."2526 # Pattern 2: Hardcoded credentials27 - pattern: "(username|user|login|password|passwd|pwd|secret|api_key|apikey|token)\\s*=\\s*['\"][^'\"]+['\"]"28 message: "Hardcoded credentials detected. Store sensitive credentials in environment variables or a secure vault."2930 # Pattern 3: Missing password hashing31 - pattern: "password\\s*=\\s*request\\.form\\[\\'password\\'\\]|password\\s*=\\s*request\\.POST\\.get\\(\\'password\\'\\)"32 message: "Storing or comparing plain text passwords detected. Always hash passwords before storage or comparison."3334 # Pattern 4: Insecure password hashing35 - pattern: "hashlib\\.md5\\(|hashlib\\.sha1\\(|hashlib\\.sha224\\("36 message: "Insecure hashing algorithm detected. Use strong hashing algorithms like bcrypt, Argon2, or PBKDF2."3738 # Pattern 5: Missing brute force protection39 - pattern: "@app\\.route\\(['\"]\\/(login|signin|authenticate)['\"]"40 message: "Authentication endpoint detected without rate limiting or brute force protection. Implement account lockout or rate limiting."4142 # Pattern 6: Insecure session management43 - pattern: "session\\[\\'user_id\\'\\]\\s*=|session\\[\\'authenticated\\'\\]\\s*=\\s*True"44 message: "Session management detected. Ensure proper session security with secure cookies, proper expiration, and rotation."4546 # Pattern 7: Missing CSRF protection in authentication47 - pattern: "form\\s*=\\s*FlaskForm|class\\s+\\w+Form\\(\\s*FlaskForm\\s*\\)|class\\s+\\w+Form\\(\\s*Form\\s*\\)"48 message: "Form handling detected. Ensure CSRF protection is enabled for all authentication forms."4950 # Pattern 8: Insecure remember me functionality51 - pattern: "remember_me|remember_token|stay_logged_in"52 message: "Remember me functionality detected. Ensure secure implementation with proper expiration and refresh mechanisms."5354 # Pattern 9: Insecure password reset55 - pattern: "@app\\.route\\(['\"]\\/(reset-password|forgot-password|recover)['\"]"56 message: "Password reset functionality detected. Ensure secure implementation with time-limited tokens and proper user verification."5758 # Pattern 10: Missing multi-factor authentication59 - pattern: "def\\s+login|def\\s+authenticate|def\\s+signin"60 message: "Authentication function detected. Consider implementing multi-factor authentication for sensitive operations."6162 # Pattern 11: Insecure direct object reference in user management63 - pattern: "User\\.objects\\.get\\(id=|User\\.query\\.get\\(|get_user_by_id\\("64 message: "Direct user lookup detected. Ensure proper authorization checks before accessing user data."6566 # Pattern 12: Insecure JWT implementation67 - pattern: "jwt\\.encode\\(|jwt\\.decode\\("68 message: "JWT usage detected. Ensure proper signing, validation, expiration, and refresh mechanisms for JWTs."6970 # Pattern 13: Missing secure flag in cookies71 - pattern: "set_cookie\\([^,]+,[^,]+,[^,]*secure=False|set_cookie\\([^,]+,[^,]+(?!,\\s*secure=True)"72 message: "Cookie setting without secure flag detected. Set secure=True for all authentication cookies."7374 # Pattern 14: Missing HTTP-only flag in cookies75 - pattern: "set_cookie\\([^,]+,[^,]+,[^,]*httponly=False|set_cookie\\([^,]+,[^,]+(?!,\\s*httponly=True)"76 message: "Cookie setting without httponly flag detected. Set httponly=True for all authentication cookies."7778 # Pattern 15: Insecure default credentials79 - pattern: "DEFAULT_USERNAME|DEFAULT_PASSWORD|ADMIN_USERNAME|ADMIN_PASSWORD"80 message: "Default credential configuration detected. Remove default credentials from production code."8182 - type: suggest83 message: |84 **Python Authentication Security Best Practices:**8586 1. **Password Storage:**87 - Use strong hashing algorithms with salting88 - Implement proper work factors89 - Example with passlib:90```python91 from passlib.hash import argon29293 # Hash a password94 hashed_password = argon2.hash("user_password")9596 # Verify a password97 is_valid = argon2.verify("user_password", hashed_password)98```99 - Example with Django:100```python101 from django.contrib.auth.hashers import make_password, check_password102103 # Hash a password104 hashed_password = make_password("user_password")105106 # Verify a password107 is_valid = check_password("user_password", hashed_password)108```109110 2. **Password Policies:**111 - Enforce minimum length (at least 8 characters)112 - Require complexity (uppercase, lowercase, numbers, special characters)113 - Check against common passwords114 - Example with Django:115```python116 # settings.py117 AUTH_PASSWORD_VALIDATORS = [118 {119 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',120 'OPTIONS': {'min_length': 12}121 },122 {123 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',124 },125 {126 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',127 },128 {129 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',130 },131 ]132```133134 3. **Brute Force Protection:**135 - Implement account lockout after failed attempts136 - Use rate limiting for authentication endpoints137 - Example with Flask and Flask-Limiter:138```python139 from flask import Flask140 from flask_limiter import Limiter141 from flask_limiter.util import get_remote_address142143 app = Flask(__name__)144 limiter = Limiter(145 app,146 key_func=get_remote_address,147 default_limits=["200 per day", "50 per hour"]148 )149150 @app.route("/login", methods=["POST"])151 @limiter.limit("5 per minute")152 def login():153 # Login logic here154 pass155```156157 4. **Multi-Factor Authentication:**158 - Implement MFA for sensitive operations159 - Use time-based one-time passwords (TOTP)160 - Example with pyotp:161```python162 import pyotp163164 # Generate a secret key for the user165 secret = pyotp.random_base32()166167 # Create a TOTP object168 totp = pyotp.TOTP(secret)169170 # Verify a token171 is_valid = totp.verify(user_provided_token)172```173174 5. **Secure Session Management:**175 - Use secure, HTTP-only cookies176 - Implement proper session expiration177 - Rotate session IDs after login178 - Example with Flask:179```python180 from flask import Flask, session181182 app = Flask(__name__)183 app.config.update(184 SECRET_KEY='your-secret-key',185 SESSION_COOKIE_SECURE=True,186 SESSION_COOKIE_HTTPONLY=True,187 SESSION_COOKIE_SAMESITE='Lax',188 PERMANENT_SESSION_LIFETIME=timedelta(hours=1)189 )190```191192 6. **CSRF Protection:**193 - Implement CSRF tokens for all forms194 - Validate tokens on form submission195 - Example with Flask-WTF:196```python197 from flask_wtf import FlaskForm, CSRFProtect198 from wtforms import StringField, PasswordField, SubmitField199200 csrf = CSRFProtect(app)201202 class LoginForm(FlaskForm):203 username = StringField('Username')204 password = PasswordField('Password')205 submit = SubmitField('Login')206```207208 7. **Secure Password Reset:**209 - Use time-limited, single-use tokens210 - Send reset links to verified email addresses211 - Example implementation:212```python213 import secrets214 from datetime import datetime, timedelta215216 def generate_reset_token(user_id):217 token = secrets.token_urlsafe(32)218 expiry = datetime.utcnow() + timedelta(hours=1)219 # Store token and expiry in database with user_id220 return token221222 def verify_reset_token(token):223 # Retrieve token from database224 # Check if token exists and is not expired225 # If valid, return user_id226 pass227```228229 8. **Secure JWT Implementation:**230 - Use strong signing keys231 - Include expiration claims232 - Validate all claims233 - Example with PyJWT:234```python235 import jwt236 from datetime import datetime, timedelta237238 # Create a JWT239 payload = {240 'user_id': user.id,241 'exp': datetime.utcnow() + timedelta(hours=1),242 'iat': datetime.utcnow()243 }244 token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')245246 # Verify a JWT247 try:248 payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])249 user_id = payload['user_id']250 except jwt.ExpiredSignatureError:251 # Token has expired252 pass253 except jwt.InvalidTokenError:254 # Invalid token255 pass256```257258 9. **Secure Cookie Configuration:**259 - Set secure, HTTP-only, and SameSite flags260 - Example with Flask:261```python262 from flask import Flask, make_response263264 app = Flask(__name__)265266 @app.route('/set_cookie')267 def set_cookie():268 resp = make_response('Cookie set')269 resp.set_cookie(270 'session_id',271 'value',272 secure=True,273 httponly=True,274 samesite='Lax',275 max_age=3600276 )277 return resp278```279280 10. **Credential Storage:**281 - Use environment variables or secure vaults282 - Never hardcode credentials283 - Example with python-dotenv:284```python285 import os286 from dotenv import load_dotenv287288 load_dotenv()289290 # Access credentials from environment variables291 db_user = os.environ.get('DB_USER')292 db_password = os.environ.get('DB_PASSWORD')293```294295 - type: validate296 conditions:297 # Check 1: Proper password hashing298 - pattern: "argon2|bcrypt|pbkdf2|make_password|generate_password_hash"299 message: "Using secure password hashing algorithms."300301 # Check 2: CSRF protection302 - pattern: "csrf|CSRFProtect|csrf_token|csrftoken"303 message: "CSRF protection is implemented."304305 # Check 3: Secure cookie settings306 - pattern: "SESSION_COOKIE_SECURE\\s*=\\s*True|secure=True|httponly=True|samesite"307 message: "Secure cookie settings are configured."308309 # Check 4: Rate limiting310 - pattern: "limiter\\.limit|RateLimitExceeded|rate_limit|throttle"311 message: "Rate limiting is implemented for authentication endpoints."312313metadata:314 priority: high315 version: 1.0316 tags:317 - security318 - python319 - authentication320 - identity321 - owasp322 - language:python323 - framework:django324 - framework:flask325 - framework:fastapi326 - category:security327 - subcategory:authentication328 - standard:owasp-top10329 - risk:a07-identification-authentication-failures330 references:331 - "https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/"332 - "https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html"333 - "https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html"334 - "https://cheatsheetseries.owasp.org/cheatsheets/Credential_Stuffing_Prevention_Cheat_Sheet.html"335 - "https://docs.djangoproject.com/en/stable/topics/auth/passwords/"336 - "https://flask-login.readthedocs.io/en/latest/"337 - "https://fastapi.tiangolo.com/tutorial/security/"338</rule>
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| ivangrynenko/cursorrules.cursor/rules/cursor-rules.mdc · 86 | Cursor rules | teststylearchgit+2 | 77/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/behat-steps.mdc · 86 | Cursor rules | lint-formatstyleperformanceagent-behaviour | 42/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/php-drupal-development-standards.mdc · 86 | Cursor rules | no sections | 34/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/python-insecure-design.mdc · 86 | Cursor rules | no sections | 40/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/python-cryptographic-failures.mdc · 86 | Cursor rules | security | 40/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/python-injection.mdc · 86 | Cursor rules | styledo-not | 51/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/node-dependencies.mdc · 86 | Cursor rules | no sections | 16/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/behat-ai-guide.mdc · 86 | Cursor rules | testtesting-strategydo-not | 45/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/new-pull-request.mdc · 86 | Cursor rules | archtesting-strategygitsecurity+3 | 58/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/accessibility-standards.mdc · 86 | Cursor rules | ui | 44/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/api-standards.mdc · 86 | Cursor rules | api | 44/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/build-optimization.mdc · 86 | Cursor rules | build | 48/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/code-generation-standards.mdc · 86 | Cursor rules | lint-formatstyletypesdocs | 52/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/confluence-editing-standards.mdc · 86 | Cursor rules | stylearchsecuritydeployment | 60/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/debugging-standards.mdc · 86 | Cursor rules | no sections | 30/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/docker-compose-standards.mdc · 86 | Cursor rules | style | 62/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-authentication-failures.mdc · 86 | Cursor rules | security | 48/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-broken-access-control.mdc · 86 | Cursor rules | stylesecurity | 52/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-cryptographic-failures.mdc · 86 | Cursor rules | security | 48/100 | 14 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-database-standards.mdc · 86 | Cursor rules | database | 30/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 14 days ago | |
| skillrecordings/egghead-next.cursor/rules/gh-task-plan.mdc · 1.4k | Cursor rules | teststylearchtypes+2 | 96/100 | 14 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 14 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-user-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 14 days ago | |
| hiromaily/go-crypto-wallet.cursor/rules/proto.mdc · 126 | Cursor rules | buildlint-formatstylearch+3 | 96/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/ivangrynenko-cursorrules-cursor-rules-python-authentication-failures)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.
Directory