

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456 # Python Server-Side Request Forgery (SSRF) Standards (OWASP A10:2021)78This rule enforces security best practices to prevent Server-Side Request Forgery (SSRF) vulnerabilities in Python applications, as defined in OWASP Top 10:2021-A10.910<rule>11name: python_ssrf12description: Detect and prevent Server-Side Request Forgery (SSRF) vulnerabilities in Python applications as defined in OWASP Top 10:2021-A1013filters:14 - type: file_extension15 pattern: "\\.py$"16 - type: file_path17 pattern: ".*"1819actions:20 - type: enforce21 conditions:22 # Pattern 1: Detect direct use of requests library with user input23 - pattern: "requests\\.(get|post|put|delete|head|options|patch)\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"24 message: "Potential SSRF vulnerability detected. User-controlled input is being used directly in HTTP requests. Implement URL validation and allowlisting."2526 # Pattern 2: Detect urllib usage with user input27 - pattern: "urllib\\.(request|parse)\\.\\w+\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"28 message: "Potential SSRF vulnerability detected. User-controlled input is being used directly in urllib functions. Implement URL validation and allowlisting."2930 # Pattern 3: Detect http.client usage with user input31 - pattern: "http\\.client\\.\\w+\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"32 message: "Potential SSRF vulnerability detected. User-controlled input is being used directly in http.client functions. Implement URL validation and allowlisting."3334 # Pattern 4: Detect aiohttp usage with user input35 - pattern: "aiohttp\\.\\w+\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"36 message: "Potential SSRF vulnerability detected. User-controlled input is being used directly in aiohttp functions. Implement URL validation and allowlisting."3738 # Pattern 5: Detect httpx usage with user input39 - pattern: "httpx\\.\\w+\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"40 message: "Potential SSRF vulnerability detected. User-controlled input is being used directly in httpx functions. Implement URL validation and allowlisting."4142 # Pattern 6: Detect pycurl usage with user input43 - pattern: "pycurl\\.\\w+\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"44 message: "Potential SSRF vulnerability detected. User-controlled input is being used directly in pycurl functions. Implement URL validation and allowlisting."4546 # Pattern 7: Detect subprocess calls with user input that might lead to SSRF47 - pattern: "subprocess\\.(Popen|call|run|check_output|check_call)\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"48 message: "Potential SSRF vulnerability detected. User-controlled input is being used in subprocess calls, which might lead to SSRF. Validate and sanitize input."4950 # Pattern 8: Detect os.system calls with user input that might lead to SSRF51 - pattern: "os\\.(system|popen|spawn)\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"52 message: "Potential SSRF vulnerability detected. User-controlled input is being used in OS commands, which might lead to SSRF. Validate and sanitize input."5354 # Pattern 9: Detect URL construction with user input55 - pattern: "(f|r)[\"\']https?://[^\"\']*?\\{[^\\}]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"56 message: "Potential SSRF vulnerability detected. User-controlled input is being used in URL construction. Implement URL validation and allowlisting."5758 # Pattern 10: Detect URL joining with user input59 - pattern: "urljoin\\([^,]+,[^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"60 message: "Potential SSRF vulnerability detected. User-controlled input is being used in URL joining. Implement URL validation and allowlisting."6162 # Pattern 11: Detect file opening with user input (potential local SSRF)63 - pattern: "open\\([^,]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"64 message: "Potential local SSRF vulnerability detected. User-controlled input is being used in file operations. Validate file paths and use path sanitization."6566 # Pattern 12: Detect XML/YAML parsing with user input (potential XXE leading to SSRF)67 - pattern: "(ET\\.fromstring|ET\\.parse|ET\\.XML|minidom\\.parse|parseString|yaml\\.load)\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"68 message: "Potential XXE vulnerability that could lead to SSRF detected. User-controlled input is being used in XML/YAML parsing. Use safe parsing methods and disable external entities."6970 # Pattern 13: Detect socket connections with user input71 - pattern: "socket\\.(socket|create_connection)\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"72 message: "Potential SSRF vulnerability detected. User-controlled input is being used in socket connections. Implement host/port validation and allowlisting."7374 # Pattern 14: Detect FTP connections with user input75 - pattern: "ftplib\\.FTP\\([^)]*?\\b(request\\.\\w+|params\\[\\'[^\\']+\\'\\]|data\\[\\'[^\\']+\\'\\]|json\\[\\'[^\\']+\\'\\]|args\\.get|form\\.get)"76 message: "Potential SSRF vulnerability detected. User-controlled input is being used in FTP connections. Implement host validation and allowlisting."7778 # Pattern 15: Detect missing URL validation before making requests79 - pattern: "def\\s+\\w+\\([^)]*?\\):[^\\n]*?\\n(?:[^\\n]*?\\n)*?[^\\n]*?requests\\.(get|post|put|delete|head|options|patch)\\([^)]*?url\\s*=\\s*[^\\n]*?(?!.*?validate_url)"80 message: "Missing URL validation before making HTTP requests. Implement URL validation with allowlisting to prevent SSRF attacks."8182 - type: suggest83 message: |84 **Python Server-Side Request Forgery (SSRF) Prevention Best Practices:**8586 1. **URL Validation and Allowlisting:**87 - Implement strict URL validation88 - Use allowlists for domains, IP ranges, and protocols89 - Example implementation:90```python91 import re92 import socket93 import ipaddress94 from urllib.parse import urlparse9596 def is_valid_url(url, allowed_domains=None, allowed_protocols=None, block_private_ips=True):97 """98 Validate URLs against allowlists and block private IPs.99100 Args:101 url (str): The URL to validate102 allowed_domains (list): List of allowed domains103 allowed_protocols (list): List of allowed protocols104 block_private_ips (bool): Whether to block private IPs105106 Returns:107 bool: True if URL is valid according to rules108 """109 if not url:110 return False111112 # Default allowlists if none provided113 if allowed_domains is None:114 allowed_domains = ["example.com", "api.example.com"]115 if allowed_protocols is None:116 allowed_protocols = ["https"]117118 try:119 # Parse URL120 parsed_url = urlparse(url)121122 # Check protocol123 if parsed_url.scheme not in allowed_protocols:124 return False125126 # Check domain against allowlist127 if parsed_url.netloc not in allowed_domains:128 return False129130 # Block private IPs if enabled131 if block_private_ips:132 hostname = parsed_url.netloc.split(':')[0]133 try:134 ip_addresses = socket.getaddrinfo(135 hostname, None, socket.AF_INET, socket.SOCK_STREAM136 )137 for family, socktype, proto, canonname, sockaddr in ip_addresses:138 ip = sockaddr[0]139 ip_obj = ipaddress.ip_address(ip)140 if ip_obj.is_private or ip_obj.is_loopback or ip_obj.is_reserved:141 return False142 except socket.gaierror:143 # DNS resolution failed144 return False145146 return True147 except Exception:148 return False149150 # Usage example151 def fetch_resource(resource_url):152 if not is_valid_url(resource_url):153 raise ValueError("Invalid or disallowed URL")154155 # Proceed with request156 import requests157 return requests.get(resource_url)158```159160 2. **Implement Network-Level Controls:**161 - Use network-level allowlists162 - Configure firewalls to block outbound requests to internal resources163 - Example with proxy configuration:164```python165 import requests166167 def safe_request(url):168 # Configure proxy that implements URL filtering169 proxies = {170 'http': 'http://ssrf-protecting-proxy:8080',171 'https': 'http://ssrf-protecting-proxy:8080'172 }173174 # Set timeout to prevent long-running requests175 timeout = 10176177 try:178 return requests.get(url, proxies=proxies, timeout=timeout)179 except requests.exceptions.RequestException as e:180 # Log the error and handle gracefully181 logging.error(f"Request failed: {e}")182 return None183```184185 3. **Use Safe Libraries and Wrappers:**186 - Create wrapper functions for HTTP requests187 - Implement consistent security controls188 - Example wrapper:189```python190 import requests191 from urllib.parse import urlparse192193 class SafeRequestHandler:194 def __init__(self, allowed_domains=None, allowed_protocols=None):195 self.allowed_domains = allowed_domains or ["api.example.com"]196 self.allowed_protocols = allowed_protocols or ["https"]197198 def validate_url(self, url):199 parsed_url = urlparse(url)200201 # Validate protocol202 if parsed_url.scheme not in self.allowed_protocols:203 return False204205 # Validate domain206 if parsed_url.netloc not in self.allowed_domains:207 return False208209 return True210211 def request(self, method, url, **kwargs):212 if not self.validate_url(url):213 raise ValueError(f"URL validation failed for: {url}")214215 # Set sensible defaults216 kwargs.setdefault('timeout', 10)217218 # Make the request219 return requests.request(method, url, **kwargs)220221 def get(self, url, **kwargs):222 return self.request('GET', url, **kwargs)223224 def post(self, url, **kwargs):225 return self.request('POST', url, **kwargs)226227 # Usage228 safe_requests = SafeRequestHandler()229 response = safe_requests.get('https://api.example.com/data')230```231232 4. **Disable Redirects or Implement Redirect Validation:**233 - Disable automatic redirects234 - Validate each redirect location235 - Example:236```python237 import requests238239 def safe_request_with_redirect_validation(url, allowed_domains):240 # Disable automatic redirects241 session = requests.Session()242 response = session.get(url, allow_redirects=False)243244 # Handle redirects manually with validation245 redirect_count = 0246 max_redirects = 5247248 while 300 <= response.status_code < 400 and redirect_count < max_redirects:249 redirect_url = response.headers.get('Location')250251 # Validate redirect URL252 parsed_url = urlparse(redirect_url)253 if parsed_url.netloc not in allowed_domains:254 raise ValueError(f"Redirect to disallowed domain: {parsed_url.netloc}")255256 # Follow the redirect with validation257 redirect_count += 1258 response = session.get(redirect_url, allow_redirects=False)259260 return response261```262263 5. **Use Metadata Instead of Direct URLs:**264 - Use resource identifiers instead of URLs265 - Resolve identifiers server-side266 - Example:267```python268 def fetch_resource_by_id(resource_id):269 # Map of allowed resources270 resource_map = {271 "user_profile": "https://api.example.com/profiles/",272 "product_data": "https://api.example.com/products/",273 "weather_info": "https://api.weather.com/forecast/"274 }275276 # Check if resource_id is in allowed list277 if resource_id not in resource_map:278 raise ValueError(f"Unknown resource ID: {resource_id}")279280 # Construct URL from safe base + ID281 base_url = resource_map[resource_id]282 return requests.get(base_url)283```284285 6. **Implement Response Handling Controls:**286 - Sanitize and validate responses287 - Prevent response data from being used in further requests288 - Example:289```python290 def safe_request_with_response_validation(url):291 response = requests.get(url)292293 # Check response size294 if len(response.content) > MAX_RESPONSE_SIZE:295 raise ValueError("Response too large")296297 # Validate content type298 content_type = response.headers.get('Content-Type', '')299 if not content_type.startswith('application/json'):300 raise ValueError(f"Unexpected content type: {content_type}")301302 # Parse and validate JSON structure303 try:304 data = response.json()305 # Validate expected structure306 if 'result' not in data:307 raise ValueError("Invalid response structure")308 return data309 except ValueError:310 raise ValueError("Invalid JSON response")311```312313 7. **Use Timeouts and Circuit Breakers:**314 - Set appropriate timeouts315 - Implement circuit breakers for failing services316 - Example:317```python318 import requests319 from requests.exceptions import Timeout, ConnectionError320321 def request_with_circuit_breaker(url, max_retries=3, timeout=5):322 retries = 0323 while retries < max_retries:324 try:325 return requests.get(url, timeout=timeout)326 except (Timeout, ConnectionError) as e:327 retries += 1328 if retries >= max_retries:329 # Circuit is now open330 raise ValueError(f"Circuit breaker open for {url}: {str(e)}")331 # Exponential backoff332 time.sleep(2 ** retries)333```334335 8. **Implement Proper Logging and Monitoring:**336 - Log all outbound requests337 - Monitor for unusual patterns338 - Example:339```python340 import logging341 import requests342343 def logged_request(url, **kwargs):344 # Log the outbound request345 logging.info(f"Outbound request to: {url}")346347 try:348 response = requests.get(url, **kwargs)349 # Log the response350 logging.info(f"Response from {url}: status={response.status_code}")351 return response352 except Exception as e:353 # Log the error354 logging.error(f"Request to {url} failed: {str(e)}")355 raise356```357358 9. **Use DNS Resolution Controls:**359 - Implement DNS resolution controls360 - Block internal DNS names361 - Example:362```python363 import socket364 import ipaddress365366 def is_safe_host(hostname):367 try:368 # Resolve hostname to IP369 ip_addresses = socket.getaddrinfo(370 hostname, None, socket.AF_INET, socket.SOCK_STREAM371 )372373 for family, socktype, proto, canonname, sockaddr in ip_addresses:374 ip = sockaddr[0]375 ip_obj = ipaddress.ip_address(ip)376377 # Check if IP is private/internal378 if (ip_obj.is_private or ip_obj.is_loopback or379 ip_obj.is_link_local or ip_obj.is_reserved):380 return False381382 return True383 except (socket.gaierror, ValueError):384 return False385386 def safe_request_with_dns_check(url):387 parsed_url = urlparse(url)388 hostname = parsed_url.netloc.split(':')[0]389390 if not is_safe_host(hostname):391 raise ValueError(f"Hostname resolves to unsafe IP: {hostname}")392393 return requests.get(url)394```395396 10. **Implement Defense in Depth:**397 - Combine multiple protection mechanisms398 - Don't rely on a single control399 - Example comprehensive approach:400```python401 class SSRFProtectedClient:402 def __init__(self):403 self.allowed_domains = ["api.example.com", "cdn.example.com"]404 self.allowed_protocols = ["https"]405 self.max_redirects = 3406 self.timeout = 10407408 def is_safe_url(self, url):409 # URL validation410 parsed_url = urlparse(url)411412 # Protocol check413 if parsed_url.scheme not in self.allowed_protocols:414 return False415416 # Domain check417 if parsed_url.netloc not in self.allowed_domains:418 return False419420 # DNS resolution check421 hostname = parsed_url.netloc.split(':')[0]422 try:423 ip_addresses = socket.getaddrinfo(424 hostname, None, socket.AF_INET, socket.SOCK_STREAM425 )426 for family, socktype, proto, canonname, sockaddr in ip_addresses:427 ip = sockaddr[0]428 ip_obj = ipaddress.ip_address(ip)429 if ip_obj.is_private or ip_obj.is_loopback or ip_obj.is_reserved:430 return False431 except socket.gaierror:432 return False433434 return True435436 def request(self, method, url, **kwargs):437 # Validate URL438 if not self.is_safe_url(url):439 raise ValueError(f"URL failed security validation: {url}")440441 # Set sensible defaults442 kwargs.setdefault('timeout', self.timeout)443 kwargs.setdefault('allow_redirects', False)444445 # Make initial request446 session = requests.Session()447 response = session.request(method, url, **kwargs)448449 # Handle redirects manually with validation450 redirect_count = 0451452 while 300 <= response.status_code < 400 and redirect_count < self.max_redirects:453 redirect_url = response.headers.get('Location')454455 # Validate redirect URL456 if not self.is_safe_url(redirect_url):457 raise ValueError(f"Redirect URL failed security validation: {redirect_url}")458459 # Follow the redirect with validation460 redirect_count += 1461 response = session.request(method, redirect_url, **kwargs)462463 # Log the request464 logging.info(f"{method} request to {url} completed with status {response.status_code}")465466 return response467468 def get(self, url, **kwargs):469 return self.request('GET', url, **kwargs)470471 def post(self, url, **kwargs):472 return self.request('POST', url, **kwargs)473474 # Usage475 client = SSRFProtectedClient()476 response = client.get('https://api.example.com/data')477```478479 - type: validate480 conditions:481 # Check 1: URL validation implementation482 - pattern: "def\\s+is_valid_url|def\\s+validate_url"483 message: "URL validation function is implemented."484485 # Check 2: Allowlist implementation486 - pattern: "allowed_domains|allowed_urls|ALLOWED_HOSTS|whitelist"487 message: "URL allowlisting is implemented."488489 # Check 3: Safe request wrapper490 - pattern: "class\\s+\\w+Request|def\\s+safe_request"491 message: "Safe request wrapper is implemented."492493 # Check 4: IP address validation494 - pattern: "ipaddress\\.ip_address|is_private|is_loopback|is_reserved"495 message: "IP address validation is implemented to prevent access to internal resources."496497metadata:498 priority: high499 version: 1.0500 tags:501 - security502 - python503 - ssrf504 - owasp505 - language:python506 - framework:django507 - framework:flask508 - framework:fastapi509 - category:security510 - subcategory:ssrf511 - standard:owasp-top10512 - risk:a10-server-side-request-forgery513 references:514 - "https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29/"515 - "https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html"516 - "https://portswigger.net/web-security/ssrf"517 - "https://docs.python.org/3/library/urllib.request.html"518 - "https://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification"519 - "https://docs.python.org/3/library/ipaddress.html"520</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-ssrf)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