├── LICENSE ├── README.md ├── leakcheck ├── leakcheck.py └── setup.py /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2024 LeakCheck Security Services LTD 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LeakCheck API Python Wrapper v2.0.0 2 | 3 | This Python wrapper allows you to interact with the LeakCheck API for checking leaked data using the official API. It includes support for both the private (authenticated) API and the public (unauthenticated) API endpoints. This wrapper has been updated to work with API v2. 4 |
5 |
6 |
7 |
8 |
9 |
10 |
220 |
221 |
222 |
223 |
Aeza Hosting - For providing powerful dedicated servers
224 | 225 | -------------------------------------------------------------------------------- /leakcheck: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Copyright (c) 2018-2024 LeakCheck Security Services LTD 4 | Licensed under MIT license 5 | Github: https://github.com/LeakCheck/leakcheck-api 6 | Created with <3 7 | """ 8 | 9 | import argparse 10 | import sys 11 | import os 12 | import json 13 | from leakcheck import LeakCheckAPI_v2, LeakCheckAPI_Public 14 | from tabulate import tabulate 15 | 16 | version = "2.0.0" 17 | 18 | def main(): 19 | parser = argparse.ArgumentParser(description="LeakCheck CLI Tool") 20 | parser.add_argument("query", help="The value to search for (email, username, etc.)") 21 | parser.add_argument("--type", "-t", help="Type of query (email, username, etc.). Will be auto-detected if not provided.") 22 | parser.add_argument("--limit", "-l", type=int, default=100, help="Limit the number of results (max 1000, default 100)") 23 | parser.add_argument("--offset", "-o", type=int, default=0, help="Offset the results (max 2500, default 0)") 24 | parser.add_argument("--public", "-p", action="store_true", help="Use the public API instead of the authenticated API.") 25 | parser.add_argument("--api-key", help="API key to authenticate with the LeakCheck service. If not provided, will attempt to read from environment variable.") 26 | parser.add_argument("--proxy", help="Optional proxy to use for the requests (HTTP, HTTPS, SOCKS5 supported). If not provided, will attempt to read from environment variable.") 27 | parser.add_argument("--pretty", action="store_true", help="Display prettified JSON output instead of a table.") 28 | 29 | args = parser.parse_args() 30 | 31 | # Load API key from environment variable if not provided as argument 32 | api_key = args.api_key or os.getenv("LEAKCHECK_APIKEY") 33 | 34 | # Check if public API or private API should be used 35 | if args.public: 36 | api = LeakCheckAPI_Public() 37 | else: 38 | try: 39 | api = LeakCheckAPI_v2(api_key=api_key) 40 | except ValueError as e: 41 | print(f"Error: {str(e)}") 42 | sys.exit(1) 43 | 44 | # Set proxy if provided or from environment variable 45 | proxy = args.proxy or os.getenv("LEAKCHECK_PROXY") 46 | if proxy: 47 | api.set_proxy(proxy) 48 | 49 | # Perform the lookup query 50 | try: 51 | if args.public: 52 | # For public API, only the query is needed 53 | result = api.lookup(args.query) 54 | else: 55 | # For authenticated API, more parameters can be provided 56 | result = api.lookup(query=args.query, query_type=args.type, limit=args.limit, offset=args.offset) 57 | except ValueError as e: 58 | print(f"Error: {str(e)}") 59 | sys.exit(1) 60 | 61 | # Print the results 62 | if result: 63 | if args.public and isinstance(result, dict) and result.get("success"): 64 | if not args.pretty and "fields" in result and result["fields"]: 65 | print(f"Sensitive data found: {', '.join(result['fields'])}") 66 | if "sources" in result and isinstance(result["sources"], list) and len(result["sources"]) > 0: 67 | if args.pretty: 68 | print(json.dumps(result, indent=4)) 69 | else: 70 | headers = ["name", "date"] 71 | rows = [[source.get("name", "N/A"), source.get("date", "N/A")] for source in result["sources"]] 72 | print(tabulate(rows, headers=headers, tablefmt="grid")) 73 | else: 74 | print("No results found.") 75 | elif isinstance(result, list) and len(result) > 0: 76 | if args.pretty: 77 | print(json.dumps(result, indent=4)) 78 | else: 79 | headers = list(result[0].keys()) 80 | headers.remove("fields") 81 | rows = [] 82 | for item in result: 83 | source_name = item["source"]["name"] if isinstance(item["source"], dict) else item["source"] 84 | rows.append([source_name if key == 'source' else item.get(key, "N/A") for key in headers]) 85 | # Append extra fields if available 86 | extra_fields = item.get('fields') 87 | if extra_fields and isinstance(extra_fields, list): 88 | for field in extra_fields: 89 | if field not in headers: 90 | headers.append(field) 91 | rows[-1].append(item.get(field, "N/A")) 92 | print(tabulate(rows, headers=headers, tablefmt="grid")) 93 | else: 94 | print("No results found.") 95 | else: 96 | print("No results found.") 97 | 98 | if __name__ == "__main__": 99 | main() -------------------------------------------------------------------------------- /leakcheck.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (c) 2018-2024 LeakCheck Security Services LTD 3 | Licensed under MIT license 4 | Github: https://github.com/LeakCheck/leakcheck-api 5 | Created with <3 6 | """ 7 | import requests 8 | import json 9 | import os 10 | import sys 11 | import platform 12 | 13 | version = "2.0.0" 14 | 15 | class LeakCheckAPI_v2: 16 | def __init__(self, api_key=None, base_url='https://leakcheck.io/api/v2'): # Updated base URL for V2 17 | # Load API key and proxy from configuration file in the home directory 18 | self.api_key = os.getenv('LEAKCHECK_APIKEY') or api_key 19 | self.proxy = os.getenv('LEAKCHECK_PROXY') 20 | 21 | if not self.api_key or len(self.api_key) < 40: 22 | raise ValueError("API key is missing, empty, or invalid (must be at least 40 characters long) in the configuration file or provided parameter.") 23 | 24 | self.base_url = base_url 25 | self.session = requests.Session() 26 | self.session.headers.update({ 27 | 'X-API-Key': self.api_key, # API key is now required in the header 28 | "User-Agent": "PyLCAPI/{}, Python {} on {}".format(version, sys.version.split(" ")[0], platform.version()) 29 | }) 30 | # Set proxy if provided 31 | if self.proxy: 32 | self.set_proxy(self.proxy) 33 | 34 | def set_proxy(self, proxy): 35 | """ 36 | Set a proxy for the session. 37 | 38 | :param proxy: Proxy URL (can be HTTP, HTTPS, or SOCKS5). 39 | """ 40 | self.session.proxies.update({'http': proxy, 'https': proxy}) 41 | 42 | def lookup(self, query, query_type=None, limit=100, offset=0): 43 | """ 44 | Perform a lookup query. 45 | 46 | :param query: The main value to search (email, username, etc.). 47 | :param query_type: Type of query ('email', 'username', etc.). If missing, it will be detected automatically. 48 | :param limit: Limit number of results (maximum 1000). 49 | :param offset: Offset for the results (maximum 2500). 50 | :return: Parsed result from API. 51 | """ 52 | if limit > 1000: 53 | raise ValueError("Limit cannot be greater than 1000.") 54 | if offset > 2500: 55 | raise ValueError("Offset cannot be greater than 2500.") 56 | 57 | endpoint = f"{self.base_url}/query/{query}" 58 | params = { 59 | 'limit': limit, 60 | 'offset': offset 61 | } 62 | # Adding optional parameters if provided 63 | if query_type: 64 | params['type'] = query_type 65 | 66 | try: 67 | response = self.session.get(endpoint, params=params) 68 | except requests.exceptions.RequestException as e: 69 | # Handle any request-related exceptions, including client and server errors 70 | raise ValueError(f"API responded with an error: {str(e)}") from e 71 | 72 | result = response.json() 73 | if not result.get('success', False): 74 | raise ValueError(f"API responded with an error: {result.get('error', 'Unknown error')}") 75 | 76 | return result.get('result') 77 | 78 | class LeakCheckAPI_Public: 79 | def __init__(self, base_url='https://leakcheck.io/api/public'): # Base URL for the public API 80 | self.base_url = base_url 81 | self.session = requests.Session() 82 | self.session.headers.update({ 83 | "User-Agent": "PyLCAPI/{}, Python {} on {}".format(version, sys.version.split(" ")[0], platform.version()) 84 | }) 85 | # Set proxy if provided 86 | self.proxy = None 87 | 88 | def set_proxy(self, proxy): 89 | """ 90 | Set a proxy for the session. 91 | 92 | :param proxy: Proxy URL (can be HTTP, HTTPS, or SOCKS5). 93 | """ 94 | self.session.proxies.update({'http': proxy, 'https': proxy}) 95 | self.proxy = proxy 96 | 97 | def lookup(self, query): 98 | """ 99 | Perform a public lookup query. 100 | 101 | :param query: The main value to search (email, email hash, or username). 102 | :return: Parsed result from API. 103 | """ 104 | try: 105 | endpoint = f"{self.base_url}?check={query}" 106 | response = self.session.get(endpoint) 107 | except requests.exceptions.RequestException as e: 108 | # Handle any request-related exceptions, including client and server errors 109 | raise ValueError(f"API responded with an error: {str(e)}") from e 110 | 111 | result = response.json() 112 | if not result.get('success', False): 113 | raise ValueError(f"API responded with an error: {result.get('error', 'Unknown error')}") 114 | 115 | return result -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r") as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name="leakcheck", 8 | version="2.0.0", 9 | py_modules = ('leakcheck',), 10 | scripts=['leakcheck'], 11 | author="LeakCheck", 12 | author_email="the@leakcheck.net", 13 | description="Python wrapper for LeakCheck API & also a CLI tool", 14 | long_description=long_description, 15 | long_description_content_type="text/markdown", 16 | url="https://github.com/LeakCheck/leakcheck-api", 17 | install_requires=[ 18 | 'requests', 19 | 'pysocks', 20 | 'tabulate' 21 | ], 22 | classifiers=[ 23 | "Programming Language :: Python :: 3", 24 | "License :: OSI Approved :: MIT License", 25 | "Operating System :: OS Independent", 26 | ], 27 | python_requires='>=3.5', 28 | ) 29 | --------------------------------------------------------------------------------