Compare commits

...

641 Commits

Author SHA1 Message Date
Paul Pfeister 8f1308b90d
Merge pull request #2758 from Aaditya-Chunekar/patch-2
Add Credly data to JSON resource
2025-12-29 19:54:44 -08:00
Paul Pfeister e856b05c2c
Merge pull request #2636 from simplyNour/Bug/fix-gradle-false-pos-test-failure
Bug: Fix local variable scoping issue affecting false-pos test output
2025-12-29 18:56:30 -08:00
Aaditya fe9e750dab
Add Credly data to JSON resource 2025-11-14 09:27:07 +05:30
Paul Pfeister 842ae1f754
Merge pull request #2733 from Aaditya-Chunekar/patch-1
Add Nothing Community data to data.json
2025-10-29 16:34:10 -07:00
Paul Pfeister 339634f7bc
Merge pull request #2737 from Nolanp123/fix-minecraft-regex
Fix Minecraft False Positives for Long Usernames
2025-10-28 20:47:32 -07:00
Nolan Parker c1632693bb Add regexCheck to Minecraft to prevent false positives for long usernames 2025-10-28 20:39:53 -05:00
Aaditya e19cb32009
Add Nothing Community data to data.json 2025-10-27 11:20:30 +05:30
Paul Pfeister b69c8ef940
Merge pull request #2710 from Aaditya-Chunekar/add-sites
hacktoberfest: Added sites support
2025-10-26 00:16:29 -07:00
Aaditya-Chunekar 2724711060 feat: add tmdb 2025-10-26 09:49:31 +05:30
Paul Pfeister 0a68ab7f4c
Merge pull request #2709 from Aaditya-Chunekar/add-topmate
hacktoberfest: Add topmate.io support
2025-10-24 20:15:02 -07:00
Paul Pfeister 8675178be1
Merge pull request #2705 from Aaditya-Chunekar/add-site-seoforum
hacktoberfest: Add SEO Forum Support
2025-10-24 20:12:50 -07:00
Aaditya-Chunekar 9bafb8a280 feat: add n8n, HackerSploit, Arduino Forum 2025-10-24 09:37:40 +05:30
Aaditya-Chunekar 8e5549862a feat: add topmate.io 2025-10-24 09:14:42 +05:30
Aaditya-Chunekar 8797fcd517 feat: add SEOForum 2025-10-24 08:46:23 +05:30
Paul Pfeister 0995d4d669
chore: reformat 2025-10-23 19:39:05 -04:00
Paul Pfeister 6c0c273a0b
Merge pull request #2695 from simplyNour/Bug/urls-are-not-clickable-in-excel-file
Make urls clickable when saved to excel
2025-10-23 16:25:17 -07:00
Paul Pfeister 3eeba790fd
Merge pull request #2722 from VivekGaddam/Twitch_Added
Added Twitch Platform Support to Sherlock
2025-10-23 15:28:01 -07:00
Paul Pfeister 61a29ec373
Merge pull request #2723 from imhiteshgarg/adding_lemmy
adding lemmy
2025-10-23 15:26:57 -07:00
Paul Pfeister 9fbbbf7c73
Merge pull request #2724 from obiwan04kanobi/feat/add-codolio
feat: add Codolio to supported sites
2025-10-23 15:26:16 -07:00
obiwan04kanobi 331b68d909 feat: add Codolio to supported sites
Add Codolio (coding portfolio tracker) as a new site target for username detection.

Detection method: Message-based using title tag differences
- Existing profiles: '<title>Username | Codolio</title>'
- Non-existing profiles: '<title>Page Not Found | Codolio</title>'

Tested with multiple usernames to confirm accurate detection.
2025-10-23 22:42:06 +05:30
Hitesh Garg 8c3e093561 adding lemmy
adding lemmy
2025-10-23 21:38:18 +05:30
vivekgaddam e35e5e3af1 corrected Twitch 2025-10-23 19:41:00 +05:30
vivekgaddam 906287b305 added twitch 2025-10-23 19:18:31 +05:30
Matheus Felipe 0dbb6abcc5
Fix Minor Capitalization Issue in README.md (#2716) 2025-10-23 09:08:29 -03:00
Matheus Felipe 03e097cc82
Reorder Terraria Forums to correct alphabetical position (#2700) 2025-10-23 08:53:50 -03:00
Matheus Felipe 91c1964918
Add GameFaqs support (#2721)
Co-authored-by: Maquinero123456 <jimenanavarrodavid@uma.es>
2025-10-23 08:04:41 -03:00
Matheus Felipe 373f3d389a
Added support for Trovo (#2720) 2025-10-23 06:17:28 -03:00
SirAzako 828c47109d
Added support for Trovo 2025-10-23 06:10:20 -03:00
Matheus Felipe 94245b25df
Add OpenGameArt support (#2719)
Co-authored-by: Horațiu Mlendea <Horatiu.Mlendea@ProtonMail.com>
2025-10-23 05:03:35 -03:00
Matheus Felipe 734542f0af
Add mstdn.social (#2718) 2025-10-23 04:19:10 -03:00
Matheus Felipe 1f8166ba9f
Remove unclaimed username entry for mstdn.social 2025-10-23 03:41:21 -03:00
MagicLike 6f1ddaa615
Added mstdn.social
Added another Mastodon instance: mstdn.social
2025-10-23 03:32:54 -03:00
Nolan Parker 7ee2891517 Fix Minor Capitalization Issue in README.md 2025-10-22 22:16:13 -05:00
Paul Pfeister b893e4aa20
Merge pull request #2711 from imhiteshgarg/add_observablehq
Adding ObservableHQ site
2025-10-21 23:04:24 -07:00
Hitesh Garg eff869906a Adding ObservableHQ site
Adding ObservableHQ site
2025-10-22 10:58:31 +05:30
Paul Pfeister 2a0107e189
Merge pull request #2702 from ABSCP4/patch-1
Update README.md
2025-10-20 15:33:36 -07:00
ABSCP4 5d8c4de212
Update README.md
fixed typo
2025-10-20 11:01:32 -07:00
Nolan Parker 1f9d7e8373 Reorder Terraria Forums to correct alphabetical position 2025-10-19 15:53:09 -05:00
Paul Pfeister 184470f871
Merge pull request #2699 from Nolanp123/fix-codesandbox-name
Fix site name formatting for CodeSandbox
2025-10-19 13:14:14 -07:00
Nolan Parker 342dbc85cc Fix site name formatting for CodeSandbox 2025-10-19 14:44:47 -05:00
Paul Pfeister 457e16e84f
Merge pull request #2670 from simplyNour/Bug/fix-false-positive-for-topcoder
fix: false positive for Topcoder
2025-10-18 23:47:34 -07:00
Paul Pfeister 43b3736b75
Merge pull request #2697 from raman1236/add-odysee-support
Add Odysee support
2025-10-18 23:06:15 -07:00
Paul Pfeister 64a49ffe17
Merge pull request #2698 from KaiAllAlone/KaiAllAlone-warframe-market
Add Warframe Market support
2025-10-18 22:48:00 -07:00
rvasikarla 0afd2006c6 Add Odysee support
- Add Odysee platform to sherlock database- Uses canonical link detection for non-existent users- URL pattern: https://odysee.com/@\{username\}- Detects error via canonical redirect to main site
2025-10-18 16:47:27 -05:00
rvasikarla 3c270173a7 Add Odysee support
- Add Odysee platform to sherlock database- Uses canonical link detection for non-existent users- URL pattern: https://odysee.com/@\{username\}- Detects error via canonical redirect to main site
2025-10-18 16:44:10 -05:00
rvasikarla 8d73f9ef4c Add Odysee support
- Add Odysee platform to sherlock database- Uses canonical link detection for non-existent users- URL pattern: https://odysee.com/@\{username\}- Detects error via canonical redirect to main site
2025-10-18 16:37:31 -05:00
Debanuj Roy 472c086805
Update data.jsonfixed syntax error 2025-10-19 03:06:25 +05:30
Debanuj Roy 400c277f24
more robust 2025-10-19 03:00:43 +05:30
Debanuj Roy e759564550
Update data.jsonupdate matching logic 2025-10-19 02:55:33 +05:30
Debanuj Roy deebe7137c
Added Warframe Market 2025-10-19 02:45:07 +05:30
nour cb14ccbaaf Make urls clickable when saved to excel 2025-10-18 15:21:36 +03:00
Paul Pfeister eb892795e9
Merge pull request #2683 from 403Code/patch-1
Add: Cfx.re Forum
2025-10-15 10:52:32 -07:00
Rizey (Nantaaaaaaaaaa) 09de90066b
Update data.json 2025-10-15 13:39:44 +07:00
Rizey (Nantaaaaaaaaaa) cd1f27c12b
Update data.json 2025-10-15 13:29:42 +07:00
Rizey (Nantaaaaaaaaaa) b837de8358
Add Cfx.re Forum 2025-10-15 13:22:09 +07:00
Paul Pfeister 7a70f35883
Merge pull request #2680 from bjornmorten/add/norwegian-forums
Add Norwegian forum sites (diskusjon.no & forum.kvinneguiden.no)
2025-10-14 11:25:31 -07:00
bjornmorten 4b17dae385
fix: regex max length for kvinneguiden 2025-10-14 19:48:02 +02:00
Paul Pfeister efefe3f54a
Merge pull request #2682 from bjornmorten/add/cryptohack
Add: CryptoHack
2025-10-14 10:41:41 -07:00
Paul Pfeister 4b70a1fc25
Merge pull request #2681 from bjornmorten/add/hackmd
Add: HackMD
2025-10-14 10:41:31 -07:00
bjornmorten a7893f399e add: CryptoHack 2025-10-14 19:28:53 +02:00
bjornmorten 1cb6c12851 add: HackMD 2025-10-14 19:21:36 +02:00
bjornmorten c4f7485ecf fix: alphabetical ordering 2025-10-14 19:10:57 +02:00
bjornmorten 228f50413e add: diskusjon.no and forum.kvinneguiden.no 2025-10-14 19:08:35 +02:00
Paul Pfeister d1867b1b51
Merge pull request #2679 from aryanj10/fix-fasle-positive-for-lesswrong
Fix LessWrong detection Issue #2634
2025-10-14 09:58:56 -07:00
Aryan Jain 6d2497582e Fix LessWrong detection Issue #2634 2025-10-14 11:04:15 -04:00
Paul Pfeister 885c43b8af
Merge pull request #2677 from spmedia/patch-9
Add: BreachSta.rs Forum
2025-10-13 16:12:36 -07:00
Edmond Major III 8ad47b0b23
Update data.json 2025-10-13 17:23:10 -05:00
Edmond Major III e93af99424
Update data.json
remix based off title instead of text in body
2025-10-13 17:20:50 -05:00
Edmond Major III 5862ab4f92
Update data.json
Add in BreachSta.rs forum - a popular cybercrime forum

https://breachsta.rs/profile/Sleepybubble - returns valid profile

https://breachsta.rs/profile/asdfasdfasdf - returns "Not found
This page doesn't exist"
2025-10-13 17:15:26 -05:00
Paul Pfeister 4110cac45c
Merge pull request #2661 from KaiAllAlone/terraria-forums
Site Added:Terraria forums
2025-10-13 15:07:31 -07:00
Paul Pfeister d66b18e8ae
Merge pull request #2676 from spmedia/patch-8
Add: Patched.sh
2025-10-13 14:53:19 -07:00
Edmond Major III b532fc6a38
Add: Patched.sh
Add Patched, a popular cybercrime forum.

https://patched.sh/User/blue = valid user

https://patched.sh/User/khjasjkdhfa38a = not a valid user and displays "The member you specified is either invalid or doesn't exist."
2025-10-13 13:20:03 -05:00
Paul Pfeister 99cf073835
Merge pull request #2674 from spmedia/patch-6
Add: Cracked.sh
2025-10-13 10:41:46 -07:00
Edmond Major III ec7e1b8b81
Update data.json
Trailing / was the issue so removed it
2025-10-13 12:30:50 -05:00
Edmond Major III a4aab38901
Update data.json
Remove www
2025-10-13 12:24:02 -05:00
Edmond Major III 5202900618
Update data.json
Updated error msg on no user
2025-10-13 12:16:09 -05:00
Edmond Major III 26444a98ad
Update data.json
Add Cracked.sh - a popular skid hacker website

Examples of profiles:

Claimed: https://cracked.sh/Blue - gives status code of 200

Unclaimed: https://cracked.sh/noonewouldeverusethis7 - gives status code of 404
2025-10-13 12:12:43 -05:00
Paul Pfeister bced3242f3
Merge pull request #2668 from simplyNour/Bug/fix-false-positive-for-hackerearth
fix:  false positive for hackerearth
2025-10-13 10:03:00 -07:00
Paul Pfeister 08aabdad76
Merge pull request #2673 from simplyNour/Deprecate/pepper-site-is-no-longer-operating
Deprecate: Pepper.it closed its doors on August2025
2025-10-13 10:00:45 -07:00
Paul Pfeister 170ee0b928
Merge branch 'master' into Deprecate/pepper-site-is-no-longer-operating 2025-10-13 09:58:47 -07:00
Paul Pfeister 2c9a54438a
Merge pull request #2672 from simplyNour/Feature/add-pepper-global-sites
Feat: Add pepper stores worldwide websites
2025-10-13 09:57:36 -07:00
nour 84f4886809 Feat: Add pepper stores worldwide websites 2025-10-13 17:46:38 +03:00
nour e26fd6b643 Fix: false positive for topcoder due to invalid regex 2025-10-13 16:27:02 +03:00
Paul Pfeister ce5de20f80
Merge pull request #2659 from faizan842/re-enable-opencollective-powershell-realmeye
Re-enable OpenCollective and Realmeye
2025-10-12 19:01:46 -07:00
Paul Pfeister 3ff2d135b5
Merge branch 'master' into re-enable-opencollective-powershell-realmeye 2025-10-12 18:58:04 -07:00
Paul Pfeister 1e65b4a209
Merge pull request #2657 from KaiAllAlone/patch-1
Add Pokemon Forums
2025-10-12 18:55:13 -07:00
Debanuj Roy db3545b7b0
Added more robust message 2025-10-12 16:31:27 +05:30
Debanuj Roy 1898a0c4a9
Add Terraria Forums 2025-10-12 16:27:30 +05:30
Faizan Habib 0d32357b10 Re-enable OpenCollective and Realmeye
- Updated OpenCollective to use status_code detection (previously used message detection)
- Added Realmeye with message detection

Both sites were previously removed due to false positives but have been verified to work correctly now:
- OpenCollective: Returns 200 for existing profiles, 404 for non-existent
- Realmeye: Shows 'Sorry, but we either:' error message for non-existent players

Tested with known usernames:
- OpenCollective: sindresorhus
- Realmeye: rotmg

Note: PowerShell Gallery was initially included but removed after discovering their /profiles/ endpoint no longer works.
2025-10-12 13:57:22 +05:30
Debanuj Roy 1be2abb056
Resolved wrong urlMain 2025-10-12 13:39:55 +05:30
Debanuj Roy fb392534ef
Add Pokemon Forums 2025-10-12 08:03:23 +05:30
Paul Pfeister bd49aac9d1
Merge pull request #2606 from Fandroid745/fix/babyru-false-positive
fix: Add error messages to BabyRu to prevent false positives
2025-10-11 18:10:54 -04:00
Matheus Felipe 94838863fd
Cleanup site-list.py (#2307) 2025-10-11 15:30:08 -03:00
Matheus Felipe 79973a58ea
Update file handling to include encoding and correct comments 2025-10-11 15:21:36 -03:00
Fandroid745 b9a72b55ca fix: use Unicode escape sequences for BabyRu error messages 2025-10-11 23:14:43 +05:30
Paul Pfeister ef55f7ddd3
chore: reformat json 2025-10-11 13:34:45 -04:00
Paul Pfeister 28b78e7ddd
Merge pull request #2633 from VivekGaddam/add-tiktok-support
Add TikTok (tiktok.com) to supported sites
2025-10-11 13:33:39 -04:00
Paul Pfeister d2072e2cac
chore: rem tiktok for improved rev 2025-10-11 13:32:51 -04:00
Paul Pfeister 3edb73cb23
Merge pull request #2650 from Nirzak/patch-1
Added classifiers for supported python version
2025-10-11 13:30:20 -04:00
Paul Pfeister 6d1280ee9d
Merge pull request #2651 from aryanj10/add-tiktok-pinterest
Added support for TikTok & Pinterest
2025-10-11 13:12:13 -04:00
Dhanush Sugganahalli 0c457e590a
Merge branch 'master' into fix/babyru-false-positive 2025-10-11 21:24:18 +05:30
Aryan Jain dc307fc0fd feat: add TikTok and Pinterest site detection support 2025-10-11 10:34:48 -04:00
Nirjas Jakilim d6256e9fc6
classifiers for supported python version 2025-10-11 20:27:27 +06:00
Aryan Jain 1645828527 Add TikTok site support 2025-10-11 09:25:00 -04:00
Matheus Felipe e774b08dc5
Add imood.com support (#2647) 2025-10-11 09:28:06 -03:00
Matheus Felipe 99067b2e59
Add imood.com support
resolve #2646
2025-10-11 09:23:52 -03:00
nour f039b50c4e Deprecate: Pepper closed its doors on August 14th 2025. 2025-10-11 08:29:32 +03:00
nour 7d5bd97142 fix: false positive for hackerearth 2025-10-11 07:17:01 +03:00
vivekgaddam 70b5055631 corrected india F+ prevent 2025-10-11 08:54:40 +05:30
Paul Pfeister 1be25e70df
Merge pull request #2621 from MaxwellOldshein/feat/validate-remote-manifest-with-local-schema-before-validate-target-test-suite
feat: GitHub Actions - Validate Remote Manifest Against Local Schema Before Running Validate Modified Targets Test Suite
2025-10-10 20:41:58 -04:00
Paul Pfeister 9000575f7c
Merge pull request #2631 from simplyNour/Add-Vjudge-Support-to-Sherlock
Add Vjudge to the sites source
2025-10-10 20:38:16 -04:00
Paul Pfeister 220ebf935c
Merge pull request #2640 from sctech-tr/patch-1
add status cafe (status.cafe)
2025-10-10 20:22:44 -04:00
sctech 959c4a2b26
change method for status.cafe 2025-10-10 20:38:08 +03:00
sctech 443d43df21
add status cafe 2025-10-10 20:09:45 +03:00
Paul Pfeister 80080cd57c
Merge pull request #2638 from simplyNour/Bug/fix-false-positive-for-kaskus 2025-10-10 12:51:15 -04:00
nour 80922a93fa fix: false positive for kaskus 2025-10-10 18:53:28 +03:00
nour 45494fc74b bug: fix local variable scoping issue in test validate targets 2025-10-10 06:29:55 +03:00
nour d92e2339a1 feat: add vjudge 2025-10-10 05:28:28 +03:00
vivekgaddam 659bf92d99 corrected the errorMsg 2025-10-09 19:50:43 +05:30
vivekgaddam 3e4d9bcd85 Add TikTok support to Sherlock 2025-10-09 17:57:15 +05:30
Matheus Felipe d3076cdfe0
Add Ifunny (#2632) 2025-10-09 09:16:41 -03:00
Derick Kunz 51436cefe8
Add Ifunny 2025-10-09 08:51:13 -03:00
Paul Pfeister 08a8177286
Merge pull request #2610 from eslteacher902010/add-musescore-clean 2025-10-09 06:19:35 -04:00
Paul Pfeister e6d5fd64e0
Merge pull request #2622 from akh7177/Add-support-for-Discord.bio
Add support for Discord.bio
2025-10-08 13:03:57 -04:00
Abhyuday K Hegde ac9f3a7fd5
Add support for Discord.bio 2025-10-08 11:21:53 +05:30
Paul Pfeister 289ab28b98
Merge pull request #2576 from obiwan04kanobi/add-aws-skills-profile-site
Add AWS Skills Profile site to Sherlock
2025-10-07 19:46:54 -04:00
Maxwell Oldshein 46ad6c9a5e Fix whitespace. 2025-10-07 14:53:47 -04:00
Maxwell Oldshein d20dcbe8db Retain original whitespace 2025-10-07 14:52:53 -04:00
Maxwell Oldshein 70c3c84196 Update validation logic placement in workflow 2025-10-07 14:50:54 -04:00
Dhanush Sugganahalli 53840c6a98
Merge branch 'master' into fix/babyru-false-positive 2025-10-07 14:41:12 +05:30
Fandroid745 068fff8711 fix:Remove regexCheck field and changed encoding to UTF-8 2025-10-07 14:33:32 +05:30
Maxwell Oldshein 5735d01804 Validate remote manifest against local schema 2025-10-06 23:52:14 -04:00
Paul Pfeister f60de0d8f8
Merge pull request #2616 from akh7177/Add-new-sites-to-data.json 2025-10-06 13:39:04 -04:00
Paul Pfeister cb3ab91492
Merge pull request #2485 from manjushsh/code-sandbox 2025-10-06 13:30:10 -04:00
paul_kniaz 4eea79ed6a MuseScore: use GET for status_code via request_method to avoid 403 on HEAD 2025-10-06 13:07:45 -04:00
Abhyuday K Hegde 03c051a525
Add new sites to Sherlock 2025-10-06 18:47:38 +05:30
Aniket eccdf80b95
Add Pronouns.page (#2419)
* Add support for Pronouns.page (#2418)

* Update the url
2025-10-06 09:52:56 -03:00
Manjush Shetty eb51bf9b1a misc: remove isnsfw from hive 2025-10-06 17:15:44 +05:30
Manjush Shetty 5d7b438fd6 add urlProbe 2025-10-06 17:11:50 +05:30
Manjush Shetty ef0b97fb57 chore: try with api instead 2025-10-06 16:54:07 +05:30
Manjush Shetty c6c3522159 chore: add custom regex for codesandbox usernames 2025-10-06 16:45:53 +05:30
Manjush Shetty 2908c8eaa8 chore: try with different message 2025-10-06 16:40:59 +05:30
Manjush S f05b8e0ed6
Merge branch 'sherlock-project:master' into code-sandbox 2025-10-06 16:21:40 +05:30
Fandroid745 01bca6b39f fix: corrected the regexCheck field value to an empty string 2025-10-06 08:57:11 +05:30
Paul Pfeister d2835e56a4
Merge pull request #2568 from shreyasNaik0101/fix/remediate-blitztactics
fix(sites): Remediate false positive for Blitz Tactics
2025-10-05 14:17:43 -04:00
shreyasNaik0101 0cf110e69e
Merge branch 'master' into fix/remediate-blitztactics 2025-10-05 22:56:59 +05:30
Paul Pfeister a88adb0488
Merge pull request #2559 from frogtheastronaut/master
Removed duplicate Bluesky entry in data.json
2025-10-05 13:23:53 -04:00
Fandroid745 4010a58dde fix: changed the username_claimed to example placeholder 2025-10-05 22:23:17 +05:30
Paul Pfeister b9e28b9b23
Merge pull request #2588 from shreyasNaik0101/fix/correct-ci-diff
fix(ci): Use merge-base for correct target validation
2025-10-05 12:49:58 -04:00
Paul Pfeister d0e005da23
Merge pull request #2609 from akh7177/Add-support-for-WakaTime
Add support for WakaTime
2025-10-05 12:30:24 -04:00
paul_kniaz 7a4f19e6b3 Fix MuseScore URL endpoint 2025-10-05 12:27:30 -04:00
paul_kniaz f958e7b96f update MuseScore username_claimed to arrangeme (valid profile) 2025-10-05 12:13:37 -04:00
paul_kniaz 4c99bf3b75 Add MuseScore site (clean version) 2025-10-05 10:44:55 -04:00
Fandroid745 e3066a1d7a fix:added the username_claimed field 2025-10-05 18:59:04 +05:30
Abhyuday K Hegde f0510a169a
Add support for WakaTime 2025-10-05 15:52:56 +05:30
manjushsh 738df6c362 chore: add error message to the codesandbox 2025-10-05 15:22:37 +05:30
Paul Pfeister 83a38db110
Merge pull request #2582 from dollaransh17/fix/boardgamegeek-false-positive
fix(sites): Update BoardGameGeek URL structure and detection method
2025-10-05 02:39:29 -04:00
dollaransh17 9e3448d992 fix(sites): So , Implemented BoardGameGeek using username validation API
- Added BoardGameGeek back using the new API endpoint suggested by @ppfeister
- Uses https://api.geekdo.com/api/accounts/validate/username?username={} for detection
- errorMsg checks for '"isValid":true' to detect valid usernames
- This approach avoids the previous issues with:
  * HTML parsing returning false positives
  * User API returning JSON with '[]' substrings that caused detection problems
- Successfully tested with both valid (blue) and invalid usernames

Thanks @ppfeister for the API suggestion and @akh7177 for the initial guidance
2025-10-05 11:59:41 +05:30
shreyasNaik0101 70e3c0ddd8 fix(ci): Address review feedback for correctness and efficiency 2025-10-05 11:00:14 +05:30
Fandroid745 017c08a45d fix: Add error messages to BabyRu to prevent false positives 2025-10-05 10:53:59 +05:30
Paul Pfeister f32f4ffaee
Merge pull request #2595 from obiwan04kanobi/feature/issue-2196-ci-docker-build-test
Add Docker build test to CI workflow (#2196)
2025-10-04 21:09:04 -04:00
Paul Pfeister 7379ba7b19
Merge branch 'remove-tor' 2025-10-04 20:52:40 -04:00
Paul Pfeister 3aeb6d6356
Merge pull request #2602 from sherlock-project/feat/no-txt
chore: make default --no-txt
2025-10-04 20:36:33 -04:00
Paul Pfeister 4246a7b16f
chore: make default --no-txt
Workflows where a txt file is still required should use --txt
2025-10-04 20:32:16 -04:00
Paul Pfeister e44fe49c8f
Merge pull request #2601 from sherlock-project/feat/graceful-skip
feat: gracefully skip sites with invalid errorType
2025-10-04 20:23:07 -04:00
Paul Pfeister 52cd5fdfc1
feat: gracefully skip sites with invalid errorType 2025-10-04 20:22:34 -04:00
Paul Pfeister 947f1ad2b6
Merge pull request #2574 from dollaransh17/fix/http-request-timeouts
Security Fix: Add timeout parameters to HTTP requests
2025-10-04 18:42:13 -04:00
shreyasNaik0101 4d00884d8c fix(ci): Implement secure diff logic per feedback 2025-10-05 03:00:21 +05:30
Paul Pfeister cfcc82aaca
Merge pull request #2597 from sherlock-project/feat/multiple-types
Support multiple errorType checks
2025-10-04 17:21:26 -04:00
Paul Pfeister 0794e02b52
feat: support multiple errorTypes 2025-10-04 16:53:30 -04:00
Paul Pfeister 975965abed
Merge pull request #2589 from dollaransh17/fix/threads-false-positive
fix(sites): Fix Threads false positive detection
2025-10-04 15:44:04 -04:00
Paul Pfeister a678bed154
Merge pull request #2587 from akh7177/remediate-cyberdefenders-fp
fix(sites):  Remediate False Positives for CyberDefenders
2025-10-04 15:43:48 -04:00
Paul Pfeister 4ec6f1eec0
Merge pull request #2585 from akh7177/remediate-slideshare-fp
fix(sites):  Remediate False Positive for SlideShare
2025-10-04 15:43:36 -04:00
Paul Pfeister d1527376e7
Merge pull request #2584 from akh7177/remediate-roblox-fp
fix(sites):  Remediate False Positive for Roblox
2025-10-04 15:43:29 -04:00
obiwan04kanobi b99719ce60 Add Docker build test to CI workflow
- Adds docker-build-test job to regression.yml
- Runs on push/merge to master and release branches
- Extracts VERSION_TAG from pyproject.toml for build
- Tests that Docker image builds and runs successfully
- Resolves dockerfile syntax warnings
- Resolves #2196"
2025-10-05 00:22:12 +05:30
dollaransh17 dc869852bc fix(sites): Fix Threads false positive detection
Threads was showing false positives for non-existent users because
the error message detection was incorrect.

Updated errorMsg:
- Old: "<title>Threads</title>" (generic, matches valid pages too)
- New: "<title>Threads • Log in</title>" (specific to non-existent users)

When a user doesn't exist, Threads redirects to a login page with the
title "Threads • Log in". Valid user profiles have titles like
"Username (@username) • Threads, Say more".

Tested with:
- Invalid user (impossibleuser12345): Correctly not found
- Valid user (zuck): Correctly found

This fixes the false positive issue where non-existent Threads profiles
were being reported as found.
2025-10-04 17:22:50 +05:30
shreyasNaik0101 3079e7a218 fix(ci): Use merge-base for correct target validation 2025-10-04 15:25:30 +05:30
Abhyuday K Hegde 5cd769c2f4
Remediate False Positives for CyberDefenders 2025-10-04 15:12:20 +05:30
Abhyuday K Hegde 977ad5c1a4
Remediate False Positive for SlideShare 2025-10-04 14:48:37 +05:30
Abhyuday K Hegde 57a0ccef38
Remediate False Positive for Roblox 2025-10-04 14:30:40 +05:30
dollaransh17 94c013886a fix(sites): Remove BoardGameGeek due to incompatible detection
BoardGameGeek cannot be reliably detected with Sherlock's current capabilities:

- Original HTML detection: Returns false positives
- API endpoint approach: The API returns status 200 for both valid and invalid users
  - Invalid user: Returns exactly '[]'
  - Valid user: Returns JSON containing '[]' substrings (e.g., "adminBadges":[])

Since Sherlock's 'message' errorType uses substring matching, it incorrectly
identifies valid users as "not found" when checking for '[]' in the response.

The site's API response format is fundamentally incompatible with Sherlock's
detection methods (message/status_code/response_url), so removal is the only
viable solution to prevent false positives and false negatives.

Addresses false positive issue originally reported in testing.
2025-10-04 11:33:27 +05:30
dollaransh17 c5e209d78e fix(sites): Implement BoardGameGeek API detection as suggested
Using the API endpoint suggested by akh7177:
https://api.geekdo.com/api/users?username={}

However, there's an edge case where valid users contain empty arrays
in their JSON response (adminBadges[], userMicrobadges[], supportYears[])
which causes Sherlock's substring matching to incorrectly flag them
as 'not found' when looking for the '[]' error pattern.

The API correctly returns:
- Valid user: JSON object with user data (but contains [] substrings)
- Invalid user: Exactly '[]' (2 characters total)

This needs further refinement to distinguish between the exact '[]'
response vs JSON containing '[]' substrings.
2025-10-04 11:23:55 +05:30
dollaransh17 3e653c46b0 fix(sites): Remove BoardGameGeek - unreliable detection
BoardGameGeek returns identical pages for both existing and non-existing
users, making reliable username detection impossible with HTTP-based
methods. The site likely uses JavaScript to load user-specific content
dynamically.
2025-10-04 03:12:47 +05:30
dollaransh17 91f3b16993 fix(sites): Update BoardGameGeek URL structure and detection method
BoardGameGeek changed from /user/{} to /profile/{} URL structure.
Also updated from message to status_code detection as the site
no longer returns clear error messages for non-existent users.
2025-10-04 02:55:57 +05:30
obiwan04kanobi 0f3df0f4da **PR description:**
This PR adds AWS Skills Profile to Sherlock’s supported sites in data.json. The configuration uses a unique substring (`shareProfileAccepted":false`) for reliable detection of non-existent usernames, addressing the challenge of JavaScript-rendered error messages.
- Site details and detection logic follow Sherlock’s contributing guidelines and Code of Conduct.
- No changes to core logic; only a new site entry.
- Reviewed for schema compliance and duplicate key cleanup as noted.
2025-10-03 13:46:53 +05:30
dollaransh17 0e7219b191 Security Fix: Add timeout parameters to HTTP requests
This fix addresses a critical security vulnerability where HTTP requests
could hang indefinitely, potentially causing denial of service.

Changes:
- Added 10-second timeout to version check API call
- Added 10-second timeout to GitHub pull request API call
- Added 30-second timeout to data file downloads (larger timeout for data)
- Added 10-second timeout to exclusions list download

Impact:
- Prevents infinite hangs that could freeze the application
- Improves user experience with predictable response times
- Fixes security issue flagged by Bandit static analysis (B113)
- Makes the application more robust in poor network conditions

The timeouts are conservative enough to work with slow connections
while preventing indefinite blocking that could be exploited.
2025-10-03 13:41:43 +05:30
Paul Pfeister 1d2c4b134f
Merge pull request #2570 from shreyasNaik0101/fix/remediate-applediscussions
fix(sites): Remediate false positive for Apple Discussions
2025-10-02 20:30:57 -04:00
shreyasNaik0101 b245c462c9 fix(sites): Remediate false positive for Apple Discussions 2025-10-03 05:56:52 +05:30
shreyasNaik0101 876e58b159 fix(sites): Remediate false positive for Blitz Tactics 2025-10-03 05:45:43 +05:30
Paul Pfeister 66d9733da7
Merge pull request #2565 from shreyasNaik0101/fix/remediate-mydramalist
fix(sites): Remediate false positive for Mydramalist
2025-10-02 19:40:47 -04:00
Paul Pfeister c55deab3a2
Merge pull request #2561 from shreyasNaik0101/fix/remediate-deviantart
fix(sites): Remediate false positive for DeviantArt
2025-10-02 19:37:00 -04:00
Paul Pfeister edcb697793
Merge pull request #2564 from shreyasNaik0101/fix/remediate-allmylinks
fix(sites): Remediate false positive for AllMyLinks
2025-10-02 19:36:43 -04:00
shreyasNaik0101 d314d75db1 fix(sites): Remediate false positive for Mydramalist 2025-10-03 04:43:05 +05:30
shreyasNaik0101 c89a52caf7 fix(sites): Remediate false positive for AllMyLinks 2025-10-03 04:25:46 +05:30
Paul Pfeister 9c18cfe273
Merge pull request #2563 from sherlock-project/chore/update-co
chore: update code owners
2025-10-02 18:25:59 -04:00
shreyasNaik0101 779d4c33f4 fix: Remove username_unclaimed as requested 2025-10-03 03:55:03 +05:30
Paul Pfeister 072c24687b
Merge pull request #2558 from hanjm-github/master
feat: Add some popular website in Korea
2025-10-02 18:22:42 -04:00
Paul Pfeister b811b2bd47
chore: update code owners 2025-10-02 18:21:20 -04:00
shreyasNaik0101 355bfbd328 fix(sites): Remediate false positive for DeviantArt 2025-10-03 00:42:07 +05:30
JongMyeong HAN 7b3632bdad
Add comment to site 'namuwiki'
Co-authored-by: Paul Pfeister <code@pfeister.dev>
2025-10-03 04:00:41 +09:00
Ethan Zhang 4fe41f09ff Removed duplicate Bluesky entry in data.json 2025-10-02 12:42:47 +10:00
JongMyeong HAN cd7c52e4fa
Feat: Add tistory 2025-10-01 00:44:55 +09:00
JongMyeong HAN 86140af50e
feat: Add SOOP 2025-10-01 00:44:02 +09:00
JongMyeong HAN e5cd5e5bfe
feat: Add namuwiki 2025-10-01 00:43:21 +09:00
JongMyeong HAN dc89f1cd27
feat: Add dcinside 2025-10-01 00:41:23 +09:00
Paul Pfeister 388a1e06d4
Merge pull request #2459 from kareemeldahshoury/Issue#2442
Fix Issue #2442: Added support for Aparat
2025-09-20 20:47:37 -04:00
Paul Pfeister 61eeeb7876
Merge branch 'master' into Issue#2442 2025-09-20 20:45:09 -04:00
Paul Pfeister df7da4288c
fix(ci): scoping 2025-09-20 20:44:38 -04:00
Paul Pfeister 70896f1da4
Merge branch 'master' into Issue#2442 2025-09-20 20:26:14 -04:00
Paul Pfeister 0a38cad926
fix(ci): issue write permission 2025-09-20 20:24:41 -04:00
Paul Pfeister 1e38fb6f7b
Merge branch 'master' into Issue#2442 2025-09-20 20:21:48 -04:00
Paul Pfeister 9b3dc3e581
fix(ci): issue write permission 2025-09-20 20:21:28 -04:00
Paul Pfeister 37b30602fd
Merge branch 'master' into Issue#2442 2025-09-20 20:12:21 -04:00
Paul Pfeister 7afdee4c58
fix: incorrect method 2025-09-20 20:09:44 -04:00
Paul Pfeister d4d8e01e31
chore: remove dead site
Fixes: #2433
2025-09-20 19:45:34 -04:00
Paul Pfeister e5e0da00fe
Merge pull request #2549 from sherlock-project/add/instapaper
feat: add instapaper
2025-09-20 18:13:30 -04:00
Paul Pfeister dc61cdc7a4
chore: set request method 2025-09-20 18:10:33 -04:00
Paul Pfeister 0fa2e1afc7
chore: cleanup everything 2025-09-20 18:09:44 -04:00
Paul Pfeister 7ca90ba728
ci: test result summarization 2025-09-20 18:06:25 -04:00
Paul Pfeister cd6fa5bb30
ci: fix the thing 2025-09-20 18:04:42 -04:00
Paul Pfeister fa05641661
ci: improve validation 2025-09-20 17:43:00 -04:00
Paul Pfeister 97ba4e8616
fix(ci): validation issue 2025-09-20 15:39:01 -04:00
Paul Pfeister 9882478fb5
feat: add instapaper 2025-09-20 15:05:44 -04:00
Paul Pfeister 9f5b7e1846
fix(validation ci): parsing and presentation 2025-09-20 15:02:43 -04:00
Paul Pfeister 05afac7082
Merge pull request #2548 from sherlock-project/feature/automatic-testing
Automatically test modified targets upon PR
2025-09-20 14:47:38 -04:00
Paul Pfeister ae362b0f02
ci: automatically validate modified targets on pr 2025-09-20 14:44:19 -04:00
Paul Pfeister 435540606e
chore: add typedef 2025-09-20 13:49:29 -04:00
Paul Pfeister 96aa12c140
Merge pull request #2546 from rezocrypt/add-laracast-support
Added Laracast support
2025-09-20 13:38:21 -04:00
My Name 9560355a7c Added Laracast support 2025-09-18 10:23:09 +04:00
Paul Pfeister b44ac231c1
chore: move SSOT to pyproject.toml
Co-authored-by: ByteXenon <125568681+ByteXenon@users.noreply.github.com>
2025-09-17 17:47:45 -04:00
Paul Pfeister 7ff3924f0b
ci(exclusions): ensure unstaging and removal of tmp 2025-09-17 17:17:49 -04:00
Paul Pfeister 39c3729524
ci(exclusions): fix loss of untracked list 2025-09-17 14:09:15 -04:00
Paul Pfeister faddcbd15f
ci(exclusions): fix loss of untracked list 2025-09-17 14:03:51 -04:00
Paul Pfeister 78a2d309d1
ci(exclusions): fix loss of untracked list 2025-09-17 13:55:42 -04:00
Paul Pfeister 35940e7584
fix: ignore exclusions list on parameterization for false positive tests 2025-09-17 13:44:02 -04:00
Paul Pfeister 524415b5d5
chore: bump to 0.16.0 2025-09-15 22:03:23 -04:00
Paul Pfeister 8882310450
feat: honor automatic exclusions list 2025-09-15 21:56:54 -04:00
Paul Pfeister 6d15f1319e
ci: fix exclusions updater (again) 2025-09-15 21:29:20 -04:00
Paul Pfeister 69d3308c71
ci: fix exclusions updater 2025-09-15 21:24:10 -04:00
Paul Pfeister 5c57b20936
ci: fix exclusions updater 2025-09-15 21:17:09 -04:00
Paul Pfeister e09319f29f
Merge pull request #2536 from sherlock-project/feature/username_fuzz
Return support for F+/F- detection via fuzzing
2025-09-15 21:05:35 -04:00
Paul Pfeister b15242881e
ci: automatically update exclusions list 2025-09-15 21:03:17 -04:00
Paul Pfeister e02507e5a1
test: set upper bound on f+ fuzz 2025-09-15 20:31:26 -04:00
Paul Pfeister 284662e156
Merge pull request #2501 from Davis-3450/add/platzi
add: platzi.com
2025-09-14 17:24:49 -04:00
Davis 1b9f823cef
Merge branch 'master' into add/platzi 2025-09-14 16:12:09 -05:00
Moshi f0f37d841c bugfix: update platzi
- "username_claimed" is now set to "freddier" (the most popular user, just in case)
- error code and request method are now explicit.
- added trailing slash for consistency
2025-09-14 16:03:32 -05:00
Pierre-Yves Lapersonne 58b20db9f1
feat: add `outgress.com` in supported web sites (#2426)
Closes #2426

Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:21:33 -04:00
Pierre-Yves Lapersonne a98a113a4b
feat: add `opencollective.com` in supported web sites (#2430)
Closes #2430

Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:21:32 -04:00
Pierre-Yves Lapersonne 164d01d163
feat: add `linuxfr.org` in supported web sites (#2427)
Closes #2427

Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:21:32 -04:00
Pierre-Yves Lapersonne ddd94474b8
feat: add `pixelfed.social` in supported web sites (#2425)
Closes #2425

Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:21:32 -04:00
Pierre-Yves Lapersonne 541b023b7f
feat: add `mamot.fr` in supported web sites (#2424)
Closes #2424

Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:21:32 -04:00
Pierre-Yves Lapersonne 9b502d9245
feat: new targets (9), minor cleanup
Closes #2421 (added support for site)
Closes #2422 (added support for site)
Closes #2423 (added support for site)
Closes #2424 (added support for site)
Closes #2425 (added support for site)
Closes #2426 (added support for site)
Closes #2427 (added support for site)
Closes #2429 (added support for site)
Closes #2430 (added support for site)

Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
Singed-off-by: Paul Pfeister <code@pfeister.dev>
2025-09-14 02:16:16 -04:00
Pierre-Yves Lapersonne b9c352fb7c
style: clean file by removing useless whitespace
Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:14:53 -04:00
Pierre-Yves Lapersonne 48ef668e1e
feat: add `write.as` in supported web sites (#2422)
Closes #2422

Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:14:53 -04:00
Pierre-Yves Lapersonne 481c39ace3
feat: add `speakerdeck.com` in supported web sites
Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:14:52 -04:00
Pierre-Yves Lapersonne 6b9305250d
feat: add `framapiaf.org` in supported web sites
Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:14:52 -04:00
Pierre-Yves Lapersonne 87bd15f927
style: remove useless empty line
Signed-off-by: Pierre-Yves Lapersonne <dev@pylapersonne.info>
2025-09-14 02:14:52 -04:00
Paul Pfeister db23ae933f
Merge pull request #2417 from jasontenpenny/master
Sort Bluesky Alphabetically
2025-09-14 01:42:14 -04:00
Paul Pfeister ad76b3685f
chore: simplify test names 2025-09-14 01:39:37 -04:00
Paul Pfeister 34cb23bc6e
test: itemize f+/f- 2025-09-14 01:36:21 -04:00
Paul Pfeister 702bfee988
chore: deprecate 3.8, 3.9 2025-09-14 01:10:52 -04:00
Paul Pfeister dfe8b1599d
test: prepare false negative detection base 2025-09-14 00:57:55 -04:00
Paul Pfeister ca094d8264
test: prepare false positive detection base 2025-09-14 00:39:35 -04:00
Paul Pfeister 5113dcfb36
Merge pull request #2493 from MR-VL/master
Fix Issue #2492 and #2494 | Added support for Pychess | Remove TorrentGalaxy
2025-09-13 21:21:00 -04:00
MR-VL d3f4c65459
remove trailing comma for cashapp breaking TOX 2025-09-13 18:15:23 -05:00
MR-VL 2504f238e5
Merge branch 'master' into master 2025-09-13 17:39:57 -05:00
Paul Pfeister 9646055560
fix(manifest): schema non-compliance 2025-09-13 18:30:08 -04:00
Paul Pfeister 80d4abae34
Merge pull request #2446 from S1lvus/master
Add support for CashApp
2025-09-13 18:25:55 -04:00
Paul Pfeister 19ae05d68a
Merge pull request #2460 from rskbansal/fix_minecraft
Fixed Minecraft
2025-09-13 18:08:53 -04:00
Paul Pfeister 5c62b2ab1b
Merge pull request #2483 from MaxwellOldshein/feat/add-playstrategy-support
Fix Issue #2475: Added support for Playstrategy
2025-09-13 18:06:26 -04:00
Paul Pfeister 6cc4d9e0c7
Merge branch 'master' into feat/add-playstrategy-support 2025-09-13 18:04:18 -04:00
Paul Pfeister 1ddfc08d7d
Merge pull request #2484 from MaxwellOldshein/feat/add-blitz-tactics-support
Fix Issue #2474: Added support for Blitz Tactics
2025-09-13 18:02:12 -04:00
Paul Pfeister cca68bb9ab
Merge pull request #2513 from akamayu-ouo/site/plurk
Add support for Plurk
2025-09-13 17:49:31 -04:00
Paul Pfeister d6db0f7d79
Merge #2516 (Tumblr) 2025-09-13 17:48:19 -04:00
Craig London d60562130c readmefixes: Fix typo 2025-09-13 17:27:25 -04:00
Craig London aa1945b017 readmefixes: HTML fixes 2025-09-13 17:27:25 -04:00
[Tulsi Shetty] dafcaec192 feat: Tumblr added 2025-08-16 18:42:19 +05:30
akamayu-ouo 3c9eda75e9
Add Plurk 2025-08-09 14:08:56 +00:00
Moshi 8635d68864 add: platzi.com 2025-07-16 14:48:16 -05:00
MR-VL 6e7b3cecb8 Syntax Fixes in README.md
remove unmatched closing </a> tag, and fix indent
add quotes to <p align=center> LN:1 to make it valid HTML
fix type from programmaticaly to programmatically
2025-07-06 18:02:24 -05:00
MR-VL 1e12c3f7a6 Remove TorrentGalaxy 2025-07-06 16:35:31 -05:00
MR-VL 9e40e0a0f4 Add support for Pychess 2025-07-06 16:27:59 -05:00
manjushsh 4706323976 data: add hive blog 2025-06-27 20:05:01 +05:30
manjushsh 4721c7f553 data: Add code sandboxio 2025-06-27 19:42:23 +05:30
Maxwell Oldshein c82c00650a Add Blitz Tactics support 2025-06-26 15:26:57 -04:00
Maxwell Oldshein 9e54e68da5 Add Playstrategy support 2025-06-26 15:10:44 -04:00
Matheus Felipe 4423230c11
Fix stray character typo in README (#2462) 2025-05-06 06:55:10 -03:00
Kotaro Fujii a04fbe6ccc Fix stray character typo in README 2025-05-06 18:29:52 +09:00
Rhythm Bansal f599ae5ff1
fixed minecraft 2025-04-30 02:23:06 +05:30
kareemeldahshoury de81f38622 Fix Issue #2442: Added support for Aparat 2025-04-29 15:25:31 -05:00
Siddharth Dushantha a40944d336
Merge pull request #2435 from apify/actorize
Apify will sponsor your project: Sherlock Actor on Apify infrastructure
2025-04-23 09:48:52 +02:00
S1lvus e0f184f263
Removed extra spaces 2025-04-07 20:31:17 -04:00
S1lvus 6c1623a3ad
Added CashApp into the site list.
This adds username search for the CashApp financial platform.
2025-04-07 20:28:28 -04:00
Matheus Felipe 4428b15162
Add star history section in README.md (#2438) 2025-03-20 21:53:09 -03:00
Matheus Felipe 2adc96833a
docs: add star history section in README.md
This is to have the section listed in the GitHub index
2025-03-20 21:50:08 -03:00
Adam Kliment b7ce20b2ca feat: Actor definition, Actor usage to README 2025-03-20 11:54:57 +01:00
Jason Tenpenny 5e3828882e
Sort Bluesky Alphabetically
moved the Bluesky config to its proper alphabetical location so it can be found easier
2025-03-02 22:40:32 -06:00
Paul Pfeister 78cba6b7ca
chore: add info regarding experienced problem 2025-02-17 01:07:07 -05:00
Paul Pfeister 9be92b9834
Merge pull request #2404 from MR-VL/master
Remove ask.fm + fix instagram  middleware
2025-02-17 00:13:21 -05:00
Paul Pfeister 53cbd332ca
chore: cleanup dead targets 2025-02-17 00:07:18 -05:00
Paul Pfeister 2ff2836159
chore: document unusual behavior
Target will fail to provide a response for unclaimed queries rather than an error
2025-02-16 23:54:29 -05:00
Paul Pfeister 0d008b109e
fix: v0 f+ 2025-02-16 23:33:04 -05:00
MR-VL a29faa8288
Fix instagram 2025-02-04 21:37:13 -06:00
MR-VL 809f8ba6c4
Remove askfm 2025-02-04 21:26:04 -06:00
Paul Pfeister 1912cbdea4
fix: manifest encoding error on Windows 2025-02-03 03:38:17 -05:00
Paul Pfeister b1fb7ac2ff
chore: add PR note to --json help 2025-02-03 03:02:22 -05:00
Paul Pfeister b5726e5edf
Merge pull request #2286 from sk337/patch-1
add v0.dev to data.json
2025-02-03 03:01:06 -05:00
Paul Pfeister 9eb100c819
Merge branch 'master' into patch-1 2025-02-03 03:00:53 -05:00
Paul Pfeister 86387d0baf
fix: validation error message 2025-02-03 03:00:04 -05:00
Paul Pfeister c6f9e2eac9
fix: validation method typo 2025-02-03 02:54:12 -05:00
Paul Pfeister 73df548532
fix: twitter f+ 2025-02-03 02:53:35 -05:00
Paul Pfeister ae87699824
fix: fiverr/babyru f+ 2025-02-03 02:51:22 -05:00
Paul Pfeister 8568ef7d99
fix: twitch f+ 2025-02-03 02:37:06 -05:00
Paul Pfeister c6f7a99b1c
fix: tldr legal f+ 2025-02-03 02:01:14 -05:00
Paul Pfeister b5bd536e6b
fix: slideshare f+ 2025-02-03 01:55:46 -05:00
Paul Pfeister d029af3e89
fix: shpock f+ 2025-02-03 01:51:54 -05:00
Paul Pfeister af2bb98901
fix: producthunt f+
Co-authored-by: Regan Bell <reganbell@gmail.com>
2025-02-03 00:51:04 -05:00
Paul Pfeister 68c4edf8b6
fix: giphy f+ 2025-02-03 00:40:05 -05:00
Paul Pfeister 300d6eda21
fix: airpilot f+
Seems to be defunct.
2025-02-03 00:35:58 -05:00
Paul Pfeister 33b567d453
fix: 8tracks f+ 2025-02-03 00:35:12 -05:00
Paul Pfeister c779d21c13
Merge pull request #2292 from Pasanlaksitha/master
Add Hugging Face data.json
2025-02-03 00:26:17 -05:00
Paul Pfeister d818c5ebf2
Merge pull request #2312 from SOGeKING-NUL/master
Adding DigitalSpy
2025-02-03 00:22:26 -05:00
Paul Pfeister 072b581f98
Merge pull request #2394 from ibnaleem/bluesky
Add Bluesky Support
2025-02-02 23:48:46 -05:00
Paul Pfeister 2de353d8d6
fix: over-restrictive fail cond 2025-02-02 23:45:27 -05:00
Paul Pfeister ca2f19ae52
fix: EOF 2025-02-02 23:43:50 -05:00
Paul Pfeister b8bdfd8601
Merge pull request #2381 from brantonb/master
Add support for omg.lol
2025-02-02 23:42:42 -05:00
Paul Pfeister a985a0891e
Merge pull request #2383 from brantonb/strava
Fix Strava false positives
2025-02-02 23:38:30 -05:00
Paul Pfeister a688e268b3
Merge pull request #2393 from joeyagreco/joey/fix-pypi-url
Fix PyPi URL
2025-02-02 23:32:43 -05:00
Paul Pfeister 3a7384e5f1
fix: pypi user-friendly url 2025-02-02 23:27:57 -05:00
ibnaleem ca17c39172
add bsky.app 2025-01-20 15:02:43 +00:00
joeyagreco 55f0628c2b fixed pypi url 2025-01-19 14:39:45 -05:00
joeyagreco 276167be9c Revert "fixed pypi url"
This reverts commit d87f4f2b60.
2025-01-19 14:37:36 -05:00
joeyagreco d87f4f2b60 fixed pypi url 2025-01-19 14:35:08 -05:00
Branton Boehm 1684fbf866 Fix Strava false positives 2024-12-25 18:21:44 -08:00
Branton Boehm c0c5d829e2 Add support for omg.lol 2024-12-25 12:34:41 -08:00
Utsav Jana 0a0e4fe606 add the regexCheck for DigitalSpy 2024-12-06 19:16:53 +05:30
Utsav Jana 979f17cf3b add the regexCheck for DigitalSpy 2024-12-06 19:14:39 +05:30
Utsav Jana fe6e2e57c3 Adding DigitalSpy 2024-12-06 19:13:25 +05:30
Paul Pfeister 2c303a2869
fix: WAF hit list 2024-11-13 16:53:59 -05:00
Paul Pfeister 0f395d037b
fix: F+s 2024-11-13 16:53:40 -05:00
Paul Pfeister 839eab1384
chore: add cloudfront waf hit 2024-11-11 22:25:47 -05:00
Paul Pfeister 98fbd525ee
Fix #2355
(Regression introduced by #1520)
2024-11-11 20:33:27 -05:00
Paul Pfeister 046c2957f3
chore: expand WAF hit list 2024-11-11 20:05:20 -05:00
Paul Pfeister 18bae485ae
Merge pull request #2287 from ntexe/master
fix #2242
2024-11-11 20:03:17 -05:00
Paul Pfeister 46023a86b6
Merge pull request #2285 from rsb-23/master
Fixed false positives #2273
2024-11-11 19:48:37 -05:00
Paul Pfeister 6f3b89c98a
Merge branch 'master' into master 2024-11-11 19:45:32 -05:00
Paul Pfeister 0b7d925b50
fix: F-/F+ Generic 2024-11-11 19:44:14 -05:00
Paul Pfeister 785346c12d
Merge pull request #2277 from sherlock-project/2275-PEP-561
Comply with PEP 561
2024-11-11 17:19:19 -05:00
Paul Pfeister a998ec309c
fix: missing Optional typing import 2024-11-11 17:16:31 -05:00
Paul Pfeister 557394dc56
Merge pull request #2278 from sherlock-project/adjust-readme
docs: update readme for fedora, parrot, 24.04
2024-11-11 17:10:12 -05:00
Paul Pfeister 5990cf1e8e
docs: cleanup install ref 2024-11-11 17:06:46 -05:00
Paul Pfeister cf393b8fec
Merge pull request #2339 from bytexenon/archive_org_fix
fix: add additional error message check for archive.org downtime
2024-11-11 16:55:50 -05:00
Paul Pfeister 662d80e1a6
Merge pull request #2356 from bytexenon/pr-option
Overload `--json` to fetch via PR number
2024-11-11 16:47:07 -05:00
ByteXenon 270fbf6473 Overload `--json` to accept pull request data and remove `--pull-request` parameter 2024-11-06 00:26:14 -07:00
Paul Pfeister 06b062c122
Update test to use still-present target 2024-11-04 20:49:22 -05:00
Paul Pfeister 6fa603981d
Remove bodybuilding[.]com forum
Forum defunct. Not added to removed list as the site will no longer
exist.
2024-11-04 20:46:03 -05:00
Paul Pfeister 8f5d601758
Merge pull request #2267 from sherlock-project/2266-deprecate-support-for-python-38
Deprecate Python 3.8
2024-11-04 20:33:42 -05:00
Paul Pfeister 08aad5a755
Merge pull request #2357 from bytexenon/version-issue-templates
Add "Package version" field to issue templates
2024-11-04 18:30:39 -05:00
ByteXenon 3ffb514f71 Make 'version' field required in Bug Report template 2024-11-04 04:49:57 -07:00
ByteXenon 24f64b3e32 Add version number field to Bug Report issue template 2024-11-04 04:46:59 -07:00
ByteXenon e84c5fce37 Add `--pull-request` [`-pr`] parameter 2024-11-04 02:22:05 -07:00
Paul Pfeister e94e00af53
Revert "Merge pull request #2340 from mikebgrep/master"
This reverts commit 185478cf8e, reversing
changes made to 3804fd9a91.

Some patterns seem to be incorrect
2024-11-01 20:33:39 -04:00
Paul Pfeister 185478cf8e
Merge pull request #2340 from mikebgrep/master
Fix Invalid usernames for number of pages
2024-11-01 20:24:27 -04:00
Paul Pfeister 98d8120ccd
Merge branch 'master' into master 2024-11-01 20:21:31 -04:00
Paul Pfeister 3804fd9a91
Merge pull request #2335 from rskbansal/master
Fixed Twitter(X)
2024-11-01 19:57:37 -04:00
Paul Pfeister bd46baa639
fix: 8tracks
Use username availability endpoint from regflow with predictable
response language (en-us).

Referenced by #2318
Fixes #2332
Closes #2333 (removes target rather than fixes)
2024-11-01 19:44:48 -04:00
Paul Pfeister c64e795447
Merge pull request #2291 from Suramyavns/master
fixed speedrun site support #2288
2024-11-01 05:02:35 -04:00
Paul Pfeister 0e5769154c
Merge pull request #2323 from Nuung/master
Add support for velog
2024-11-01 04:50:06 -04:00
Paul Pfeister d4b57510f1
Merge pull request #2328 from yuzicodes/add-rarible
Add site rarible.com
2024-11-01 04:42:54 -04:00
Aalim Sheikh b06fb4e425
Update sherlock_project/resources/data.json
Co-authored-by: Paul Pfeister <code@pfeister.dev>
2024-11-01 14:09:04 +05:30
Paul Pfeister 1c2e99a5b3
Merge pull request #2325 from anujatappeta/corrected-function-calling
commiting to correct function call
2024-11-01 04:33:58 -04:00
Paul Pfeister 43e543acae
Merge pull request #2326 from alokranjan609/librarything-detection-fix
Change the errorMsg for Librarything
2024-11-01 04:29:58 -04:00
Paul Pfeister 3f1f2534a3
Update tests/sherlock_interactives.py 2024-11-01 04:29:23 -04:00
Paul Pfeister 821062bb81
Merge pull request #2310 from nktkhndlwl/vlr-support
add VLR.gg support
2024-11-01 04:05:39 -04:00
Paul Pfeister 7cd9f2acb0
Merge pull request #2283 from gtkacz/2248-exophase_support
Adding support for exophase via `data.json` for #2248
2024-11-01 04:00:47 -04:00
Paul Pfeister 7b7a0d2c8e
Merge pull request #2316 from MR-VL/master
Add support for Atcoder
2024-11-01 03:39:28 -04:00
Paul Pfeister f50d0e6c41
Merge pull request #2349 from NOMADE55/add-topcoder-bgg-small-ecommerce
Add BoardGameGeek and Small Ecommerce Platforms
2024-11-01 03:22:33 -04:00
Lucas Terracino bbe9e93164 Add support for Tiendanube 2024-10-22 14:38:09 -03:00
Lucas Terracino beb57d2e49 Add support for Empretienda 2024-10-22 14:38:01 -03:00
Lucas Terracino a03aa3157f Add support for BoardGameGeek 2024-10-22 14:28:14 -03:00
Lucas Terracino 4deba5f147 Add support for Topcoder 2024-10-22 14:11:51 -03:00
Bytexenon af4c08a08b
fix: remove "Other" from archive.org downtime message check 2024-10-20 07:03:08 -07:00
mikebgrep deb1936027 add regexCheck for the pages that does not have related to the issue with long not valid username 2024-10-20 16:12:37 +03:00
Bytexenon fb52343aa3
fix: add additional error message check for archive.org downtime 2024-10-20 05:27:10 -07:00
Rhythm Bansal fdf3655e63
fixed `urlProbe` for Twitter by adding an alternative endpoint 2024-10-17 22:18:52 +05:30
Aalim Sheikh d83e7c1652
Add site rarible.com 2024-10-11 20:35:29 +05:30
Alok 8e0c7eff17 Change the errorMsg for Librarything 2024-10-11 11:02:57 +05:30
anuja b7406919dc commiting to correct function call 2024-10-11 07:53:59 +05:30
nktkhndlwl 656abbbbf8 fix errorType 2024-10-10 20:46:54 +05:30
Nuung ef751d34f2 modify: velog's username_claimed value 2024-10-09 19:11:51 +09:00
Nuung 4ef9e6b0de modify: I forgot to adding @ 2024-10-09 18:52:36 +09:00
Nuung ecd59455b0 Add support for velog 2024-10-09 18:31:06 +09:00
MR-VL 15e6924338
Add support for Atcoder 2024-10-05 21:47:45 -05:00
Utsav Jana ad86a8b954 Adding DigitalSpy 2024-10-02 22:25:26 +05:30
Niket Khandelwal 61fdb6e206 add VLR.gg support 2024-10-02 00:50:33 +05:30
Pallavi Kathait 193de54b6d
Update site-list.py
These changes improve readability and maintain the functionality of the original code.
2024-09-29 21:31:19 +05:30
Pasan Laksitha b6c33d2901 Add Hugging Face platform details to data.json for Sherlock project. 2024-09-11 10:16:25 +05:30
suramyavns b65b03fe63 removed duplication 2024-09-11 07:49:29 +05:30
suramyavns 5193ab8a97 fixed speedrun site support 2024-09-10 14:18:46 +05:30
sk337 84965712f6
Update data.json 2024-09-05 13:09:41 -07:00
sk337 5f0d55bcfa
fix requested changes 2024-09-05 13:07:13 -07:00
ntexe 277d19816e fix #2242 2024-09-05 16:03:08 +03:00
sk337 a7b370bc3d
add unclaimed username to v0.dev 2024-09-04 13:11:30 -07:00
sk337 efd765eba7
Update data.json 2024-09-04 13:06:22 -07:00
rsb-23 192e2c333e Fixed false positives #2273
- Updated user-agent in header and removed duplicate
-
2024-09-03 21:04:10 +05:30
gtkacz 89b4cec3cb Adding support for exophase via `data.json` for #2248 2024-09-02 15:16:57 -03:00
Paul Pfeister 4660afb7d8
Fix implicit optional (PEP 484)
Co-authored-by: GuardianWang <31812793+GuardianWang@users.noreply.github.com>
2024-08-30 01:21:08 -04:00
Paul Pfeister e9eb7d32ce
docs: update readme for fedora, parrot, 24.04 2024-08-28 00:25:55 -04:00
ntexe f7075e1b64 Restore Fanpop
Cleaned up commit for sherlock-project/sherlock#2269
2024-08-27 23:08:40 -04:00
Paul Pfeister f32fdaa93a
Merge pull request #2272 from PeterDaveHello/patch-1
Remove not needed `apt-get update` in Dockerfile
2024-08-27 22:51:59 -04:00
Paul Pfeister 1c8e3f8142
Merge branch 'add-kaskus' 2024-08-27 22:45:01 -04:00
Paul Pfeister 298161114b
fix: indentation 2024-08-27 22:44:50 -04:00
Paul Pfeister 0d0335bca0
Comply with PEP 561 2024-08-27 22:32:48 -04:00
paperbenni 1e2e380876 add site Gitea.com 2024-08-27 19:37:35 +02:00
L0mbart bceb625984
Update data.json
add kaskus site
2024-08-27 13:17:00 +07:00
Peter Dave Hello a5dda7ae91
Remove not needed `apt-get update` in Dockerfile
There's no need to wait and waste the time and bandwidth to wait for `apt-get update` for `pip3 install` ;)
2024-08-27 02:37:23 +08:00
Paul Pfeister 9e111a334b
Merge pull request #2259 from Txbias/codeforce-support
Remove Codeforces from removed-sites.md
2024-08-23 01:37:43 -04:00
Paul Pfeister 74a3576132
Merge remote-tracking branch 'ntexe/master' 2024-08-23 01:31:41 -04:00
Paul Pfeister 0646063509
fix: file not found 2024-08-23 01:21:49 -04:00
Paul Pfeister c6c1f3eef7
Deprecate Python 3.8
Python 3.8 is nearing EOL, and it's being deprecated here to allow for
more ready dependency resolution between pandas and numpy, avoiding a
fatal import. Resolves #2266.
2024-08-23 01:15:47 -04:00
Siddharth Dushantha 47ab466d85
Merge pull request #2265 from MR-VL/master
remove ICQ.com
2024-08-22 16:04:01 -04:00
MR-VL 378967c2a5
remove ICQ 2024-08-21 15:10:04 -05:00
ntexe 2cc854bd6b You can now disable creation of a txt file 2024-08-21 14:01:22 +03:00
Txbias 4d83f057ac Removed Codeforces from the removed-sites.md file 2024-08-15 16:27:55 +02:00
Siddharth Dushantha 573ae6c488
Merge pull request #2254 from sherlock-project/fix-sync-json-data
updated sherlock path
2024-08-11 06:09:43 -04:00
Siddharth Dushantha fce4347a3c updated sherlock path 2024-08-11 12:07:39 +02:00
Siddharth Dushantha 7b2076c113
Merge pull request #2225 from Netail/feat/threads
feat: add Threads
2024-08-11 06:03:00 -04:00
Maikel 7e18e0eb4c
Merge branch 'sherlock-project:master' into feat/threads 2024-08-08 00:11:47 +02:00
Siddharth Dushantha 22100ceed3 fix merge conflict 2024-08-07 17:31:39 +02:00
Siddharth Dushantha 40102be04a
Merge pull request #2239 from sherlock-project/rm-old-dir
removed sherlock dir
2024-08-07 17:28:39 +02:00
Siddharth Dushantha 201ab43631 removed old sherlock dir 2024-08-04 13:41:48 +02:00
Maikel defd1740b8
Merge branch 'sherlock-project:master' into feat/threads 2024-08-02 09:43:58 +02:00
Netail 4544ddc219 fix: use Sec-Fetch-Mode 2024-07-29 21:37:41 +02:00
Paul Pfeister 7e87a88d71
chore: discord check via unauthed reg flow check 2024-07-28 00:14:57 -04:00
Maikel db4bb5ada6
fix: feedback 2024-07-22 19:37:00 +02:00
Paul Pfeister 09b324f7d4
chore: deactivate alik.cz 2024-07-22 00:33:31 -04:00
Paul Pfeister 35773d43da
Accomodate legacy client version checks 2024-07-09 20:15:52 -04:00
Netail eeda506990 feat: add Threads 2024-07-08 20:26:55 +02:00
Paul Pfeister cda65e3da5
Use temp manifest instead of symlink 2024-07-08 05:53:32 -04:00
Paul Pfeister d016276478
Update remote uri 2024-07-08 05:51:28 -04:00
Paul Pfeister 2a1e06975d
Update filepath to new module name 2024-07-08 05:44:26 -04:00
Paul Pfeister 930ed2ac7c
Merge branch '2130-torrequest' into release/0.15.0-rc2 2024-07-08 04:56:21 -04:00
Paul Pfeister 18367353df
Merge branch 'bump-version' into release/0.15.0-rc2 2024-07-08 04:45:14 -04:00
Paul Pfeister ba3952d86b
Merge branch 'feature/security-policy' into release/0.15.0-rc2 2024-07-08 04:43:51 -04:00
Paul Pfeister c5b25fa494
Merge branch '2207-specify-schema' into release/0.15.0-rc2 2024-07-08 04:43:37 -04:00
Paul Pfeister e1c4db4dab
Merge branch '2205-target-debug' into release/0.15.0-rc2 2024-07-08 04:37:55 -04:00
Paul Pfeister 12590137f5
Merge branch 'feature/run-tests-on-staging' into release/0.15.0-rc2 2024-07-08 04:37:50 -04:00
Paul Pfeister 2680cc85fb
Merge branch '2204-alert-if-script' into release/0.15.0-rc2 2024-07-08 04:37:42 -04:00
Paul Pfeister 9aa8242d92
Merge branch '2195-update-dockerfile' into release/0.15.0-rc2 2024-07-08 04:37:38 -04:00
Paul Pfeister c12304a71a
Merge branch 'package-collision' into release/0.15.0-rc2 2024-07-08 04:37:30 -04:00
Paul Pfeister cf7032dd99
Symlink to new manifest location
Clients that aren't yet updated will still rely on this location after
the move, and will fail unexpectedly. Symlink allows existing clients to
function as otherwise expected until they finally update.
2024-07-08 04:20:58 -04:00
Paul Pfeister f79bbfcdc1
Update message 2024-07-08 04:10:53 -04:00
Paul Pfeister e966b9c169
Add security policy 2024-07-08 02:31:17 -04:00
Paul Pfeister 27badf6b3d
Update command hint 2024-07-08 02:03:42 -04:00
Paul Pfeister bb9dd410da
SHERLOCK_ENV set 2024-07-08 01:42:04 -04:00
Paul Pfeister f1d4a841eb
Switch to snake_case 2024-07-08 01:36:24 -04:00
Paul Pfeister 80e61cd3be
Shrink error message 2024-07-08 01:34:20 -04:00
Paul Pfeister f9617d4f64
Address review wrt/snake_case 2024-07-08 01:30:32 -04:00
Paul Pfeister 04472af9c0
Fix workdir 2024-07-01 00:02:17 -04:00
Paul Pfeister 448da43bf7
Refresh Dockerfile 2024-06-30 23:59:36 -04:00
Paul Pfeister 2add15e92c
pipx -> pip 2024-06-30 23:13:24 -04:00
Paul Pfeister efc6b12c65
Make torrequest optional 2024-06-30 22:49:16 -04:00
Paul Pfeister 0ece8bf672
Except ImportErrors induced by legacy run method 2024-06-30 22:32:31 -04:00
Paul Pfeister 079f14ec46
Add --dump-response flag 2024-06-30 22:16:39 -04:00
Paul Pfeister cc57469a65
Return schema to manifest 2024-06-30 21:16:11 -04:00
Paul Pfeister 33db232493
Switch to tagged update checks 2024-06-30 21:01:42 -04:00
Paul Pfeister 99586a56cf
Prepare for tagged version checking 2024-06-30 20:45:30 -04:00
Paul Pfeister e3a4879fcd
Remove old version item 2024-06-29 18:50:24 -04:00
Paul Pfeister c71cb72a29
Add release branches to ci
Closes #2194
2024-06-29 00:49:30 -04:00
Paul Pfeister 501cb3dce2
Merge pull request #2206 from sherlock-project/temp
Remove ETSY and EUW from websites and add one.lt
2024-06-29 00:29:16 -04:00
slavran fff8feb1f6
Remove ETSY and EUW from websites and add one.lt 2024-06-29 00:26:51 -04:00
Paul Pfeister 5019e8a122
Merge pull request #2044 from RahalBhupathi/warframemarket
Added Warframe Market
2024-06-29 00:24:46 -04:00
Paul Pfeister 2d5217c56a
Revert "updated sites.ms with warframe.market entry"
This reverts commit db1e82c2f4.

Letting the ci update the list is just less work than dealing with a
3wm.
2024-06-29 00:24:02 -04:00
Paul Pfeister b42a58c86d
Update Warframe Market name 2024-06-29 00:23:59 -04:00
Paul Pfeister e33d595201
Merge pull request #2199 from Wicloz/master
New format for LeetCode profiles
2024-06-29 00:03:41 -04:00
Paul Pfeister 2016892e64
Remove torrequest dep
Not sure why it's not in my patch file, but I was removing via sed in my spec instead.
2024-06-28 23:39:38 -04:00
Paul Pfeister 44ad8f506a
Lint 2024-06-28 23:38:44 -04:00
Siddharth Dushantha cfa4097df9 removed support for tor 2024-06-26 21:57:11 +02:00
Wilco de Boer 32a55103e1
New format for LeetCode profiles 2024-06-26 20:52:40 +02:00
Paul Pfeister ab869ef974
Downgrade tox
CentOS Stream seems to lack tox >= 4, so 3 is needed for proper support.
Version can be bumped safely once the CentOS package for tox is updated.
2024-06-25 23:18:56 -04:00
Paul Pfeister 6d6e17c22f
Bump to 0.15.0 2024-06-25 00:15:32 -04:00
Paul Pfeister 267e5a6979
Adjust ci paths 2024-06-24 17:04:50 -04:00
Paul Pfeister ca781a3c3b
Rename importable module 2024-06-24 16:40:03 -04:00
Paul Pfeister 7f6f600fed
Update homepage 2024-06-24 16:26:07 -04:00
Paul Pfeister 61ef8eb3c3
Merge branch 'fix-false-positives' 2024-06-24 16:21:15 -04:00
Paul Pfeister 255c9dea8c
Swap yaml wildcard for workflow 2024-06-24 16:15:12 -04:00
Paul Pfeister c58b030456
Break linting env out 2024-06-24 16:06:33 -04:00
Paul Pfeister f86bdc1f84
Add yaml to triggers 2024-06-24 15:57:37 -04:00
Paul Pfeister 54f6bf3f79
Explicitly run tox lint testenv 2024-06-24 15:51:44 -04:00
Paul Pfeister c2805f82e8
Minor lint
Fixes hanging imports from #2151
Fixes bare f-string from #2178
2024-06-24 15:42:08 -04:00
Siddharth Dushantha 58df6bbc2b
Merge pull request #2187 from sherlock-project/fix-tests
Fixed tests due to broken sites
2024-06-24 19:30:56 +00:00
Paul Pfeister e8569b6f2c
Ignore test files 2024-06-24 15:21:15 -04:00
Paul Pfeister d3998faf59
Try devRant 2024-06-24 15:20:14 -04:00
Siddharth Dushantha a774a639d4 removed Pentestit + fixed tests 2024-06-24 12:27:06 +02:00
Siddharth Dushantha a9a62c2a11 removed Zhihu due to false positives 2024-06-24 12:14:08 +02:00
Siddharth Dushantha 54bebcf2f4 fixed LibraryThing false positive 2024-06-24 12:07:17 +02:00
Siddharth Dushantha 2746e2964a fixed freeCodeCamp false positive 2024-06-24 12:05:22 +02:00
Siddharth Dushantha 94b0afa07c
Merge pull request #2185 from sherlock-project/cleanup
fixed image
2024-06-20 14:58:39 +00:00
Siddharth Dushantha 3204e88a5b fixed image
GitHub has some issues replacing an image with the same name leads to no
changes
2024-06-20 16:57:29 +02:00
Siddharth Dushantha 42793796fd
Merge pull request #2184 from sherlock-project/cleanup
removed content thats on sherlockproject.xyz
2024-06-20 14:56:28 +00:00
Siddharth Dushantha 7021ec2449 removed content thats on sherlockproject.xyz 2024-06-20 16:54:43 +02:00
Siddharth Dushantha affbf5012e
Merge pull request #2181 from sherlock-project/testing-action
minor change to test site list syncing
2024-06-20 12:14:44 +00:00
Siddharth Dushantha 2ee484d696 minor change to test site list syncing 2024-06-20 14:07:28 +02:00
Siddharth Dushantha 8317cc1e29
Merge pull request #2180 from sherlock-project/fix-action
use a fork of the github action
2024-06-20 11:53:58 +00:00
Siddharth Dushantha 5ef6a2b8f3 use a fork of the github action
My fork does not delete all contents
2024-06-20 13:52:13 +02:00
Siddharth Dushantha 1a68d794d6
Merge pull request #2179 from sherlock-project/twitter-to-x
Renamed Twitter to X
2024-06-20 11:22:41 +00:00
Siddharth Dushantha 418b6a3409 Renamed Twitter to X
Mainly doing this to test if the new site list action works :)
2024-06-20 13:19:35 +02:00
Siddharth Dushantha 15180f92d0
Merge pull request #2178 from sherlock-project/new-site-list
Update site list to sherlockproject.xyz/sites
2024-06-20 11:13:24 +00:00
Siddharth Dushantha c5fa9d05ca Update site list to sherlockproject.xyz/sites
With these changes, the site list will be written to the
sherlock-project/sherlockproject.xyz repo where the docs and everything
is located. This way, we wont have to manually update the list on the
website.
2024-06-20 13:04:30 +02:00
Siddharth Dushantha b80f38dcb2
Merge pull request #2175 from sherlock-project/bugfix/codeowner-typo
Fix CODEOWNER transposition error
2024-06-17 00:50:44 +00:00
Paul Pfeister 8e2a492200
Fix transposition err 2024-06-16 20:45:02 -04:00
Siddharth Dushantha 25d445a6c5
Merge pull request #2174 from sherlock-project/fix-2158
Only execute GitHub action when needed
2024-06-17 00:40:10 +00:00
Siddharth Dushantha 923fa4cd0e
Merge pull request #2160 from sherlock-project/feature/better-docu
Update install docs
2024-06-17 00:37:26 +00:00
Siddharth Dushantha 579a3e794a Only execute GitHub action when needed
fixes #2158
2024-06-17 02:36:24 +02:00
Paul Pfeister 4e1e237c32
Add BlackArch install command
Co-authored-by: Siddharth Dushantha <siddharth.dushantha@gmail.com>
2024-06-16 20:33:41 -04:00
Paul Pfeister 4098b26b75
Remove BlackArch 2024-06-16 20:16:25 -04:00
Siddharth Dushantha 7443de18e9
Merge pull request #2159 from roxerj/2152-fix
[2152-fix] fixed issue #2152
2024-06-16 23:44:20 +00:00
Paul Pfeister 7b8aed8a5f
Update docs 2024-06-09 22:22:10 -04:00
juozapas.cypas 005e3ed096 [2152-fix] fixed issue #2152, where CyberDefenders returns false positive 2024-06-09 18:21:12 +03:00
Siddharth Dushantha d678908c00
Merge pull request #2157 from sherlock-project/new-logo
added new logo
2024-06-09 12:00:22 +00:00
Siddharth Dushantha 13eb6f0828 added new logo
The logo was created by the Kali Linux team and gave us permission to
use it.

In addition to the new logo, the ./images/ directory has been
moved to into ./docs/ in order to make the root directory of the project
cleaner. The old preview.png was never used as we had been using a
preview image that was hosted on user-images.githubuesrcontent.com. This
too has been changed so that we use the local copy instead
2024-06-09 10:39:50 +02:00
Paul Pfeister 3211b90b02
Merge #2127 to implement Poetry, pytest, and tox
Closes #2111 as its feature branch was the base of this PR's branch
Closes #2133 as no longer necessary
Closes #2147 as no longer necessary
2024-06-09 01:47:04 -04:00
Siddharth Dushantha ef124acf34
Merge pull request #2154 from ppfeister/feat/better-forms
Revamp issue forms
2024-06-04 19:19:40 +00:00
Paul Pfeister 8b9d4824f5
Simplify 2024-06-03 01:49:36 -04:00
Paul Pfeister c8aba1848b
Remove foreword 2024-06-03 01:48:13 -04:00
Paul Pfeister 174618cf6b
Improve bug form 2024-06-03 01:46:41 -04:00
Paul Pfeister f15699a4f4
Revamp forms 2024-06-02 16:28:34 -04:00
Siddharth Dushantha 3b187d1abc Removed uneeded info from --version output 2024-06-02 16:53:32 +02:00
Paul Pfeister 850528fb87
Add newline 2024-06-02 02:19:39 -04:00
Paul Pfeister 87f2f08f23
Add matheusfelipeog 2024-06-02 02:17:04 -04:00
Paul Pfeister 3c4f3d5d58
Revert "Changed errorType to message for EyeEm"
EyeEm seems to have begun properly serving 404s again

This reverts commit 945a364970.
2024-06-02 01:58:17 -04:00
Paul Pfeister b728ce0659
Cleanup 2024-06-01 16:10:07 -04:00
Paul Pfeister b0521d6f5c
'pwd' -> 'current working directory'
Co-authored-by: Siddharth Dushantha <siddharth.dushantha@gmail.com>
2024-06-01 16:02:40 -04:00
Paul Pfeister c812216cc5
Remove Main
Workflow made redundant with the addition of Regression workflow, which runs on both push to and PR against master.
2024-05-31 18:24:53 -04:00
Paul Pfeister 9701e4face
Remove Nightly
Workflow found to be ineffective after the removal of unclaimed_usernames. All sites skipped by tests due to the lack of this value, leading to false success of this test.

Workflow will be eventually rewritten following the new standard.
2024-05-31 18:24:13 -04:00
Paul Pfeister b2ddd9a396
Re-ID Regression CI 2024-05-31 17:08:50 -04:00
Paul Pfeister 67258b58a4
Adapt for online testing
When using tox, pass `-e offline` to exclude online tests.
When using pytest, pass `-m "not online"` to do the same.
2024-05-31 14:46:47 -04:00
Paul Pfeister d46775802e
Simple docu change
Co-authored-by: Siddharth Dushantha <siddharth.dushantha@gmail.com>
2024-05-31 14:46:47 -04:00
Paul Pfeister 9579f941be
Remove test branch 2024-05-31 14:46:47 -04:00
Paul Pfeister e5736d3888
Fix platform dependant issues 2024-05-31 14:46:47 -04:00
Paul Pfeister 4aaf0583c5
Fix platform differences 2024-05-31 14:46:47 -04:00
Paul Pfeister 906575df3a
Remove test branch from ci 2024-05-31 14:46:47 -04:00
Paul Pfeister 8bd8b20f9c
Remove Windows 2024-05-31 14:46:46 -04:00
Paul Pfeister beb4f3eaf6
Disable fail-fast 2024-05-31 14:46:46 -04:00
Paul Pfeister e32a84ea05
Fix tox caught errors 2024-05-31 14:46:46 -04:00
Paul Pfeister 249bab36eb
Drop py313 from ci 2024-05-31 14:46:46 -04:00
Paul Pfeister 790305bc07
Fix ci 2024-05-31 14:46:46 -04:00
Paul Pfeister 030860c0a1
Cleanup 2024-05-31 14:46:46 -04:00
Paul Pfeister 2b24cca340
Add tests 2024-05-31 14:46:46 -04:00
Paul Pfeister 08a12912c7
Remove exrex depend 2024-05-31 14:46:46 -04:00
Paul Pfeister 9f75d5ed14
Fix newline 2024-05-31 14:46:46 -04:00
Paul Pfeister a785a5931f
Adopt tox and pytest 2024-05-31 14:46:46 -04:00
Paul Pfeister 85ec59e255
whitelist -> allowlist
Seriously, tox?
2024-05-31 14:46:46 -04:00
Paul Pfeister b344611371
Add basic tox 2024-05-31 14:46:45 -04:00
Paul Pfeister 1de8ad0fc4
Fix linter flags 2024-05-31 14:46:45 -04:00
Paul Pfeister b8ca8aade4
Add Sponsor 2024-05-31 14:42:28 -04:00
Siddharth Dushantha e5ad3c471b fix incorrect path, closes #2140 2024-05-31 10:50:42 +02:00
pandyah5 945a364970 Changed errorType to message for EyeEm 2024-05-29 19:55:39 -04:00
Paul Pfeister 78119452aa Fix #2137 Archive downtime F+ 2024-05-29 12:05:00 -04:00
Paul Pfeister d42dadfc45
Remove pointless initialization of checksymbols 2024-05-29 00:54:42 -04:00
Abhishek 2271de7a1d
Merge branch 'sherlock-project:master' into master 2024-05-29 10:05:46 +05:30
Siddharth Dushantha 1cd81385b2
Merge pull request #2136 from sherlock-project/issue-forms
added issue forms
2024-05-28 07:34:12 +00:00
abhirai7 a9c00d9dbe Refactor checksymbols list initialization 2024-05-28 11:00:30 +05:30
Siddharth Dushantha 1f91d752f0
minor correction to label
Co-authored-by: Paul Pfeister <code@pfeister.dev>
2024-05-27 20:32:43 +00:00
Siddharth Dushantha ad5eb89c4c added issue forms 2024-05-27 16:22:40 +02:00
Paul Pfeister b38faf7dcf
Fix conflicts 2024-05-24 19:07:54 -04:00
Siddharth Dushantha 9b84a7817c
Merge pull request #2134 from sherlock-project/dir-cleanup
Project directory cleanup
2024-05-24 20:07:34 +00:00
Paul Pfeister 2486e49a29
Fix URI in header 2024-05-24 15:51:25 -04:00
Siddharth Dushantha a4550899be Updated paths based on changes in c065cbb92b 2024-05-24 21:20:56 +02:00
Siddharth Dushantha 7cb006526e removed docker-compose.yml
This was an example docker-compose.yml file. This example is also
available in ./docs/INSTALL.md. So keeping the file is just redundant
2024-05-24 12:00:14 +02:00
Siddharth Dushantha ec2aa0871e renamed install.md to INSTALL.md 2024-05-24 11:58:47 +02:00
Siddharth Dushantha e618a5a593 moved {removed-,}sites.md to ./docs 2024-05-24 11:56:54 +02:00
Siddharth Dushantha c065cbb92b moved site_list.py to scripts/site-list.py
This script is only executed by the GitHub workflow. Keeping it inside
the scripts directory makes the project's directory cleaner. Additionally,
it decreases the chance of contributers executing the script even though
its harmless.
2024-05-24 11:50:28 +02:00
Siddharth Dushantha ab5fcbb90f
Merge pull request #2132 from sherlock-project/remove-removed-sites-json
removed removed_sites.json
2024-05-22 21:01:26 +00:00
Siddharth Dushantha 0b9dfedc20 removed removed_sites.json 2024-05-22 16:44:18 +02:00
Paul Pfeister 04ce7aa0bb
Change remote version URI 2024-05-20 00:51:28 -04:00
Paul Pfeister 07274a9a2c
Add note about version number 2024-05-18 18:06:16 -04:00
Paul Pfeister 1b0e50854f
Allow pandas upgrade 2024-05-18 17:41:01 -04:00
Paul Pfeister 313d2a9080
Caret depends 2024-05-18 17:28:50 -04:00
Paul Pfeister 377e0766a2
Update pyproject.toml
Co-authored-by: Matheus Felipe <matheusfelipeog@gmail.com>
2024-05-18 14:29:33 -04:00
Paul Pfeister ba2eef7b0e
Revert "Remove tor"
This reverts commit 606743b99d.
2024-05-18 02:41:25 -04:00
Paul Pfeister 4b7fd8b59d
Fix typos 2024-05-18 02:22:18 -04:00
Paul Pfeister 606743b99d
Remove tor 2024-05-18 01:29:11 -04:00
Paul Pfeister 16e6ee639b
Add email to maintainers
Co-authored-by: Matheus Felipe <matheusfelipeog@gmail.com>
2024-05-18 01:01:37 -04:00
Paul Pfeister 33bbb4e720
Fix pyproject URLs
Co-authored-by: Matheus Felipe <matheusfelipeog@gmail.com>
2024-05-18 00:35:24 -04:00
Paul Pfeister 41f798a34e
Ignore dist 2024-05-17 21:29:52 -04:00
Paul Pfeister b485001fcb
Switch versioning plugin 2024-05-17 20:57:37 -04:00
Paul Pfeister 8fee9a9714
Ignore Poetry 2024-05-17 20:02:14 -04:00
Paul Pfeister 7867e26868 Remove upper limit 2024-05-17 00:19:08 -04:00
Paul Pfeister ea1c421838 Update docs with module changes 2024-05-16 23:47:10 -04:00
Paul Pfeister 63a1c1448a Fix version string 2024-05-16 23:37:03 -04:00
Paul Pfeister 3b713ed008 Fix cli mod exec import 2024-05-16 23:36:55 -04:00
Paul Pfeister e58057820f Downgrade poetry-core 2024-05-16 04:00:05 -04:00
Paul Pfeister 36c274ec19 Remove License classifier 2024-05-16 03:07:31 -04:00
Paul Pfeister af7565ec3d Allow higher certifi 2024-05-16 02:51:06 -04:00
Paul Pfeister 07227e4a9a Add dynamic versionin support (disabled) 2024-05-16 02:09:41 -04:00
Paul Pfeister 6b0995599a Remove install redirect 2024-05-16 00:16:46 -04:00
Paul Pfeister 9f58f93562 Remove requirements.txt 2024-05-16 00:09:23 -04:00
Paul Pfeister 44bc8523dd Remove setup.[cfg|py] from codeowners 2024-05-16 00:08:40 -04:00
Paul Pfeister caed51e268 Remove rpm spec 2024-05-16 00:08:00 -04:00
Paul Pfeister b2a69b5198 Remove setup.[cfg|py] 2024-05-16 00:06:49 -04:00
Paul Pfeister de8ebb1577 Relocate unit tests 2024-05-15 23:53:37 -04:00
Paul Pfeister fba6432f40 Switch to Poetry 2024-05-15 23:34:37 -04:00
Siddharth Dushantha 0ecb496ae9
Merge pull request #2125 from ppfeister/feature/codeowners
Add LICENSE
2024-05-15 20:19:38 +00:00
Paul Pfeister 7f29e8054d
Add LICENSE 2024-05-15 16:06:33 -04:00
Siddharth Dushantha 47c01a5687
Merge pull request #2117 from ppfeister/feature/codeowners
Add CODEOWNERS
2024-05-15 19:44:10 +00:00
Siddharth Dushantha 3f01b819c6
Merge pull request #2119 from ppfeister/feature/docu
Refresh docs
2024-05-15 19:23:54 +00:00
Paul Pfeister 379725e796 Refresh documentation 2024-05-15 15:20:26 -04:00
Paul Pfeister b78ced0c55 Fix manpage 2024-05-14 03:37:34 -04:00
Paul Pfeister 19c4af1a2e Satisfy rpmlint 2024-05-14 03:32:50 -04:00
Paul Pfeister 3c291a2d3f Remove problematic shebang sed 2024-05-14 02:55:55 -04:00
Paul Pfeister ff1e9d5766 Update spec 2024-05-14 02:44:43 -04:00
Paul Pfeister 3dbb0cb277
Merge pull request #2123 from ppfeister/bugfix/2113
Fix #2113
2024-05-13 22:51:50 -04:00
Paul Pfeister 0220c481ea Fix #2113 2024-05-13 22:47:53 -04:00
Paul Pfeister f2090bd198
Merge pull request #2033 from joaomfbh/tor_exception_handling
Add exception handling for Tor option
2024-05-13 01:12:27 -04:00
Paul Pfeister dc5d6d6d66 Set more specific err msg 2024-05-13 01:07:17 -04:00
Paul Pfeister 0d953ff236 Prepare PyProject for PyPI 2024-05-13 00:19:07 -04:00
Paul Pfeister 3e978d774b Remove pkger/vendor 2024-05-12 04:23:10 -04:00
Paul Pfeister 4b6e630e7f Finalize spec 2024-05-12 04:06:19 -04:00
Paul Pfeister 1bfb8c18c0 restore spec 2024-05-12 01:20:40 -04:00
Paul Pfeister 77c065ada3 maybe fix spec? 2024-05-12 01:07:31 -04:00
Paul Pfeister ed7f4374da Add rpm spec items 2024-05-12 00:14:17 -04:00
Paul Pfeister 128eb0d125 Add spec to srpm 2024-05-12 00:10:41 -04:00
Paul Pfeister c545fb9683 Fix version expansion 2024-05-11 23:35:26 -04:00
Paul Pfeister 3832444429 Fix egg 2024-05-11 23:32:42 -04:00
Paul Pfeister f5f64d55e0 Fix unexpanded macro 2024-05-11 23:23:24 -04:00
Paul Pfeister 86397058fb mend 2024-05-11 23:15:29 -04:00
Paul Pfeister b6d460ca9c Prepare rpm spec 2024-05-11 23:07:57 -04:00
Matheus Felipe f8e3bd7e29
Build the package along with the data file for local use (#2118)
* fix: build the package along with the data file for local use

* chore: set the package directory explicitly rather than dynamically
2024-05-11 17:52:55 -03:00
Siddharth Dushantha b83f5be912
Merge pull request #2116 from ppfeister/feature/pyproject
Prepare PyProject for PyPi
2024-05-11 16:25:05 +00:00
Paul Pfeister 1698928bd3 Prepare PyProject 2024-05-11 18:21:51 +02:00
Paul Pfeister 253e4d4e89 Add CODEOWNERS 2024-05-11 02:28:05 -04:00
github-actions[bot] f794e238a0 Updated Site List 2024-05-09 21:20:32 +00:00
Siddharth Dushantha 3d283b699e
Merge pull request #2107 from ppfeister/bugfix/false-pos
Fix new false positives
2024-05-09 21:20:20 +00:00
Siddharth Dushantha 66bd3a8c86
Merge pull request #2112 from sherlock-project/version-bump
version bump 0.14.3 -> 0.14.4
2024-05-09 16:28:40 +00:00
Paul Pfeister de21308219 Fix Linktree F+
Linktree only permits usernames with the given regex and 404s otherwise
2024-05-07 21:16:24 -04:00
Paul Pfeister 82d7e9ce43 Fix CNET F+
CNET appears to have changed some things...
'null null' text has been removed with a redesign, and invalid users now return a 404 so we don't need a whole GET and English-only check.
2024-05-07 20:55:25 -04:00
RahalBhupathi db1e82c2f4 updated sites.ms with warframe.market entry 2024-03-08 16:42:05 -05:00
RahalBhupathi 75a0bdc1f1 Added Warframe Market to sites 2024-03-08 13:46:00 -05:00
Marco Sirabella 79f5f18a69
Make an actual package with pyproject.toml
Fixes #2017
2024-03-02 13:21:32 -08:00
João Figueiredo 50816be0c1 Add exception handling for Tor option 2024-03-01 09:45:28 -03:00
73 changed files with 2924 additions and 2934 deletions

19
.actor/Dockerfile Normal file
View File

@ -0,0 +1,19 @@
FROM sherlock/sherlock as sherlock
# Install Node.js
RUN apt-get update; apt-get install curl gpg -y
RUN mkdir -p /etc/apt/keyrings
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
RUN apt-get update && apt-get install -y curl bash git jq jo xz-utils nodejs
# Install Apify CLI (node.js) for the Actor Runtime
RUN npm -g install apify-cli
# Install Dependencies for the Actor Shell Script
RUN apt-get update && apt-get install -y bash jq jo xz-utils nodejs
# Copy Actor dir with the actorization shell script
COPY .actor/ .actor
ENTRYPOINT [".actor/actor.sh"]

93
.actor/README.md Normal file
View File

@ -0,0 +1,93 @@
# Sherlock Actor on Apify
[![Sherlock Actor](https://apify.com/actor-badge?actor=netmilk/sherlock)](https://apify.com/netmilk/sherlock?fpr=sherlock)
This Actor wraps the [Sherlock Project](https://sherlockproject.xyz/) to provide serverless username reconnaissance across social networks in the cloud. It helps you find usernames across multiple social media platforms without installing and running the tool locally.
## What are Actors?
[Actors](https://docs.apify.com/platform/actors?fpr=sherlock) are serverless microservices running on the [Apify Platform](https://apify.com/?fpr=sherlock). They are based on the [Actor SDK](https://docs.apify.com/sdk/js?fpr=sherlock) and can be found in the [Apify Store](https://apify.com/store?fpr=sherlock). Learn more about Actors in the [Apify Whitepaper](https://whitepaper.actor?fpr=sherlock).
## Usage
### Apify Console
1. Go to the Apify Actor page
2. Click "Run"
3. In the input form, fill in **Username(s)** to search for
4. The Actor will run and produce its outputs in the default datastore
### Apify CLI
```bash
apify call YOUR_USERNAME/sherlock --input='{
"usernames": ["johndoe", "janedoe"]
}'
```
### Using Apify API
```bash
curl --request POST \
--url "https://api.apify.com/v2/acts/YOUR_USERNAME~sherlock/run" \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--data '{
"usernames": ["johndoe", "janedoe"],
}
}'
```
## Input Parameters
The Actor accepts a JSON schema with the following structure:
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `usernames` | array | Yes | - | List of usernames to search for |
| `usernames[]` | string | Yes | "json" | Username to search for |
### Example Input
```json
{
"usernames": ["techuser", "designuser"],
}
```
## Output
The Actor provides three types of outputs:
### Dataset Record*
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `username` | string | Yes | Username the search was conducted for |
| `links` | array | Yes | Array with found links to the social media |
| `links[]`| string | No | URL to the account
### Example Dataset Item (JSON)
```json
{
"username": "johndoe",
"links": [
"https://github.com/johndoe"
]
}
```
## Performance & Resources
- **Memory Requirements**:
- Minimum: 512 MB RAM
- Recommended: 1 GB RAM for multiple usernames
- **Processing Time**:
- Single username: ~1-2 minutes
- Multiple usernames: 2-5 minutes
- Varies based on number of sites checked and response times
For more help, check the [Sherlock Project documentation](https://github.com/sherlock-project/sherlock) or raise an issue in the Actor's repository.

13
.actor/actor.json Normal file
View File

@ -0,0 +1,13 @@
{
"actorSpecification": 1,
"name": "sherlock",
"version": "0.0",
"buildTag": "latest",
"environmentVariables": {},
"dockerFile": "./Dockerfile",
"dockerContext": "../",
"input": "./input_schema.json",
"storages": {
"dataset": "./dataset_schema.json"
}
}

14
.actor/actor.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
INPUT=`apify actor:get-input | jq -r .usernames[] | xargs echo`
echo "INPUT: $INPUT"
sherlock $INPUT
for username in $INPUT; do
# escape the special meaning leading characters
# https://github.com/jpmens/jo/blob/master/jo.md#description
safe_username=$(echo $username | sed 's/^@/\\@/' | sed 's/^:/\\:/' | sed 's/%/\\%/')
echo "pushing results for username: $username, content:"
cat $username.txt
sed '$d' $username.txt | jo -a | jo username=$safe_username links:=- | apify actor:push-data
done

View File

@ -0,0 +1,45 @@
{
"actorSpecification": 1,
"fields":{
"title": "Sherlock actor input",
"description": "This is actor input schema",
"type": "object",
"schemaVersion": 1,
"properties": {
"links": {
"title": "Links to accounts",
"type": "array",
"description": "A list of social media accounts found for the uername"
},
"username": {
"title": "Lookup username",
"type": "string",
"description": "Username the lookup was performed for"
}
},
"required": [
"username",
"links"
]
},
"views": {
"overview": {
"title": "Overview",
"transformation": {
"fields": [
"username",
"links"
],
},
"display": {
"component": "table",
"links": {
"label": "Links"
},
"username":{
"label": "Username"
}
}
}
}
}

18
.actor/input_schema.json Normal file
View File

@ -0,0 +1,18 @@
{
"title": "Sherlock actor input",
"description": "This is actor input schema",
"type": "object",
"schemaVersion": 1,
"properties": {
"usernames": {
"title": "Usernames to hunt down",
"type": "array",
"description": "A list of usernames to be checked for existence across social media",
"editor": "stringList",
"prefill": ["johndoe"]
}
},
"required": [
"usernames"
]
}

View File

@ -5,4 +5,4 @@ tests/
*.txt
!/requirements.txt
venv/
devel/

15
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,15 @@
### REPOSITORY
/.github/CODEOWNERS @sdushantha @ppfeister
/.github/FUNDING.yml @sdushantha
/LICENSE @sdushantha
### PACKAGING
# Changes made to these items without code owner approval may negatively
# impact packaging pipelines.
/pyproject.toml @ppfeister @sdushantha
### REGRESSION
/.github/workflows/regression.yml @ppfeister
/tox.ini @ppfeister
/pytest.ini @ppfeister
/tests/ @ppfeister

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
github: [ sdushantha, ppfeister, matheusfelipeog ]

View File

@ -1,38 +0,0 @@
---
name: Bug report
about: Report a bug in Sherlock's functionality
title: ''
labels: bug
assignees: ''
---
<!--
######################################################################
WARNING!
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
######################################################################
-->
## Checklist
<!--
Put x into all boxes (like this [x]) once you have completed what they say.
Make sure complete everything in the checklist.
-->
- [ ] I'm reporting a bug in Sherlock's functionality
- [ ] The bug I'm reporting is not a false positive or a false negative
- [ ] I've verified that I'm running the latest version of Sherlock
- [ ] I've checked for similar bug reports including closed ones
- [ ] I've checked for pull requests that attempt to fix this bug
## Description
<!--
Provide a detailed description of the bug that you have found in Sherlock.
Provide the version of Sherlock you are running.
-->
WRITE DESCRIPTION HERE

71
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@ -0,0 +1,71 @@
name: Bug report
description: File a bug report
labels: ["bug"]
body:
- type: dropdown
id: package
attributes:
label: Installation method
description: |
Some packages are maintained by the community, rather than by the Sherlock Project.
Knowing which packages are affected helps us diagnose package-specific bugs.
options:
- Select one
- PyPI (via pip)
- Homebrew
- Docker
- Kali repository (via apt)
- Built from source
- Other (indicate below)
validations:
required: true
- type: input
id: package-version
attributes:
label: Package version
description: |
Knowing the version of the package you are using can help us diagnose your issue more quickly.
You can find the version by running `sherlock --version`.
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: |
Detailed descriptions that help contributors understand and reproduce your bug are much more likely to lead to a fix.
Please include the following information:
- What you were trying to do
- What you expected to happen
- What actually happened
placeholder: |
When doing {action}, the expected result should be {expected result}.
When doing {action}, however, the actual result was {actual result}.
This is undesirable because {reason}.
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to reproduce
description: Write a step by step list that will allow us to reproduce this bug.
placeholder: |
1. Do something
2. Then do something else
validations:
required: true
- type: textarea
id: additional-info
attributes:
label: Additional information
description: If you have some additional information, please write it here.
validations:
required: false
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/sherlock-project/sherlock/blob/master/docs/CODE_OF_CONDUCT.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -0,0 +1,27 @@
name: False negative
description: Report a site that is returning false negative results
title: "False negative for: "
labels: ["false negative"]
body:
- type: markdown
attributes:
value: |
Please include the site name in the title of your issue.
Submit **one site per report** for faster resolution. If you have multiple sites in the same report, it often takes longer to fix.
- type: textarea
id: additional-info
attributes:
label: Additional info
description: If you know why the site is returning false negatives, or noticed any patterns, please explain.
placeholder: |
Reddit is returning false negatives because...
validations:
required: false
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/sherlock-project/sherlock/blob/master/docs/CODE_OF_CONDUCT.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true

View File

@ -0,0 +1,28 @@
name: False positive
description: Report a site that is returning false positive results
title: "False positive for: "
labels: ["false positive"]
body:
- type: markdown
attributes:
value: |
Please include the site name in the title of your issue.
Submit **one site per report** for faster resolution. If you have multiple sites in the same report, it often takes longer to fix.
- type: textarea
id: additional-info
attributes:
label: Additional info
description: If you know why the site is returning false positives, or noticed any patterns, please explain.
placeholder: |
Reddit is returning false positives because...
False positives only occur after x searches...
validations:
required: false
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/sherlock-project/sherlock/blob/master/docs/CODE_OF_CONDUCT.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true

View File

@ -1,32 +0,0 @@
---
name: Feature request
about: Request a new functionality for Sherlock
title: ''
labels: enhancement
assignees: ''
---
<!--
######################################################################
WARNING!
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
######################################################################
-->
## Checklist
<!--
Put x into all boxes (like this [x]) once you have completed what they say.
Make sure complete everything in the checklist.
-->
- [ ] I'm reporting a feature request
- [ ] I've checked for similar feature requests including closed ones
## Description
<!--
Provide a detailed description of the feature you would like Sherlock to have
-->
WRITE DESCRIPTION HERE

View File

@ -0,0 +1,24 @@
name: Feature request
description: Request a feature or enhancement
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Concise and thoughtful titles help other contributors find and add your requested feature.
- type: textarea
id: description
attributes:
label: Description
description: Describe the feature you are requesting
placeholder: I'd like Sherlock to be able to do xyz
validations:
required: true
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/sherlock-project/sherlock/blob/master/docs/CODE_OF_CONDUCT.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true

View File

@ -1,33 +0,0 @@
---
name: Question
about: Ask us a question
title: ''
labels: question
assignees: ''
---
<!--
######################################################################
WARNING!
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE.
######################################################################
-->
## Checklist
<!--
Put x into all boxes (like this [x]) once you have completed what they say.
Make sure complete everything in the checklist.
-->
- [ ] I'm asking a question regarding Sherlock
- [ ] My question is not a tech support question.
**We are not your tech support**.
If you have questions related to `pip`, `git`, or something that is not related to Sherlock, please ask them on [Stack Overflow](https://stackoverflow.com/) or [r/learnpython](https://www.reddit.com/r/learnpython/)
## Question
ASK YOUR QUESTION HERE

View File

@ -1,34 +0,0 @@
---
name: Reporting false negative
about: Reporting a site that is returning false positives
title: ''
labels: false negative
assignees: ''
---
<!--
######################################################################
WARNING!
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
######################################################################
-->
## Checklist
<!--
Put x into all boxes (like this [x]) once you have completed what they say.
Make sure complete everything in the checklist.
-->
- [ ] I'm reporting a website that is returning **false negative** results
- [ ] I've checked for similar site support requests including closed ones
- [ ] I've checked for pull requests attempting to fix this false negative
- [ ] I'm only reporting **one** site (create a separate issue for each site)
## Description
<!--
Provide the username that is causing Sherlock to return a false negative, along with any other information that might help us fix this false negative.
-->
WRITE DESCRIPTION HERE

View File

@ -1,34 +0,0 @@
---
name: Reporting false positive
about: Reporting a site that is returning false positives
title: ''
labels: false positive
assignees: ''
---
<!--
######################################################################
WARNING!
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
######################################################################
-->
## Checklist
<!--
Put x into all boxes (like this [x]) once you have completed what they say.
Make sure complete everything in the checklist.
-->
- [ ] I'm reporting a website that is returning **false positive** results
- [ ] I've checked for similar site support requests including closed ones
- [ ] I've checked for pull requests attempting to fix this false positive
- [ ] I'm only reporting **one** site (create a separate issue for each site)
## Description
<!--
Provide the username that is causing Sherlock to return a false positive, along with any other information that might help us fix this false positive.
-->
WRITE DESCRIPTION HERE

35
.github/ISSUE_TEMPLATE/site-request.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: Reuest a new website
description: Request that Sherlock add support for a new website
title: "Requesting support for: "
labels: ["site support request"]
body:
- type: markdown
attributes:
value: |
Ensure that the site name is in the title of your request. Requests without this information will be **closed**.
- type: input
id: site-url
attributes:
label: Site URL
description: |
What is the URL of the website indicated in your title?
Websites sometimes have similar names. This helps constributors find the correct site.
placeholder: https://reddit.com
validations:
required: true
- type: textarea
id: additional-info
attributes:
label: Additional info
description: If you have suggestions on how Sherlock should detect for usernames, please explain below
placeholder: Sherlock can detect if a username exists on Reddit by checking for...
validations:
required: false
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/sherlock-project/sherlock/blob/master/docs/CODE_OF_CONDUCT.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true

View File

@ -1,37 +0,0 @@
---
name: Site support request
about: Request support for a new site
title: ''
labels: site support request
assignees: ''
---
<!--
######################################################################
WARNING!
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
######################################################################
-->
## Checklist
<!--
Put x into all boxes (like this [x]) once you have completed what they say.
Make sure complete everything in the checklist.
-->
- [ ] I'm requesting support for a new site
- [ ] I've checked for similar site support requests including closed ones
- [ ] I've checked that the site I am requesting has not been removed in the past and is not documented in [removed_sites.md](https://github.com/sherlock-project/sherlock/blob/master/removed_sites.md)
- [ ] The site I am requesting support for is not a pornographic website
- [ ] I'm only requesting support of **one** website (create a separate issue for each site)
## Description
<!--
Provide the url to the website and the name of the website.
If there is anything else you want to mention regarding the site support request include that in this section.
-->
URL:

11
.github/SECURITY.md vendored Normal file
View File

@ -0,0 +1,11 @@
## Security Policy
### Supported Versions
Sherlock is a forward looking project. Only the latest and most current version is supported.
### Reporting a Vulnerability
Security concerns can be submitted [__here__][report-url] without risk of exposing sensitive information. For issues that are low severity or unlikely to see exploitation, public issues are often acceptable.
[report-url]: https://github.com/sherlock-project/sherlock/security/advisories/new

89
.github/workflows/exclusions.yml vendored Normal file
View File

@ -0,0 +1,89 @@
name: Exclusions Updater
on:
schedule:
#- cron: '0 5 * * 0' # Runs at 05:00 every Sunday
- cron: '0 5 * * *' # Runs at 05:00 every day
workflow_dispatch:
jobs:
update-exclusions:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Poetry
uses: abatilo/actions-poetry@v4
with:
poetry-version: 'latest'
- name: Install dependencies
run: |
poetry install --no-interaction --with dev
- name: Run false positive tests
run: |
$(poetry env activate)
pytest -q --tb no -m validate_targets_fp -n 20 | tee fp_test_results.txt
deactivate
- name: Parse false positive detections by desired categories
run: |
grep -oP '(?<=test_false_pos\[)[^\]]+(?=\].*result was Claimed)' fp_test_results.txt \
| sort -u > false_positive_exclusions.txt
grep -oP '(?<=test_false_pos\[)[^\]]+(?=\].*result was WAF)' fp_test_results.txt \
| sort -u > waf_hits.txt
- name: Detect if exclusions list changed
id: detect_changes
run: |
git fetch origin exclusions || true
if git show origin/exclusions:false_positive_exclusions.txt >/dev/null 2>&1; then
# If the exclusions branch and file exist, compare
if git diff --quiet origin/exclusions -- false_positive_exclusions.txt; then
echo "exclusions_changed=false" >> "$GITHUB_OUTPUT"
else
echo "exclusions_changed=true" >> "$GITHUB_OUTPUT"
fi
else
# If the exclusions branch or file do not exist, treat as changed
echo "exclusions_changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Quantify and display results
run: |
FP_COUNT=$(wc -l < false_positive_exclusions.txt | xargs)
WAF_COUNT=$(wc -l < waf_hits.txt | xargs)
echo ">>> Found $FP_COUNT false positives and $WAF_COUNT WAF hits."
echo ">>> False positive exclusions:" && cat false_positive_exclusions.txt
echo ">>> WAF hits:" && cat waf_hits.txt
- name: Commit and push exclusions list
if: steps.detect_changes.outputs.exclusions_changed == 'true'
run: |
git config user.name "Paul Pfeister (automation)"
git config user.email "code@pfeister.dev"
mv false_positive_exclusions.txt false_positive_exclusions.txt.tmp
git add -f false_positive_exclusions.txt.tmp # -f required to override .gitignore
git stash push -m "stash false positive exclusion list" -- false_positive_exclusions.txt.tmp
git fetch origin exclusions || true # Allows creation of branch if deleted
git checkout -B exclusions origin/exclusions || (git checkout --orphan exclusions && git rm -rf .)
git stash pop || true
mv false_positive_exclusions.txt.tmp false_positive_exclusions.txt
git rm -f false_positive_exclusions.txt.tmp || true
git add false_positive_exclusions.txt
git commit -m "auto: update exclusions list" || echo "No changes to commit"
git push origin exclusions

View File

@ -1,38 +0,0 @@
name: Tests
on:
push:
branches: [ master ]
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- '3.12'
- '3.11'
- '3.10'
- '3.9'
- '3.8'
- '3.7'
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install ruff flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with ruff
run: |
# stop the build if there are Python syntax errors or undefined names
ruff . --output-format=github --select=E9,F63,F7,F82
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Sherlock Site Detect Tests
run: |
cd sherlock && python -m unittest tests.all.SherlockDetectTests --verbose

View File

@ -1,27 +0,0 @@
name: Nightly
on:
schedule:
# Run Nightly Tests At 3AM (The Hour Of The Wolf) Every Day
- cron: '0 3 * * *'
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.x]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Sherlock Site Coverage Tests
run: |
cd sherlock && python -m unittest tests.all.SherlockSiteCoverageTests --verbose

View File

@ -1,47 +0,0 @@
name: Pull Request Action
on:
pull_request:
branches: [ master ]
jobs:
getchange:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.changes.outputs.matrix }}
steps:
- id: changes
run: |
URL="https://api.github.com/repos/sherlock-project/sherlock/pulls/${{ github.event.pull_request.number }}/files"
FILES=$(curl -s -X GET -G $URL | jq -r '.[] | .filename')
if echo $FILES | grep -q ".json"; then
echo "::set-output name=matrix::{\"include\":[{\"python\":\"3.x\"}]}"
else
echo "::set-output name=matrix::{\"include\":[{\"python\":\"3.7\"},{\"python\":\"3.8\"}]},{\"python\":\"3.9\"},{\"python\":\"3.10\"}]},{\"python\":\"3.11\"},{\"python\":\"3.12\"}]}"
fi
tests:
needs: [getchange]
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJson(needs.getchange.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install ruff flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint With Ruff
run: |
# stop the build if there are Python syntax errors or undefined names
ruff check . --output-format=github --select=E9,F63,F7,F82
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Sherlock Site Detect Tests
run: |
cd sherlock && python -m unittest tests.all.SherlockDetectTests --verbose

92
.github/workflows/regression.yml vendored Normal file
View File

@ -0,0 +1,92 @@
name: Regression Testing
on:
pull_request:
branches:
- master
- release/**
paths:
- '.github/workflows/regression.yml'
- '**/*.json'
- '**/*.py'
- '**/*.ini'
- '**/*.toml'
- 'Dockerfile'
push:
branches:
- master
- release/**
paths:
- '.github/workflows/regression.yml'
- '**/*.json'
- '**/*.py'
- '**/*.ini'
- '**/*.toml'
- 'Dockerfile'
jobs:
tox-lint:
runs-on: ubuntu-latest
# Linting is ran through tox to ensure that the same linter
# is used by local runners
steps:
- uses: actions/checkout@v4
- name: Set up linting environment
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install tox and related dependencies
run: |
python -m pip install --upgrade pip
pip install tox
- name: Run tox linting environment
run: tox -e lint
tox-matrix:
runs-on: ${{ matrix.os }}
strategy:
# We want to know what specicic versions it fails on
fail-fast: false
matrix:
os: [
ubuntu-latest,
windows-latest,
macos-latest,
]
python-version: [
'3.10',
'3.11',
'3.12',
'3.13',
]
steps:
- uses: actions/checkout@v4
- name: Set up environment ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install tox and related dependencies
run: |
python -m pip install --upgrade pip
pip install tox
pip install tox-gh-actions
- name: Run tox
run: tox
docker-build-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Get version from pyproject.toml
id: get-version
run: |
VERSION=$(grep -m1 'version = ' pyproject.toml | cut -d'"' -f2)
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Build Docker image
run: |
docker build \
--build-arg VERSION_TAG=${{ steps.get-version.outputs.version }} \
-t sherlock-test:latest .
- name: Test Docker image runs
run: docker run --rm sherlock-test:latest --version

View File

@ -1,13 +1,13 @@
name: Update Site List
name: Update Site List
# Trigger the workflow when changes are pushed to the main branch
# and the changes include the sherlock/resources/data.json file
# and the changes include the sherlock_project/resources/data.json file
on:
push:
branches:
- master
- master
paths:
- sherlock/resources/data.json
- sherlock_project/resources/data.json
jobs:
sync-json-data:
@ -26,24 +26,21 @@ jobs:
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
python-version: '3.x'
# Execute the site_list.py Python script
- name: Execute site_list.py
run: python site_list.py
- name: Execute site-list.py
run: python devel/site-list.py
# Commit any changes made by the script
- name: Commit files
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
if ! git diff --exit-code; then
git commit -a -m "Updated Site List"
fi
# Push the changes to the remote repository
- name: Push changes
uses: ad-m/github-push-action@master
- name: Pushes to another repository
uses: sdushantha/github-action-push-to-another-repository@main
env:
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
source-directory: 'output'
destination-github-username: 'sherlock-project'
commit-message: 'Updated site list'
destination-repository-name: 'sherlockproject.xyz'
user-email: siddharth.dushantha@gmail.com
target-branch: master

View File

@ -0,0 +1,126 @@
name: Modified Target Validation
on:
pull_request_target:
branches:
- master
paths:
- "sherlock_project/resources/data.json"
jobs:
validate-modified-targets:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
# Checkout the base branch but fetch all history to avoid a second fetch call
ref: ${{ github.base_ref }}
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install Poetry
uses: abatilo/actions-poetry@v4
with:
poetry-version: "latest"
- name: Install dependencies
run: |
poetry install --no-interaction --with dev
- name: Prepare JSON versions for comparison
run: |
# Fetch only the PR's branch head (single network call in this step)
git fetch origin pull/${{ github.event.pull_request.number }}/head:pr
# Find the merge-base commit between the target branch and the PR branch
MERGE_BASE=$(git merge-base origin/${{ github.base_ref }} pr)
echo "Comparing PR head against merge-base commit: $MERGE_BASE"
# Safely extract the file from the PR's head and the merge-base commit
git show pr:sherlock_project/resources/data.json > data.json.head
git show $MERGE_BASE:sherlock_project/resources/data.json > data.json.base
# CRITICAL FIX: Overwrite the checked-out data.json with the one from the PR
# This ensures that pytest runs against the new, updated file.
cp data.json.head sherlock_project/resources/data.json
- name: Discover modified targets
id: discover-modified
run: |
CHANGED=$(
python - <<'EOF'
import json
import sys
try:
with open("data.json.base") as f: base = json.load(f)
with open("data.json.head") as f: head = json.load(f)
except FileNotFoundError as e:
print(f"Error: Could not find {e.filename}", file=sys.stderr)
sys.exit(1)
except json.JSONDecodeError as e:
print(f"Error: Could not decode JSON from a file - {e}", file=sys.stderr)
sys.exit(1)
changed = []
for k, v in head.items():
if k not in base or base[k] != v:
changed.append(k)
print(",".join(sorted(changed)))
EOF
)
# Preserve changelist
echo -e ">>> Changed targets: \n$(echo $CHANGED | tr ',' '\n')"
echo "changed_targets=$CHANGED" >> "$GITHUB_OUTPUT"
- name: Validate remote manifest against local schema
if: steps.discover-modified.outputs.changed_targets != ''
run: |
poetry run pytest tests/test_manifest.py::test_validate_manifest_against_local_schema
# --- The rest of the steps below are unchanged ---
- name: Validate modified targets
if: steps.discover-modified.outputs.changed_targets != ''
continue-on-error: true
run: |
poetry run pytest -q --tb no -rA -m validate_targets -n 20 \
--chunked-sites "${{ steps.discover-modified.outputs.changed_targets }}" \
--junitxml=validation_results.xml
- name: Prepare validation summary
if: steps.discover-modified.outputs.changed_targets != ''
id: prepare-summary
run: |
summary=$(
poetry run python devel/summarize_site_validation.py validation_results.xml || echo "Failed to generate summary of test results"
)
echo "$summary" > validation_summary.md
- name: Announce validation results
if: steps.discover-modified.outputs.changed_targets != ''
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('validation_summary.md', 'utf8');
await github.rest.issues.createComment({
issue_number: context.payload.pull_request.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body,
});
- name: This step shows as ran when no modifications are found
if: steps.discover-modified.outputs.changed_targets == ''
run: |
echo "No modified targets found"

11
.gitignore vendored
View File

@ -1,8 +1,13 @@
# Virtual Environment
# Virtual Environments
venv/
bin/
lib/
pyvenv.cfg
poetry.lock
# Regression Testing
.coverage
.tox/
# Editor Configurations
.vscode/
@ -14,6 +19,10 @@ __pycache__/
# Pip
src/
# Devel, Build, and Installation
*.egg-info/
dist/**
# Jupyter Notebook
.ipynb_checkpoints
*.ipynb

View File

@ -1,31 +0,0 @@
# How To Contribute To Sherlock
First off, thank you for the help!
There are many ways to contribute. Here is some high level grouping.
## Adding New Sites
Please look at the Wiki entry on
[adding new sites](https://github.com/sherlock-project/sherlock/wiki/Adding-Sites-To-Sherlock)
to understand the issues.
Any new sites that are added need to have a username that has been claimed, and one
that is unclaimed documented in the site data. This allows the regression tests
to ensure that everything is working.
It is required that a contributor test any new sites by either running the full tests, or running
a site-specific query against the claimed and unclaimed usernames.
It is not required that a contributor run the
[site_list.py](https://github.com/sherlock-project/sherlock/blob/master/site_list.py)
script.
If there are performance problems with a site (e.g. slow to respond, unreliable uptime, ...), then
the site may be removed from the list. The
[removed_sites.md](https://github.com/sherlock-project/sherlock/blob/master/removed_sites.md)
file contains sites that were included at one time in Sherlock, but had to be removed for
one reason or another.
## Adding New Functionality
Please ensure that the content on your branch passes all tests before submitting a pull request.

View File

@ -1,26 +1,31 @@
FROM python:3.11-slim-bullseye as build
WORKDIR /wheels
# Release instructions:
# 1. Update the version tag in the Dockerfile to match the version in sherlock/__init__.py
# 2. Update the VCS_REF tag to match the tagged version's FULL commit hash
# 3. Build image with BOTH latest and version tags
# i.e. `docker build -t sherlock/sherlock:0.16.0 -t sherlock/sherlock:latest .`
COPY requirements.txt /opt/sherlock/
RUN apt-get update \
&& apt-get install -y build-essential \
&& pip3 wheel -r /opt/sherlock/requirements.txt
FROM python:3.12-slim-bullseye AS build
WORKDIR /sherlock
FROM python:3.11-slim-bullseye
WORKDIR /opt/sherlock
RUN pip3 install --no-cache-dir --upgrade pip
ARG VCS_REF
FROM python:3.12-slim-bullseye
WORKDIR /sherlock
ARG VCS_REF= # CHANGE ME ON UPDATE
ARG VCS_URL="https://github.com/sherlock-project/sherlock"
ARG VERSION_TAG= # CHANGE ME ON UPDATE
ENV SHERLOCK_ENV=docker
LABEL org.label-schema.vcs-ref=$VCS_REF \
org.label-schema.vcs-url=$VCS_URL
org.label-schema.vcs-url=$VCS_URL \
org.label-schema.name="Sherlock" \
org.label-schema.version=$VERSION_TAG \
website="https://sherlockproject.xyz"
COPY --from=build /wheels /wheels
COPY . /opt/sherlock/
RUN pip3 install --no-cache-dir sherlock-project==$VERSION_TAG
RUN pip3 install --no-cache-dir -r requirements.txt -f /wheels \
&& rm -rf /wheels
WORKDIR /sherlock
WORKDIR /opt/sherlock/sherlock
ENTRYPOINT ["python", "sherlock.py"]
ENTRYPOINT ["sherlock"]

184
README.md
View File

@ -1,184 +0,0 @@
<p align=center>
<br>
<a href="https://sherlock-project.github.io/" target="_blank"><img src="https://user-images.githubusercontent.com/27065646/53551960-ae4dff80-3b3a-11e9-9075-cef786c69364.png"/></a>
<br>
<span>Hunt down social media accounts by username across <a href="https://github.com/sherlock-project/sherlock/blob/master/sites.md">social networks</a></span>
<br>
</p>
<p align="center">
<a href="#installation">Installation</a>
&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<a href="#usage">Usage</a>
&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<a href="#docker-notes">Docker Notes</a>
&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<a href="#contributing">Contributing</a>
</p>
<p align="center">
<img width="70%" height="70%" src="https://user-images.githubusercontent.com/27065646/219638267-a5e11090-aa6e-4e77-87f7-0e95f6ad5978.png"/>
</a>
</p>
## Installation
```console
# clone the repo
$ git clone https://github.com/sherlock-project/sherlock.git
# change the working directory to sherlock
$ cd sherlock
# install the requirements
$ python3 -m pip install -r requirements.txt
```
## Usage
```console
$ python3 sherlock --help
usage: sherlock [-h] [--version] [--verbose] [--folderoutput FOLDEROUTPUT]
[--output OUTPUT] [--tor] [--unique-tor] [--csv] [--xlsx]
[--site SITE_NAME] [--proxy PROXY_URL] [--json JSON_FILE]
[--timeout TIMEOUT] [--print-all] [--print-found] [--no-color]
[--browse] [--local] [--nsfw]
USERNAMES [USERNAMES ...]
Sherlock: Find Usernames Across Social Networks (Version 0.14.3)
positional arguments:
USERNAMES One or more usernames to check with social networks.
Check similar usernames using {?} (replace to '_', '-', '.').
optional arguments:
-h, --help show this help message and exit
--version Display version information and dependencies.
--verbose, -v, -d, --debug
Display extra debugging information and metrics.
--folderoutput FOLDEROUTPUT, -fo FOLDEROUTPUT
If using multiple usernames, the output of the results will be
saved to this folder.
--output OUTPUT, -o OUTPUT
If using single username, the output of the result will be saved
to this file.
--tor, -t Make requests over Tor; increases runtime; requires Tor to be
installed and in system path.
--unique-tor, -u Make requests over Tor with new Tor circuit after each request;
increases runtime; requires Tor to be installed and in system
path.
--csv Create Comma-Separated Values (CSV) File.
--xlsx Create the standard file for the modern Microsoft Excel
spreadsheet (xlsx).
--site SITE_NAME Limit analysis to just the listed sites. Add multiple options to
specify more than one site.
--proxy PROXY_URL, -p PROXY_URL
Make requests over a proxy. e.g. socks5://127.0.0.1:1080
--json JSON_FILE, -j JSON_FILE
Load data from a JSON file or an online, valid, JSON file.
--timeout TIMEOUT Time (in seconds) to wait for response to requests (Default: 60)
--print-all Output sites where the username was not found.
--print-found Output sites where the username was found.
--no-color Don't color terminal output
--browse, -b Browse to all results on default browser.
--local, -l Force the use of the local data.json file.
--nsfw Include checking of NSFW sites from default list.
```
To search for only one user:
```
python3 sherlock user123
```
To search for more than one user:
```
python3 sherlock user1 user2 user3
```
Accounts found will be stored in an individual text file with the corresponding username (e.g ```user123.txt```).
## Anaconda (Windows) Notes
If you are using Anaconda in Windows, using `python3` might not work. Use `python` instead.
## Docker Notes
If docker is installed you can build an image and run this as a container.
```
docker build -t mysherlock-image .
```
Once the image is built, sherlock can be invoked by running the following:
```
docker run --rm -t mysherlock-image user123
```
Use the following command to access the saved results:
```
docker run --rm -t -v "$PWD/results:/opt/sherlock/results" mysherlock-image -o /opt/sherlock/results/text.txt user123
```
Docker is instructed to create (or use) the folder `results` in the current working directory and to mount it at `/opt/sherlock/results` on the docker container by using the ```-v "$PWD/results:/opt/sherlock/results"``` options. `Sherlock` is instructed to export the result using the `-o /opt/sherlock/results/text.txt` option.
### Using `docker-compose`
You can use the `docker-compose.yml` file from the repository and use this command:
```
docker-compose run sherlock -o /opt/sherlock/results/text.txt user123
```
## Contributing
We would love to have you help us with the development of Sherlock. Each and every contribution is greatly valued!
Here are some things we would appreciate your help on:
- Addition of new site support ¹
- Bringing back site support of [sites that have been removed](removed_sites.md) in the past due to false positives
[1] Please look at the Wiki entry on [adding new sites](https://github.com/sherlock-project/sherlock/wiki/Adding-Sites-To-Sherlock)
to understand the issues.
## Tests
Thank you for contributing to Sherlock!
Before creating a pull request with new development, please run the tests
to ensure that everything is working great. It would also be a good idea to run the tests
before starting development to distinguish problems between your
environment and the Sherlock software.
The following is an example of the command line to run all the tests for
Sherlock. This invocation hides the progress text that Sherlock normally
outputs, and instead shows the verbose output of the tests.
```console
$ cd sherlock/sherlock
$ python3 -m unittest tests.all --verbose
```
Note that we do currently have 100% test coverage. Unfortunately, some of
the sites that Sherlock checks are not always reliable, so it is common
to get response problems. Any problems in connection will show up as
warnings in the tests instead of true errors.
If some sites are failing due to connection problems (site is down, in maintenance, etc)
you can exclude them from tests by creating a `tests/.excluded_sites` file with a
list of sites to ignore (one site name per line).
## Star History
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=sherlock-project/sherlock&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=sherlock-project/sherlock&type=Date" />
<img alt="Sherlock Project Star History Chart" src="https://api.star-history.com/svg?repos=sherlock-project/sherlock&type=Date" />
</picture>
## License
MIT © Sherlock Project<br/>
Original Creator - [Siddharth Dushantha](https://github.com/sdushantha)

45
devel/site-list.py Normal file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env python
# This module generates the listing of supported sites which can be found in
# sites.mdx. It also organizes all the sites in alphanumeric order
import json
import os
DATA_REL_URI: str = "sherlock_project/resources/data.json"
DEFAULT_ENCODING = "utf-8"
# Read the data.json file
with open(DATA_REL_URI, "r", encoding=DEFAULT_ENCODING) as data_file:
data: dict = json.load(data_file)
# Removes schema-specific keywords for proper processing
social_networks = data.copy()
social_networks.pop('$schema', None)
# Sort the social networks in alphanumeric order
social_networks = sorted(social_networks.items())
# Make output dir where the site list will be written
os.mkdir("output")
# Write the list of supported sites to sites.mdx
with open("output/sites.mdx", "w", encoding=DEFAULT_ENCODING) as site_file:
site_file.write("---\n")
site_file.write("title: 'List of supported sites'\n")
site_file.write("sidebarTitle: 'Supported sites'\n")
site_file.write("icon: 'globe'\n")
site_file.write("description: 'Sherlock currently supports **400+** sites'\n")
site_file.write("---\n\n")
for social_network, info in social_networks:
url_main = info["urlMain"]
is_nsfw = "**(NSFW)**" if info.get("isNSFW") else ""
site_file.write(f"1. [{social_network}]({url_main}) {is_nsfw}\n")
# Overwrite the data.json file with sorted data
with open(DATA_REL_URI, "w", encoding=DEFAULT_ENCODING) as data_file:
sorted_data = json.dumps(data, indent=2, sort_keys=True)
data_file.write(sorted_data)
data_file.write("\n") # Keep the newline after writing data
print("Finished updating supported site listing!")

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
# This module summarizes the results of site validation tests queued by
# workflow validate_modified_targets for presentation in Issue comments.
from defusedxml import ElementTree as ET
import sys
from pathlib import Path
def summarize_junit_xml(xml_path: Path) -> str:
tree = ET.parse(xml_path)
root = tree.getroot()
suite = root.find('testsuite')
pass_message: str = ":heavy_check_mark: &nbsp; Pass"
fail_message: str = ":x: &nbsp; Fail"
if suite is None:
raise ValueError("Invalid JUnit XML: No testsuite found")
summary_lines: list[str] = []
summary_lines.append("#### Automatic validation of changes\n")
summary_lines.append("| Target | F+ Check | F- Check |")
summary_lines.append("|---|---|---|")
failures = int(suite.get('failures', 0))
errors_detected: bool = False
results: dict[str, dict[str, str]] = {}
for testcase in suite.findall('testcase'):
test_name = testcase.get('name').split('[')[0]
site_name = testcase.get('name').split('[')[1].rstrip(']')
failure = testcase.find('failure')
error = testcase.find('error')
if site_name not in results:
results[site_name] = {}
if test_name == "test_false_neg":
results[site_name]['F- Check'] = pass_message if failure is None and error is None else fail_message
elif test_name == "test_false_pos":
results[site_name]['F+ Check'] = pass_message if failure is None and error is None else fail_message
if error is not None:
errors_detected = True
for result in results:
summary_lines.append(f"| {result} | {results[result].get('F+ Check', 'Error!')} | {results[result].get('F- Check', 'Error!')} |")
if failures > 0:
summary_lines.append("\n___\n" +
"\nFailures were detected on at least one updated target. Commits containing accuracy failures" +
" will often not be merged (unless a rationale is provided, such as false negatives due to regional differences).")
if errors_detected:
summary_lines.append("\n___\n" +
"\n**Errors were detected during validation. Please review the workflow logs.**")
return "\n".join(summary_lines)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: summarize_site_validation.py <junit-xml-file>")
sys.exit(1)
xml_path: Path = Path(sys.argv[1])
if not xml_path.is_file():
print(f"Error: File '{xml_path}' does not exist.")
sys.exit(1)
summary: str = summarize_junit_xml(xml_path)
print(summary)

View File

@ -1,7 +0,0 @@
version: '2'
services:
sherlock:
build: .
volumes:
- "./results:/opt/sherlock/results"

143
docs/README.md Normal file
View File

@ -0,0 +1,143 @@
<p align="center">
<br>
<a href="https://sherlock-project.github.io/" target="_blank"><img src="images/sherlock-logo.png" alt="sherlock"/></a>
<br>
<span>Hunt down social media accounts by username across <a href="https://sherlockproject.xyz/sites">400+ social networks</a></span>
<br>
</p>
<p align="center">
<a href="https://sherlockproject.xyz/installation">Installation</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://sherlockproject.xyz/usage">Usage</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://sherlockproject.xyz/contribute">Contributing</a>
</p>
<p align="center">
<img width="70%" height="70%" src="images/demo.png" alt="demo"/>
</p>
## Installation
> [!WARNING]
> Packages for ParrotOS and Ubuntu 24.04, maintained by a third party, appear to be __broken__.
> Users of these systems should defer to pipx/pip or Docker.
| Method | Notes |
| - | - |
| `pipx install sherlock-project` | `pip` may be used in place of `pipx` |
| `docker run -it --rm sherlock/sherlock` |
| `dnf install sherlock-project` | |
Community-maintained packages are available for Debian (>= 13), Ubuntu (>= 22.10), Homebrew, Kali, and BlackArch. These packages are not directly supported or maintained by the Sherlock Project.
See all alternative installation methods [here](https://sherlockproject.xyz/installation)
## General usage
To search for only one user:
```bash
sherlock user123
```
To search for more than one user:
```bash
sherlock user1 user2 user3
```
Accounts found will be stored in an individual text file with the corresponding username (e.g ```user123.txt```).
```console
$ sherlock --help
usage: sherlock [-h] [--version] [--verbose] [--folderoutput FOLDEROUTPUT]
[--output OUTPUT] [--tor] [--unique-tor] [--csv] [--xlsx]
[--site SITE_NAME] [--proxy PROXY_URL] [--json JSON_FILE]
[--timeout TIMEOUT] [--print-all] [--print-found] [--no-color]
[--browse] [--local] [--nsfw]
USERNAMES [USERNAMES ...]
Sherlock: Find Usernames Across Social Networks (Version 0.14.3)
positional arguments:
USERNAMES One or more usernames to check with social networks.
Check similar usernames using {?} (replace to '_', '-', '.').
optional arguments:
-h, --help show this help message and exit
--version Display version information and dependencies.
--verbose, -v, -d, --debug
Display extra debugging information and metrics.
--folderoutput FOLDEROUTPUT, -fo FOLDEROUTPUT
If using multiple usernames, the output of the results will be
saved to this folder.
--output OUTPUT, -o OUTPUT
If using single username, the output of the result will be saved
to this file.
--tor, -t Make requests over Tor; increases runtime; requires Tor to be
installed and in system path.
--unique-tor, -u Make requests over Tor with new Tor circuit after each request;
increases runtime; requires Tor to be installed and in system
path.
--csv Create Comma-Separated Values (CSV) File.
--xlsx Create the standard file for the modern Microsoft Excel
spreadsheet (xlsx).
--site SITE_NAME Limit analysis to just the listed sites. Add multiple options to
specify more than one site.
--proxy PROXY_URL, -p PROXY_URL
Make requests over a proxy. e.g. socks5://127.0.0.1:1080
--json JSON_FILE, -j JSON_FILE
Load data from a JSON file or an online, valid, JSON file.
--timeout TIMEOUT Time (in seconds) to wait for response to requests (Default: 60)
--print-all Output sites where the username was not found.
--print-found Output sites where the username was found.
--no-color Don't color terminal output
--browse, -b Browse to all results on default browser.
--local, -l Force the use of the local data.json file.
--nsfw Include checking of NSFW sites from default list.
```
## Apify Actor Usage [![Sherlock Actor](https://apify.com/actor-badge?actor=netmilk/sherlock)](https://apify.com/netmilk/sherlock?fpr=sherlock)
<a href="https://apify.com/netmilk/sherlock?fpr=sherlock"><img src="https://apify.com/ext/run-on-apify.png" alt="Run Sherlock Actor on Apify" width="176" height="39" /></a>
You can run Sherlock in the cloud without installation using the [Sherlock Actor](https://apify.com/netmilk/sherlock?fpr=sherlock) on [Apify](https://apify.com?fpr=sherlock) free of charge.
``` bash
$ echo '{"usernames":["user123"]}' | apify call -so netmilk/sherlock
[{
"username": "user123",
"links": [
"https://www.1337x.to/user/user123/",
...
]
}]
```
Read more about the [Sherlock Actor](../.actor/README.md), including how to use it programmatically via the Apify [API](https://apify.com/netmilk/sherlock/api?fpr=sherlock), [CLI](https://docs.apify.com/cli/?fpr=sherlock) and [JS/TS and Python SDKs](https://docs.apify.com/sdk?fpr=sherlock).
## Credits
Thank you to everyone who has contributed to Sherlock! ❤️
<a href="https://github.com/sherlock-project/sherlock/graphs/contributors">
<img src="https://contrib.rocks/image?&columns=25&max=10000&&repo=sherlock-project/sherlock" alt="contributors"/>
</a>
## Star History
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=sherlock-project/sherlock&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=sherlock-project/sherlock&type=Date" />
<img alt="Sherlock Project Star History Chart" src="https://api.star-history.com/svg?repos=sherlock-project/sherlock&type=Date" />
</picture>
## License
MIT © Sherlock Project<br/>
Original Creator - [Siddharth Dushantha](https://github.com/sdushantha)
<!-- Reference Links -->
[ext_pypi]: https://pypi.org/project/sherlock-project/
[ext_brew]: https://formulae.brew.sh/formula/sherlock

BIN
docs/images/demo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

42
docs/pyproject/README.md Normal file
View File

@ -0,0 +1,42 @@
<!-- This README should be a mini version at all times for use on pypi -->
<p align=center>
<br>
<a href="https://sherlock-project.github.io/" target="_blank"><img src="https://www.kali.org/tools/sherlock/images/sherlock-logo.svg" width="25%"/></a>
<br>
<strong><span>Hunt down social media accounts by username across <a href="https://github.com/sherlock-project/sherlock/blob/master/sites.md">400+ social networks</a></span></strong>
<br><br>
<span>Additional documentation can be found at our <a href="https://github.com/sherlock-project/sherlock/">GitHub repository</a></span>
<br>
</p>
## Usage
```console
$ sherlock --help
usage: sherlock [-h] [--version] [--verbose] [--folderoutput FOLDEROUTPUT]
[--output OUTPUT] [--tor] [--unique-tor] [--csv] [--xlsx]
[--site SITE_NAME] [--proxy PROXY_URL] [--json JSON_FILE]
[--timeout TIMEOUT] [--print-all] [--print-found] [--no-color]
[--browse] [--local] [--nsfw]
USERNAMES [USERNAMES ...]
```
To search for only one user:
```bash
$ sherlock user123
```
To search for more than one user:
```bash
$ sherlock user1 user2 user3
```
<br>
___
<br>
<p align="center">
<img width="70%" height="70%" src="https://user-images.githubusercontent.com/27065646/219638267-a5e11090-aa6e-4e77-87f7-0e95f6ad5978.png"/>
</a>
</p>

View File

@ -84,22 +84,6 @@ As of 2020-02-23, all usernames are reported as not existing.
},
```
## Fanpop
As of 2020-02-23, all usernames are reported as not existing.
```json
"fanpop": {
"errorType": "response_url",
"errorUrl": "http://www.fanpop.com/",
"rank": 9454,
"url": "http://www.fanpop.com/fans/{}",
"urlMain": "http://www.fanpop.com/",
"username_claimed": "blue",
"username_unclaimed": "noonewould_everusethis7"
},
```
## Canva
As of 2020-02-23, all usernames are reported as not existing.
@ -618,7 +602,7 @@ removed
## Coderwall
As of 2020-07-06, Coderwall returns false positives when checking for an username which contains a period.
I have tried to find out what Coderwall's criteria is for a valid username, but unfortunately I have not been able to
I have tried to find out what Coderwall's criteria is for a valid username, but unfortunately I have not been able to
find it and because of this, the best thing we can do now is to remove it.
```json
"Coderwall": {
@ -666,15 +650,15 @@ As of 2020-07-24, Zomato seems to be unstable. Majority of the time, Zomato take
## Mixer
As of 2020-07-22, the Mixer service has closed down.
```json
"mixer.com": {
"errorType": "status_code",
"rank": 1544,
"url": "https://mixer.com/{}",
"urlMain": "https://mixer.com/",
"urlProbe": "https://mixer.com/api/v1/channels/{}",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
"mixer.com": {
"errorType": "status_code",
"rank": 1544,
"url": "https://mixer.com/{}",
"urlMain": "https://mixer.com/",
"urlProbe": "https://mixer.com/api/v1/channels/{}",
"username_claimed": "blue",
"username_unclaimed": "noonewouldeverusethis7"
},
```
@ -1273,19 +1257,6 @@ As of 2022-05-1, FanCentro returns false positives. Will later in new version of
},
```
## Codeforces
As og 2022-05-01, Codeforces returns false positives
```json
"Codeforces": {
"errorType": "response_url",
"errorUrl": "https://codeforces.com/",
"url": "https://codeforces.com/profile/{}",
"urlMain": "https://www.codeforces.com/",
"username_claimed": "tourist",
"username_unclaimed": "noonewouldeverusethis789"
},
```
## Smashcast
As og 2022-05-01, Smashcast is down
```json
@ -1300,7 +1271,7 @@ As og 2022-05-01, Smashcast is down
## Countable
As og 2022-05-01, Countable returns false positives
As og 2022-05-01, Countable returns false positives
```json
"Countable": {
"errorType": "status_code",
@ -1867,4 +1838,160 @@ __2024-04-24 :__ BCF seems to have gone defunct. Uncertain.
"urlMain": "https://bitcoinforum.com",
"username_claimed": "bitcoinforum.com"
}
```
```
## Zhihu
As of 24.06.2024, Zhihu returns false positives as they obfuscate the code thats returned. Checking for patterns may allow us to find a way to detect the existans of a user, this will be need to be worked on later
```json
"Zhihu": {
"errorMsg": "用户不存在",
"errorType": "message",
"url": "https://www.zhihu.com/people/{}",
"urlMain": "https://www.zhihu.com/",
"username_claimed": "blue"
}
```
## Penetestit
As of 24.06.2024, Pentestit returns a 403. This is most likely due to a new site structures
```json
"labpentestit": {
"errorType": "response_url",
"errorUrl": "https://lab.pentestit.ru/{}",
"url": "https://lab.pentestit.ru/profile/{}",
"urlMain": "https://lab.pentestit.ru/",
"username_claimed": "CSV"
}
```
## Euw
__2024-06-09 :__ errorMsg detection doesn't work anymore, because the error message is included in HTTP request body, even in successful search
```json
"Euw": {
"errorMsg": "This summoner is not registered at OP.GG. Please check spelling.",
"errorType": "message",
"url": "https://euw.op.gg/summoner/userName={}",
"urlMain": "https://euw.op.gg/",
"username_claimed": "blue"
}
```
## Etsy
__2024-06-10 :__ Http request returns 403 forbidden, and tries to verify the connection, so it doesn't work anymore
```json
"Etsy": {
"errorType": "status_code",
"url": "https://www.etsy.com/shop/{}",
"urlMain": "https://www.etsy.com/",
"username_claimed": "JennyKrafts"
}
```
## Alik.cz
__2024-07-21 :__ Target is now BLACKLISTED from the default manifest due to the site recieving unnecessarily high traffic from Sherlock (by request of the site owners). This target is not permitted to be reactivited. Inclusion in unrelated manifests is not impacted, but it is discouraged.
## 8tracks
__2025-02-02 :__ Might be dead again. Nobody knows for sure.
```json
"8tracks": {
"errorType": "message",
"errorMsg": "\"available\":true",
"headers": {
"Accept-Language": "en-US,en;q=0.5"
},
"url": "https://8tracks.com/{}",
"urlProbe": "https://8tracks.com/users/check_username?login={}&format=jsonh",
"urlMain": "https://8tracks.com/",
"username_claimed": "blue"
}
```
## Shpock
__2025-02-02 :__ Can likely be added back with a new endpoint (source username availability endpoint from mobile app reg flow?)
```json
"Shpock": {
"errorType": "status_code",
"url": "https://www.shpock.com/shop/{}/items",
"urlMain": "https://www.shpock.com/",
"username_claimed": "user"
}
```
## Twitch
__2025-02-02 :__
```json
"Twitch": {
"errorType": "message",
"errorMsg": "components.availability-tracking.warn-unavailable.component",
"url": "https://www.twitch.tv/{}",
"urlMain": "https://www.twitch.tv/",
"urlProbe": "https://m.twitch.tv/{}",
"username_claimed": "jenny"
}
```
## Fiverr
__2025-02-02 :__ Fiverr added CSRF protections that messed with this test
```json
"Fiverr": {
"errorMsg": "\"status\":\"success\"",
"errorType": "message",
"headers": {
"Content-Type": "application/json",
"Accept-Language": "en-US,en;q=0.9"
},
"regexCheck": "^[A-Za-z][A-Za-z\\d_]{5,14}$",
"request_method": "POST",
"request_payload": {
"username": "{}"
},
"url": "https://www.fiverr.com/{}",
"urlMain": "https://www.fiverr.com/",
"urlProbe": "https://www.fiverr.com/validate_username",
"username_claimed": "blueman"
}
```
## BabyRU
__2025-02-02 :__ Just being problematic (possibly related to errorMsg encoding?)
```json
"babyRU": {
"errorMsg": [
"\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0438\u0441\u043a\u0430\u043b\u0438, \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430",
"Доступ с вашего IP-адреса временно ограничен"
],
"errorType": "message",
"url": "https://www.baby.ru/u/{}/",
"urlMain": "https://www.baby.ru/",
"username_claimed": "blue"
}
```
## v0.dev
__2025-02-16 :__ Unsure if any way to view profiles exists now
```json
"v0.dev": {
"errorType": "message",
"errorMsg": "<title>v0 by Vercel</title>",
"url": "https://v0.dev/{}",
"urlMain": "https://v0.dev",
"username_claimed": "t3dotgg"
}
```
## TorrentGalaxy
__2025-07-06 :__ Site appears to have gone offline in March and hasn't come back
```json
"TorrentGalaxy": {
"errorMsg": "<title>TGx:Can't show details</title>",
"errorType": "message",
"regexCheck": "^[A-Za-z0-9]{3,15}$",
"url": "https://torrentgalaxy.to/profile/{}",
"urlMain": "https://torrentgalaxy.to/",
"username_claimed": "GalaxyRG"
},
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

68
pyproject.toml Normal file
View File

@ -0,0 +1,68 @@
[build-system]
requires = [ "poetry-core>=1.2.0" ]
build-backend = "poetry.core.masonry.api"
# poetry-core 1.8 not available in .fc39. Can upgrade to 1.8.0 at .fc39 EOL
[tool.poetry-version-plugin]
source = "init"
[tool.poetry]
name = "sherlock-project"
version = "0.16.0"
description = "Hunt down social media accounts by username across social networks"
license = "MIT"
authors = [
"Siddharth Dushantha <siddharth.dushantha@gmail.com>"
]
maintainers = [
"Paul Pfeister <code@pfeister.dev>",
"Matheus Felipe <matheusfelipeog@protonmail.com>",
"Sondre Karlsen Dyrnes <sondre@villdyr.no>"
]
readme = "docs/pyproject/README.md"
packages = [ { include = "sherlock_project"} ]
keywords = [ "osint", "reconnaissance", "information gathering" ]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Security"
]
homepage = "https://sherlockproject.xyz/"
repository = "https://github.com/sherlock-project/sherlock"
[tool.poetry.urls]
"Bug Tracker" = "https://github.com/sherlock-project/sherlock/issues"
[tool.poetry.dependencies]
python = "^3.9"
certifi = ">=2019.6.16"
colorama = "^0.4.1"
PySocks = "^1.7.0"
requests = "^2.22.0"
requests-futures = "^1.0.0"
stem = "^1.8.0"
pandas = "^2.2.1"
openpyxl = "^3.0.10"
tomli = "^2.2.1"
[tool.poetry.group.dev.dependencies]
jsonschema = "^4.0.0"
rstr = "^3.2.2"
pytest = "^8.4.2"
pytest-xdist = "^3.8.0"
[tool.poetry.group.ci.dependencies]
defusedxml = "^0.7.1"
[tool.poetry.scripts]
sherlock = 'sherlock_project.sherlock:main'

7
pytest.ini Normal file
View File

@ -0,0 +1,7 @@
[pytest]
addopts = --strict-markers -m "not validate_targets"
markers =
online: mark tests are requiring internet access.
validate_targets: mark tests for sweeping manifest validation (sends many requests).
validate_targets_fp: validate_targets, false positive tests only.
validate_targets_fn: validate_targets, false negative tests only.

View File

@ -1,860 +0,0 @@
{
"AdobeForums": {
"errorType": "status_code",
"url": "https://forums.adobe.com/people/{}",
"urlMain": "https://forums.adobe.com/",
"username_claimed": "jack"
},
"AngelList": {
"errorType": "status_code",
"url": "https://angel.co/u/{}",
"urlMain": "https://angel.co/",
"username_claimed": "blue"
},
"Basecamp": {
"errorMsg": "The account you were looking for doesn't exist",
"errorType": "message",
"url": "https://{}.basecamphq.com",
"urlMain": "https://basecamp.com/",
"username_claimed": "blue"
},
"BlackPlanet": {
"errorMsg": "My Hits",
"errorType": "message",
"url": "http://blackplanet.com/{}",
"urlMain": "http://blackplanet.com/"
},
"Canva": {
"errorType": "response_url",
"errorUrl": "https://www.canva.com/{}",
"url": "https://www.canva.com/{}",
"urlMain": "https://www.canva.com/",
"username_claimed": "jenny"
},
"Codementor": {
"errorType": "status_code",
"url": "https://www.codementor.io/@{}",
"urlMain": "https://www.codementor.io/",
"username_claimed": "blue"
},
"EVE Online": {
"errorType": "response_url",
"errorUrl": "https://eveonline.com",
"url": "https://evewho.com/pilot/{}/",
"urlMain": "https://eveonline.com",
"username_claimed": "blue"
},
"fanpop": {
"errorType": "response_url",
"errorUrl": "http://www.fanpop.com/",
"url": "http://www.fanpop.com/fans/{}",
"urlMain": "http://www.fanpop.com/",
"username_claimed": "blue"
},
"Fotolog": {
"errorType": "status_code",
"url": "https://fotolog.com/{}",
"urlMain": "https://fotolog.com/"
},
"Foursquare": {
"errorType": "status_code",
"url": "https://foursquare.com/{}",
"urlMain": "https://foursquare.com/",
"username_claimed": "dens"
},
"gpodder.net": {
"errorType": "status_code",
"url": "https://gpodder.net/user/{}",
"urlMain": "https://gpodder.net/",
"username_claimed": "blue"
},
"Investing.com": {
"errorType": "status_code",
"url": "https://www.investing.com/traders/{}",
"urlMain": "https://www.investing.com/",
"username_claimed": "jenny"
},
"Khan Academy": {
"errorType": "status_code",
"url": "https://www.khanacademy.org/profile/{}",
"urlMain": "https://www.khanacademy.org/",
"username_claimed": "blue"
},
"KiwiFarms": {
"errorMsg": "The specified member cannot be found",
"errorType": "message",
"url": "https://kiwifarms.net/members/?username={}",
"urlMain": "https://kiwifarms.net/",
"username_claimed": "blue"
},
"NPM-Package": {
"errorType": "status_code",
"url": "https://www.npmjs.com/package/{}",
"urlMain": "https://www.npmjs.com/",
"username_claimed": "blue"
},
"Pexels": {
"errorType": "status_code",
"url": "https://www.pexels.com/@{}",
"urlMain": "https://www.pexels.com/",
"username_claimed": "bruno"
},
"Pixabay": {
"errorType": "status_code",
"url": "https://pixabay.com/en/users/{}",
"urlMain": "https://pixabay.com/",
"username_claimed": "blue"
},
"PowerShell Gallery": {
"errorType": "status_code",
"url": "https://www.powershellgallery.com/profiles/{}",
"urlMain": "https://www.powershellgallery.com",
"username_claimed": "powershellteam"
},
"RamblerDating": {
"errorType": "response_url",
"errorUrl": "https://dating.rambler.ru/page/{}",
"url": "https://dating.rambler.ru/page/{}",
"urlMain": "https://dating.rambler.ru/",
"username_claimed": "blue"
},
"Shockwave": {
"errorMsg": "Oh no! You just finished all of the games on the internet!",
"errorType": "message",
"url": "http://www.shockwave.com/member/profiles/{}.jsp",
"urlMain": "http://www.shockwave.com/",
"username_claimed": "blue"
},
"StreamMe": {
"errorType": "status_code",
"url": "https://www.stream.me/{}",
"urlMain": "https://www.stream.me/",
"username_claimed": "blue"
},
"Teknik": {
"errorMsg": "The user does not exist",
"errorType": "message",
"url": "https://user.teknik.io/{}",
"urlMain": "https://teknik.io/",
"username_claimed": "red"
},
"YandexMarket": {
"errorMsg": "\u0422\u0443\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u0442",
"errorType": "message",
"url": "https://market.yandex.ru/user/{}/achievements",
"urlMain": "https://market.yandex.ru/",
"username_claimed": "blue"
},
"Insanejournal": {
"errorMsg": "Unknown user",
"errorType": "message",
"url": "http://{}.insanejournal.com/profile",
"urlMain": "insanejournal.com",
"username_claimed": "blue"
},
"Trip": {
"errorType": "status_code",
"url": "https://www.trip.skyscanner.com/user/{}",
"urlMain": "https://www.trip.skyscanner.com/",
"username_claimed": "blue"
},
"SportsTracker": {
"errorUrl": "https://www.sports-tracker.com/page-not-found",
"errorType": "response_url",
"url": "https://www.sports-tracker.com/view_profile/{}",
"urlMain": "https://www.sports-tracker.com/",
"username_claimed": "blue"
},
"boingboing.net": {
"errorType": "status_code",
"url": "https://bbs.boingboing.net/u/{}",
"urlMain": "https://boingboing.net/",
"username_claimed": "admin"
},
"elwoRU": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d",
"errorType": "message",
"url": "https://elwo.ru/index/8-0-{}",
"urlMain": "https://elwo.ru/",
"username_claimed": "red"
},
"ingvarr.net.ru": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d",
"errorType": "message",
"url": "http://ingvarr.net.ru/index/8-0-{}",
"urlMain": "http://ingvarr.net.ru/",
"username_claimed": "red"
},
"Redsun.tf": {
"errorMsg": "The specified member cannot be found",
"errorType": "message",
"url": "https://forum.redsun.tf/members/?username={}",
"urlMain": "https://redsun.tf/",
"username_claimed": "dan"
},
"CreativeMarket": {
"errorType": "status_code",
"url": "https://creativemarket.com/users/{}",
"urlMain": "https://creativemarket.com/",
"username_claimed": "blue"
},
"pvpru": {
"errorType": "status_code",
"url": "https://pvpru.com/board/member.php?username={}&tab=aboutme#aboutme",
"urlMain": "https://pvpru.com/",
"username_claimed": "blue"
},
"easyen": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d",
"errorType": "message",
"url": "https://easyen.ru/index/8-0-{}",
"urlMain": "https://easyen.ru/",
"username_claimed": "wd"
},
"pedsovet": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d",
"errorType": "message",
"url": "http://pedsovet.su/index/8-0-{}",
"urlMain": "http://pedsovet.su/",
"username_claimed": "blue"
},
"radioskot": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d",
"errorType": "message",
"url": "https://radioskot.ru/index/8-0-{}",
"urlMain": "https://radioskot.ru/",
"username_claimed": "red"
},
"Coderwall": {
"errorMsg": "404! Our feels when that url is used",
"errorType": "message",
"url": "https://coderwall.com/{}",
"urlMain": "https://coderwall.com/",
"username_claimed": "jenny"
},
"TamTam": {
"errorType": "response_url",
"errorUrl": "https://tamtam.chat/",
"url": "https://tamtam.chat/{}",
"urlMain": "https://tamtam.chat/",
"username_claimed": "blue"
},
"Zomato": {
"errorType": "status_code",
"headers": {
"Accept-Language": "en-US,en;q=0.9"
},
"url": "https://www.zomato.com/pl/{}/foodjourney",
"urlMain": "https://www.zomato.com/",
"username_claimed": "deepigoyal"
},
"mixer.com": {
"errorType": "status_code",
"url": "https://mixer.com/{}",
"urlMain": "https://mixer.com/",
"urlProbe": "https://mixer.com/api/v1/channels/{}",
"username_claimed": "blue"
},
"KanoWorld": {
"errorType": "status_code",
"url": "https://api.kano.me/progress/user/{}",
"urlMain": "https://world.kano.me/",
"username_claimed": "blue"
},
"YandexCollection": {
"errorType": "status_code",
"url": "https://yandex.ru/collections/user/{}/",
"urlMain": "https://yandex.ru/collections/",
"username_claimed": "blue"
},
"PayPal": {
"errorMsg": "<meta name=\"twitter:title\" content=\"Get your very own PayPal.Me link\" />",
"errorType": "message",
"url": "https://www.paypal.com/paypalme/{}",
"headers": {
"User-Agent": ""
},
"urlMain": "https://www.paypal.me/",
"username_claimed": "blue"
},
"ImageShack": {
"errorType": "response_url",
"errorUrl": "https://imageshack.us/",
"url": "https://imageshack.us/user/{}",
"urlMain": "https://imageshack.us/",
"username_claimed": "blue"
},
"Aptoide": {
"errorType": "status_code",
"url": "https://{}.en.aptoide.com/",
"urlMain": "https://en.aptoide.com/",
"username_claimed": "blue"
},
"Crunchyroll": {
"errorType": "status_code",
"url": "https://www.crunchyroll.com/user/{}",
"urlMain": "https://www.crunchyroll.com/",
"username_claimed": "blue"
},
"T-MobileSupport": {
"errorType": "status_code",
"url": "https://support.t-mobile.com/people/{}",
"urlMain": "https://support.t-mobile.com",
"username_claimed": "blue"
},
"OpenCollective": {
"errorType": "status_code",
"url": "https://opencollective.com/{}",
"urlMain": "https://opencollective.com/",
"username_claimed": "sindresorhus"
},
"SegmentFault": {
"errorType": "status_code",
"url": "https://segmentfault.com/u/{}",
"urlMain": "https://segmentfault.com/",
"username_claimed": "bule"
},
"Viadeo": {
"errorType": "status_code",
"url": "http://fr.viadeo.com/en/profile/{}",
"urlMain": "http://fr.viadeo.com/en/",
"username_claimed": "franck.patissier"
},
"MeetMe": {
"errorType": "response_url",
"errorUrl": "https://www.meetme.com/",
"url": "https://www.meetme.com/{}",
"urlMain": "https://www.meetme.com/",
"username_claimed": "blue"
},
"tracr.co": {
"errorMsg": "No search results",
"errorType": "message",
"regexCheck": "^[A-Za-z0-9]{2,32}$",
"url": "https://tracr.co/users/1/{}",
"urlMain": "https://tracr.co/",
"username_claimed": "blue"
},
"Taringa": {
"errorType": "status_code",
"regexCheck": "^[^.]*$",
"url": "https://www.taringa.net/{}",
"urlMain": "https://taringa.net/",
"username_claimed": "blue"
},
"Photobucket": {
"errorType": "status_code",
"url": "https://photobucket.com/user/{}/library",
"urlMain": "https://photobucket.com/",
"username_claimed": "blue"
},
"4pda": {
"errorMsg": "[1,false,0]",
"errorType": "message",
"url": "https://4pda.ru/forum/index.php?act=search&source=pst&noform=1&username={}",
"urlMain": "https://4pda.ru/",
"urlProbe": " https://4pda.ru/forum/index.php?act=auth&action=chkname&login={}",
"username_claimed": "green"
},
"PokerStrategy": {
"errorType": "status_code",
"url": "http://www.pokerstrategy.net/user/{}/profile/",
"urlMain": "http://www.pokerstrategy.net",
"username_claimed": "blue"
},
"Filmogs": {
"errorType": "status_code",
"url": "https://www.filmo.gs/users/{}",
"urlMain": "https://www.filmo.gs/",
"username_claimed": "cupparober"
},
"500px": {
"errorMsg": "No message available",
"errorType": "message",
"url": "https://500px.com/p/{}",
"urlMain": "https://500px.com/",
"urlProbe": "https://api.500px.com/graphql?operationName=ProfileRendererQuery&variables=%7B%22username%22%3A%22{}%22%7D&extensions=%7B%22persistedQuery%22%3A%7B%22version%22%3A1%2C%22sha256Hash%22%3A%224d02ff5c13927a3ac73b3eef306490508bc765956940c31051468cf30402a503%22%7D%7D",
"username_claimed": "blue"
},
"Badoo": {
"errorType": "status_code",
"url": "https://badoo.com/profile/{}",
"urlMain": "https://badoo.com/",
"username_claimed": "blue"
},
"Pling": {
"errorMsg": "Resource not found",
"errorType": "message",
"url": "https://www.pling.com/u/{}/",
"urlMain": "https://www.pling.com/",
"username_claimed": "blue"
},
"Realmeye": {
"errorMsg": "Sorry, but we either:",
"errorType": "message",
"url": "https://www.realmeye.com/player/{}",
"urlMain": "https://www.realmeye.com/",
"username_claimed": "blue"
},
"Travellerspoint": {
"errorMsg": "Wooops. Sorry!",
"errorType": "message",
"url": "https://www.travellerspoint.com/users/{}",
"urlMain": "https://www.travellerspoint.com",
"username_claimed": "blue"
},
"GDProfiles": {
"errorType": "status_code",
"url": "https://gdprofiles.com/{}",
"urlMain": "https://gdprofiles.com/",
"username_claimed": "blue"
},
"AllTrails": {
"errorMsg": "class=\"home index\"",
"errorType": "message",
"url": "https://www.alltrails.com/members/{}",
"urlMain": "https://www.alltrails.com/",
"username_claimed": "blue"
},
"Cent": {
"errorMsg": "<title>Cent</title>",
"errorType": "message",
"url": "https://beta.cent.co/@{}",
"urlMain": "https://cent.co/",
"username_claimed": "blue"
},
"Anobii": {
"errorType": "response_url",
"url": "https://www.anobii.com/{}/profile",
"urlMain": "https://www.anobii.com/",
"username_claimed": "blue"
},
"Kali community": {
"errorMsg": "This user has not registered and therefore does not have a profile to view.",
"errorType": "message",
"url": "https://forums.kali.org/member.php?username={}",
"urlMain": "https://forums.kali.org/",
"username_claimed": "blue"
},
"NameMC (Minecraft.net skins)": {
"errorMsg": "Profiles: 0 results",
"errorType": "message",
"url": "https://namemc.com/profile/{}",
"urlMain": "https://namemc.com/",
"username_claimed": "blue"
},
"Steamid": {
"errorMsg": "<link rel=\"canonical\" href=\"https://steamid.uk\" />",
"errorType": "message",
"url": "https://steamid.uk/profile/{}",
"urlMain": "https://steamid.uk/",
"username_claimed": "blue"
},
"TripAdvisor": {
"errorMsg": "This page is on vacation\u2026",
"errorType": "message",
"url": "https://tripadvisor.com/members/{}",
"urlMain": "https://tripadvisor.com/",
"username_claimed": "blue"
},
"House-Mixes.com": {
"errorMsg": "Profile Not Found",
"errorType": "message",
"regexCheck": "^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$",
"url": "https://www.house-mixes.com/profile/{}",
"urlMain": "https://www.house-mixes.com/",
"username_claimed": "blue"
},
"Quora": {
"errorMsg": "Page Not Found",
"errorType": "message",
"url": "https://www.quora.com/profile/{}",
"urlMain": "https://www.quora.com/",
"username_claimed": "Matt-Riggsby"
},
"SparkPeople": {
"errorMsg": "We couldn't find that user",
"errorType": "message",
"url": "https://www.sparkpeople.com/mypage.asp?id={}",
"urlMain": "https://www.sparkpeople.com",
"username_claimed": "adam"
},
"Cloob": {
"errorType": "status_code",
"url": "https://www.cloob.com/name/{}",
"urlMain": "https://www.cloob.com/",
"username_claimed": "blue"
},
"TM-Ladder": {
"errorMsg": "player unknown or invalid",
"errorType": "message",
"url": "http://en.tm-ladder.com/{}_rech.php",
"urlMain": "http://en.tm-ladder.com/index.php",
"username_claimed": "blue"
},
"plug.dj": {
"errorType": "status_code",
"url": "https://plug.dj/@/{}",
"urlMain": "https://plug.dj/",
"username_claimed": "plug-dj-rock"
},
"Facenama": {
"errorType": "response_url",
"errorUrl": "https://facenama.com/404.html",
"regexCheck": "^[-a-zA-Z0-9_]+$",
"url": "https://facenama.com/{}",
"urlMain": "https://facenama.com/",
"username_claimed": "blue"
},
"Designspiration": {
"errorType": "status_code",
"url": "https://www.designspiration.net/{}/",
"urlMain": "https://www.designspiration.net/",
"username_claimed": "blue"
},
"CapFriendly": {
"errorMsg": "<div class=\"err show p5\">No results found</div>",
"errorType": "message",
"regexCheck": "^[a-zA-z][a-zA-Z0-9_]{2,79}$",
"url": "https://www.capfriendly.com/users/{}",
"urlMain": "https://www.capfriendly.com/",
"username_claimed": "thisactuallyexists"
},
"Gab": {
"errorMsg": "The page you are looking for isn't here.",
"errorType": "message",
"url": "https://gab.com/{}",
"urlMain": "https://gab.com",
"username_claimed": "a"
},
"FanCentro": {
"errorMsg": "var environment",
"errorType": "message",
"url": "https://fancentro.com/{}",
"urlMain": "https://fancentro.com/",
"username_claimed": "nielsrosanna"
},
"Codeforces": {
"errorType": "response_url",
"errorUrl": "https://codeforces.com/",
"url": "https://codeforces.com/profile/{}",
"urlMain": "https://www.codeforces.com/",
"username_claimed": "tourist"
},
"Smashcast": {
"errorType": "status_code",
"url": "https://www.smashcast.tv/api/media/live/{}",
"urlMain": "https://www.smashcast.tv/",
"username_claimed": "hello"
},
"Countable": {
"errorType": "status_code",
"url": "https://www.countable.us/{}",
"urlMain": "https://www.countable.us/",
"username_claimed": "blue"
},
"Spotify": {
"errorType": "status_code",
"url": "https://open.spotify.com/user/{}",
"urlMain": "https://open.spotify.com/",
"username_claimed": "blue"
},
"Raidforums": {
"errorType": "status_code",
"url": "https://raidforums.com/User-{}",
"urlMain": "https://raidforums.com/",
"username_claimed": "red"
},
"Pinterest": {
"errorType": "status_code",
"url": "https://www.pinterest.com/{}/",
"urlMain": "https://www.pinterest.com/",
"username_claimed": "blue"
},
"PCPartPicker": {
"errorType": "status_code",
"url": "https://pcpartpicker.com/user/{}",
"urlMain": "https://pcpartpicker.com",
"username_claimed": "blue"
},
"eBay.com": {
"errorMsg": "The User ID you entered was not found. Please check the User ID and try again.",
"errorType": "message",
"url": "https://www.ebay.com/usr/{}",
"urlMain": "https://www.ebay.com/",
"username_claimed": "blue"
},
"eBay.de": {
"errorMsg": "Der eingegebene Nutzername wurde nicht gefunden. Bitte pr\u00fcfen Sie den Nutzernamen und versuchen Sie es erneut.",
"errorType": "message",
"url": "https://www.ebay.de/usr/{}",
"urlMain": "https://www.ebay.de/",
"username_claimed": "blue"
},
"Ghost": {
"errorMsg": "Domain Error",
"errorType": "message",
"url": "https://{}.ghost.io/",
"urlMain": "https://ghost.org/",
"username_claimed": "troyhunt"
},
"Atom Discussions": {
"errorMsg": "Oops! That page doesn\u2019t exist or is private.",
"errorType": "message",
"url": "https://discuss.atom.io/u/{}/summary",
"urlMain": "https://discuss.atom.io",
"username_claimed": "blue"
},
"Gam1ng": {
"errorType": "status_code",
"url": "https://gam1ng.com.br/user/{}",
"urlMain": "https://gam1ng.com.br",
"username_claimed": "PinKgirl"
},
"OGUsers": {
"errorType": "status_code",
"url": "https://ogusers.com/{}",
"urlMain": "https://ogusers.com/",
"username_claimed": "ogusers"
},
"Otzovik": {
"errorType": "status_code",
"url": "https://otzovik.com/profile/{}",
"urlMain": "https://otzovik.com/",
"username_claimed": "blue"
},
"radio_echo_msk": {
"errorType": "status_code",
"url": "https://echo.msk.ru/users/{}",
"urlMain": "https://echo.msk.ru/",
"username_claimed": "blue"
},
"Ello": {
"errorMsg": "We couldn't find the page you're looking for",
"errorType": "message",
"url": "https://ello.co/{}",
"urlMain": "https://ello.co/",
"username_claimed": "blue"
},
"GitHub Support Community": {
"errorMsg": "Oops! That page doesn\u2019t exist or is private.",
"errorType": "message",
"url": "https://github.community/u/{}/summary",
"urlMain": "https://github.community",
"username_claimed": "jperl"
},
"GuruShots": {
"errorType": "status_code",
"url": "https://gurushots.com/{}/photos",
"urlMain": "https://gurushots.com/",
"username_claimed": "blue"
},
"Google Developer": {
"errorMsg": "Sorry, the profile was not found.",
"errorType": "message",
"url": "https://g.dev/{}",
"urlMain": "https://g.dev/",
"username_claimed": "blue"
},
"mastodon.technology": {
"errorType": "status_code",
"url": "https://mastodon.technology/@{}",
"urlMain": "https://mastodon.xyz/",
"username_claimed": "ashfurrow"
},
"zoomit": {
"errorMsg": "\u0645\u062a\u0627\u0633\u0641\u0627\u0646\u0647 \u0635\u0641\u062d\u0647 \u06cc\u0627\u0641\u062a \u0646\u0634\u062f",
"errorType": "message",
"url": "https://www.zoomit.ir/user/{}",
"urlMain": "https://www.zoomit.ir",
"username_claimed": "kossher"
},
"Facebook": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9\\.]{3,49}(?<!\\.com|\\.org|\\.net)$",
"url": "https://www.facebook.com/{}",
"urlMain": "https://www.facebook.com/",
"urlProbe": "https://www.facebook.com/{}/videos/",
"username_claimed": "hackerman"
},
"BinarySearch": {
"errorMsg": "{}",
"errorType": "message",
"regexCheck": "^[a-zA-Z0-9-_]{1,15}$",
"url": "https://binarysearch.io/@/{}",
"urlMain": "https://binarysearch.io/",
"urlProbe": "https://binarysearch.io/api/users/{}/profile",
"username_claimed": "Eyes_Wide_Shut"
},
"Arduino": {
"errorType": "status_code",
"regexCheck": "^(?![_-])[A-Za-z0-9_-]{3,}$",
"url": "https://create.arduino.cc/projecthub/{}",
"urlMain": "https://www.arduino.cc/",
"username_claimed": "blue"
},
"koo": {
"errorMsg": "This profile does not exist",
"errorType": "message",
"url": "https://www.kooapp.com/profile/{}",
"urlMain": "https://www.kooapp.com",
"urlProbe": "https://www.kooapp.com/apiV1/users/handle/{}/valid",
"username_claimed": "john"
},
"We Heart It": {
"errorMsg": "Oops! You've landed on a moving target!",
"errorType": "message",
"url": "https://weheartit.com/{}",
"urlMain": "https://weheartit.com/",
"username_claimed": "ventivogue"
},
"Tinder": {
"errorMsg": [
"<title data-react-helmet=\"true\">Tinder | Dating, Make Friends &amp; Meet New People</title>",
"<title data-react-helmet=\"true\">Tinder | Match. Chat. Date.</title>"
],
"errorType": "message",
"url": "https://www.tinder.com/@{}",
"urlMain": "https://tinder.com/",
"username_claimed": "blue"
},
"Coil": {
"errorMsg": "User not found",
"errorType": "message",
"request_method": "POST",
"request_payload": {
"operationName": "getCreator",
"query": "query getCreator($userShortName:String!){getCreator(userShortName:$userShortName){id}}",
"variables": {
"userShortName": "{}"
}
},
"url": "https://coil.com/u/{}",
"urlMain": "https://coil.com/",
"urlProbe": "https://coil.com/gateway",
"username_claimed": "adam"
},
"OnlyFans": {
"errorType": "status_code",
"isNSFW": true,
"url": "https://onlyfans.com/{}",
"urlMain": "https://onlyfans.com/",
"urlProbe": "https://onlyfans.com/api2/v2/users/{}",
"username_claimed": "theemilylynne"
},
"OK": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z][a-zA-Z0-9_.-]*$",
"url": "https://ok.ru/{}",
"urlMain": "https://ok.ru/",
"username_claimed": "ok"
},
"forumhouseRU": {
"errorMsg": "\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f.",
"errorType": "message",
"url": "https://www.forumhouse.ru/members/?username={}",
"urlMain": "https://www.forumhouse.ru/",
"username_claimed": "red"
},
"Enjin": {
"errorMsg": "Yikes, there seems to have been an error. We've taken note and will check out the problem right away!",
"errorType": "message",
"url": "https://www.enjin.com/profile/{}",
"urlMain": "https://www.enjin.com/",
"username_claimed": "blue"
},
"IRL": {
"errorType": "status_code",
"url": "https://www.irl.com/{}",
"urlMain": "https://www.irl.com/",
"username_claimed": "hacker"
},
"Munzee": {
"errorType": "status_code",
"url": "https://www.munzee.com/m/{}",
"urlMain": "https://www.munzee.com/",
"username_claimed": "blue"
},
"Quizlet": {
"errorMsg": "Page Unavailable",
"errorType": "message",
"url": "https://quizlet.com/{}",
"urlMain": "https://quizlet.com",
"username_claimed": "blue"
},
"GunsAndAmmo": {
"errorType": "status_code",
"url": "https://forums.gunsandammo.com/profile/{}",
"urlMain": "https://gunsandammo.com/",
"username_claimed": "adam"
},
"TikTok": {
"errorType": "status_code",
"url": "https://tiktok.com/@{}",
"urlMain": "https://tiktok.com/",
"username_claimed": "red"
},
"Lolchess": {
"errorMsg": "No search results",
"errorType": "message",
"url": "https://lolchess.gg/profile/na/{}",
"urlMain": "https://lolchess.gg/",
"username_claimed": "blue"
},
"Virgool": {
"errorMsg": "\u06f4\u06f0\u06f4",
"errorType": "message",
"url": "https://virgool.io/@{}",
"urlMain": "https://virgool.io/",
"username_claimed": "blue"
},
"Whonix Forum": {
"errorType": "status_code",
"url": "https://forums.whonix.org/u/{}/summary",
"urlMain": "https://forums.whonix.org/",
"username_claimed": "red"
},
"ebio.gg": {
"errorType": "status_code",
"url": "https://ebio.gg/{}",
"urlMain": "https:/ebio.gg",
"username_claimed": "dev"
},
"metacritic": {
"errorMsg": "User not found",
"errorType": "message",
"regexCheck": "^(?![-_].)[A-Za-z0-9-_]{3,15}$",
"url": "https://www.metacritic.com/user/{}",
"urlMain": "https://www.metacritic.com/",
"username_claimed": "blue"
},
"Oracle Communities": {
"errorType": "status_code",
"url": "https://community.oracle.com/people/{}",
"urlMain": "https://community.oracle.com",
"username_claimed": "dev"
},
"HexRPG": {
"errorMsg": "Error : User ",
"errorType": "message",
"regexCheck": "^[a-zA-Z0-9_ ]{3,20}$",
"url": "https://www.hexrpg.com/userinfo/{}",
"urlMain": "https://www.hexrpg.com/",
"username_claimed": "blue"
},
"G2G": {
"errorType": "response_url",
"errorUrl": "https://www.g2g.com/{}",
"regexCheck": "^[A-Za-z][A-Za-z0-9_]{2,11}$",
"url": "https://www.g2g.com/{}",
"urlMain": "https://www.g2g.com/",
"username_claimed": "user"
},
"BitCoinForum": {
"errorMsg": "The user whose profile you are trying to view does not exist.",
"errorType": "message",
"url": "https://bitcoinforum.com/profile/{}",
"urlMain": "https://bitcoinforum.com",
"username_claimed": "bitcoinforum.com"
}
}

View File

@ -1,10 +0,0 @@
certifi>=2019.6.16
colorama>=0.4.1
PySocks>=1.7.0
requests>=2.22.0
requests-futures>=1.0.0
stem>=1.8.0
torrequest>=0.1.0
pandas>=1.0.0
openpyxl<=3.0.10
exrex>=0.11.0

View File

@ -1,6 +0,0 @@
""" Sherlock Module
This module contains the main logic to search for usernames at social
networks.
"""

View File

@ -1,80 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Sherlock Targets",
"description": "Social media target to probe for existence of usernames",
"type": "object",
"properties": {
"$schema": { "type": "string" }
},
"patternProperties": {
"^(?!\\$).*?$": {
"type": "object",
"description": "User-friendly target name",
"required": [ "url", "urlMain", "errorType", "username_claimed" ],
"properties": {
"url": { "type": "string" },
"urlMain": { "type": "string" },
"urlProbe": { "type": "string" },
"username_claimed": { "type": "string" },
"regexCheck": { "type": "string" },
"isNSFW": { "type": "boolean" },
"headers": { "type": "object" },
"request_payload": { "type": "object" },
"__comment__": {
"type": "string",
"description": "Used to clarify important target information if (and only if) a commit message would not suffice.\nThis key should not be parsed anywhere within Sherlock."
},
"tags": {
"oneOf": [
{ "$ref": "#/$defs/tag" },
{ "type": "array", "items": { "$ref": "#/$defs/tag" } }
]
},
"request_method": {
"type": "string",
"enum": [ "GET", "POST", "HEAD", "PUT" ]
},
"errorType": {
"type": "string",
"enum": [ "message", "response_url", "status_code" ]
},
"errorMsg": {
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"errorCode": {
"oneOf": [
{ "type": "integer" },
{ "type": "array", "items": { "type": "integer" } }
]
},
"errorUrl": { "type": "string" },
"response_url": { "type": "string" }
},
"dependencies": {
"errorMsg": {
"properties" : { "errorType": { "const": "message" } }
},
"errorUrl": {
"properties": { "errorType": { "const": "response_url" } }
},
"errorCode": {
"properties": { "errorType": { "const": "status_code" } }
}
},
"if": { "properties": { "errorType": { "const": "message" } } },
"then": { "required": [ "errorMsg" ] },
"else": {
"if": { "properties": { "errorType": { "const": "response_url" } } },
"then": { "required": [ "errorUrl" ] }
},
"additionalProperties": false
}
},
"additionalProperties": false,
"$defs": {
"tag": { "type": "string", "enum": [ "adult", "gaming" ] }
}
}

View File

@ -1,4 +0,0 @@
"""Sherlock Tests
This package contains various submodules used to run tests.
"""

View File

@ -1,213 +0,0 @@
"""Sherlock Tests
This module contains various tests.
"""
from tests.base import SherlockBaseTest
import exrex
class SherlockDetectTests(SherlockBaseTest):
def test_detect_true_via_message(self):
"""Test Username Does Exist (Via Message).
This test ensures that the "message" detection mechanism of
ensuring that a Username does exist works properly.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
site = "AllMyLinks"
site_data = self.site_data_all[site]
# Ensure that the site's detection method has not changed.
self.assertEqual("message", site_data["errorType"])
self.username_check([site_data["username_claimed"]], [site], exist_check=True)
return
def test_detect_false_via_message(self):
"""Test Username Does Not Exist (Via Message).
This test ensures that the "message" detection mechanism of
ensuring that a Username does *not* exist works properly.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
site = "AllMyLinks"
site_data = self.site_data_all[site]
# Ensure that the site's detection method has not changed.
self.assertEqual("message", site_data["errorType"])
# Generate a valid username based on the regex for a username that the
# site supports that is *most likely* not taken. The regex is slightly
# modified version of site_data["regexCheck"] as we want a username
# that has the maximum length that is supported by the site. This way,
# we wont generate a random username that might actually exist. This
# method is very hacky, but it does the job as having hardcoded
# usernames that dont exists will lead to people with ill intent to
# create an account with that username which will break the tests
valid_username = exrex.getone(r"^[a-z0-9][a-z0-9-]{32}$")
self.username_check([valid_username], [site], exist_check=False)
return
def test_detect_true_via_status_code(self):
"""Test Username Does Exist (Via Status Code).
This test ensures that the "status code" detection mechanism of
ensuring that a Username does exist works properly.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
site = "BitBucket"
site_data = self.site_data_all[site]
# Ensure that the site's detection method has not changed.
self.assertEqual("status_code", site_data["errorType"])
self.username_check([site_data["username_claimed"]], [site], exist_check=True)
return
def test_detect_false_via_status_code(self):
"""Test Username Does Not Exist (Via Status Code).
This test ensures that the "status code" detection mechanism of
ensuring that a Username does *not* exist works properly.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
site = "BitBucket"
site_data = self.site_data_all[site]
# Ensure that the site's detection method has not changed.
self.assertEqual("status_code", site_data["errorType"])
# Generate a valid username based on the regex for a username that the
# site supports that is *most likely* not taken. The regex is slightly
# modified version of site_data["regexCheck"] as we want a username
# that has the maximum length that is supported by the site. This way,
# we wont generate a random username that might actually exist. This
# method is very hacky, but it does the job as having hardcoded
# usernames that dont exists will lead to people with ill intent to
# create an account with that username which will break the tests
valid_username = exrex.getone(r"^[a-zA-Z0-9-_]{30}")
self.username_check([valid_username], [site], exist_check=False)
return
class SherlockSiteCoverageTests(SherlockBaseTest):
def test_coverage_false_via_status(self):
"""Test Username Does Not Exist Site Coverage (Via HTTP Status).
This test checks all sites with the "HTTP Status" detection mechanism
to ensure that a Username that does not exist is reported that way.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
self.detect_type_check("status_code", exist_check=False)
return
def test_coverage_true_via_status(self):
"""Test Username Does Exist Site Coverage (Via HTTP Status).
This test checks all sites with the "HTTP Status" detection mechanism
to ensure that a Username that does exist is reported that way.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
self.detect_type_check("status_code", exist_check=True)
return
def test_coverage_false_via_message(self):
"""Test Username Does Not Exist Site Coverage (Via Error Message).
This test checks all sites with the "Error Message" detection mechanism
to ensure that a Username that does not exist is reported that way.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
self.detect_type_check("message", exist_check=False)
return
def test_coverage_true_via_message(self):
"""Test Username Does Exist Site Coverage (Via Error Message).
This test checks all sites with the "Error Message" detection mechanism
to ensure that a Username that does exist is reported that way.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if detection mechanism did not work as expected.
"""
self.detect_type_check("message", exist_check=True)
return
def test_coverage_total(self):
"""Test Site Coverage Is Total.
This test checks that all sites have test data available.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Will trigger an assert if we do not have total coverage.
"""
self.coverage_total_check()
return

View File

@ -1,224 +0,0 @@
"""Sherlock Base Tests
This module contains various utilities for running tests.
"""
import os
import os.path
import unittest
import sherlock
from result import QueryStatus
from notify import QueryNotify
from sites import SitesInformation
import warnings
class SherlockBaseTest(unittest.TestCase):
def setUp(self):
"""Sherlock Base Test Setup.
Does common setup tasks for base Sherlock tests.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
"""
# This ignores the ResourceWarning from an unclosed SSLSocket.
# TODO: Figure out how to fix the code so this is not needed.
warnings.simplefilter("ignore", ResourceWarning)
# Create object with all information about sites we are aware of.
sites = SitesInformation(data_file_path=os.path.join(os.path.dirname(__file__), "../resources/data.json"))
# Create original dictionary from SitesInformation() object.
# Eventually, the rest of the code will be updated to use the new object
# directly, but this will glue the two pieces together.
site_data_all = {}
for site in sites:
site_data_all[site.name] = site.information
self.site_data_all = site_data_all
# Load excluded sites list, if any
excluded_sites_path = os.path.join(os.path.dirname(os.path.realpath(sherlock.__file__)), "tests/.excluded_sites")
try:
with open(excluded_sites_path, "r", encoding="utf-8") as excluded_sites_file:
self.excluded_sites = excluded_sites_file.read().splitlines()
except FileNotFoundError:
self.excluded_sites = []
# Create notify object for query results.
self.query_notify = QueryNotify()
self.tor = False
self.unique_tor = False
self.timeout = None
self.skip_error_sites = True
return
def site_data_filter(self, site_list):
"""Filter Site Data.
Keyword Arguments:
self -- This object.
site_list -- List of strings corresponding to sites which
should be filtered.
Return Value:
Dictionary containing sub-set of site data specified by "site_list".
"""
# Create new dictionary that has filtered site data based on input.
# Note that any site specified which is not understood will generate
# an error.
site_data = {}
for site in site_list:
with self.subTest(f"Checking test vector Site '{site}' "
f"exists in total site data."
):
site_data[site] = self.site_data_all[site]
return site_data
def username_check(self, username_list, site_list, exist_check=True):
"""Username Exist Check.
Keyword Arguments:
self -- This object.
username_list -- List of strings corresponding to usernames
which should exist on *all* of the sites.
site_list -- List of strings corresponding to sites which
should be filtered.
exist_check -- Boolean which indicates if this should be
a check for Username existence,
or non-existence.
Return Value:
Nothing.
Will trigger an assert if Username does not have the expected
existence state.
"""
# Filter all site data down to just what is needed for this test.
site_data = self.site_data_filter(site_list)
if exist_check:
check_type_text = "claimed"
exist_result_desired = QueryStatus.CLAIMED
else:
check_type_text = "available"
exist_result_desired = QueryStatus.AVAILABLE
for username in username_list:
results = sherlock.sherlock(username,
site_data,
self.query_notify,
tor=self.tor,
unique_tor=self.unique_tor,
timeout=self.timeout
)
for site, result in results.items():
with self.subTest(f"Checking Username '{username}' "
f"{check_type_text} on Site '{site}'"
):
if (
(self.skip_error_sites == True) and
(result["status"].status == QueryStatus.UNKNOWN)
):
#Some error connecting to site.
self.skipTest(f"Skipping Username '{username}' "
f"{check_type_text} on Site '{site}': "
f"Site returned error status."
)
self.assertEqual(exist_result_desired,
result["status"].status)
return
def detect_type_check(self, detect_type, exist_check=True):
"""Username Exist Check.
Keyword Arguments:
self -- This object.
detect_type -- String corresponding to detection algorithm
which is desired to be tested.
Note that only sites which have documented
usernames which exist and do not exist
will be tested.
exist_check -- Boolean which indicates if this should be
a check for Username existence,
or non-existence.
Return Value:
Nothing.
Runs tests on all sites using the indicated detection algorithm
and which also has test vectors specified.
Will trigger an assert if Username does not have the expected
existence state.
"""
# Dictionary of sites that should be tested for having a username.
# This will allow us to test sites with a common username in parallel.
sites_by_username = {}
for site, site_data in self.site_data_all.items():
if (
(site in self.excluded_sites) or
(site_data["errorType"] != detect_type) or
(site_data.get("username_claimed") is None) or
(site_data.get("username_unclaimed") is None)
):
# This is either not a site we are interested in, or the
# site does not contain the required information to do
# the tests.
pass
else:
# We should run a test on this site.
# Figure out which type of user
if exist_check:
username = site_data.get("username_claimed")
else:
username = site_data.get("username_unclaimed")
# Add this site to the list of sites corresponding to this
# username.
if username in sites_by_username:
sites_by_username[username].append(site)
else:
sites_by_username[username] = [site]
# Check on the username availability against all of the sites.
for username, site_list in sites_by_username.items():
self.username_check([username],
site_list,
exist_check=exist_check
)
return
def coverage_total_check(self):
"""Total Coverage Check.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
Counts up all Sites with full test data available.
Will trigger an assert if any Site does not have test coverage.
"""
site_no_tests_list = []
for site, site_data in self.site_data_all.items():
if site_data.get("username_claimed") is None:
# Test information not available on this site.
site_no_tests_list.append(site)
self.assertEqual("", ", ".join(site_no_tests_list))
return

View File

@ -1,29 +0,0 @@
import importlib
import unittest
import sys
sys.path.append('../')
import sherlock as sh
checksymbols = []
checksymbols = ["_", "-", "."]
"""Test for multiple usernames.
This test ensures that the function multiple_usernames works properly. More specific,
different scenarios are tested and only usernames that contain this specific sequence: {?}
should return positive.
Keyword Arguments:
self -- This object.
Return Value:
Nothing.
"""
class TestMultipleUsernames(unittest.TestCase):
def test_area(self):
test_usernames = ["test{?}test" , "test{?feo" , "test"]
for name in test_usernames:
if(sh.check_for_parameter(name)):
self.assertAlmostEqual(sh.multiple_usernames(name), ["test_test" , "test-test" , "test.test"])
else:
self.assertAlmostEqual(name, name)

View File

@ -0,0 +1,30 @@
""" Sherlock Module
This module contains the main logic to search for usernames at social
networks.
"""
from importlib.metadata import version as pkg_version, PackageNotFoundError
import pathlib
import tomli
def get_version() -> str:
"""Fetch the version number of the installed package."""
try:
return pkg_version("sherlock_project")
except PackageNotFoundError:
pyproject_path: pathlib.Path = pathlib.Path(__file__).resolve().parent.parent / "pyproject.toml"
with pyproject_path.open("rb") as f:
pyproject_data = tomli.load(f)
return pyproject_data["tool"]["poetry"]["version"]
# This variable is only used to check for ImportErrors induced by users running as script rather than as module or package
import_error_test_var = None
__shortname__ = "Sherlock"
__longname__ = "Sherlock: Find Usernames Across Social Networks"
__version__ = get_version()
forge_api_latest_release = "https://api.github.com/repos/sherlock-project/sherlock/releases/latest"

View File

@ -14,9 +14,9 @@ if __name__ == "__main__":
# Check if the user is using the correct version of Python
python_version = sys.version.split()[0]
if sys.version_info < (3, 6):
print(f"Sherlock requires Python 3.6+\nYou are using Python {python_version}, which is not supported by Sherlock.")
if sys.version_info < (3, 9):
print(f"Sherlock requires Python 3.9+\nYou are using Python {python_version}, which is not supported by Sherlock.")
sys.exit(1)
import sherlock
from sherlock_project import sherlock
sherlock.main()

View File

@ -3,7 +3,7 @@
This module defines the objects for notifying the caller about the
results of queries.
"""
from result import QueryStatus
from sherlock_project.result import QueryStatus
from colorama import Fore, Style
import webbrowser

View File

View File

@ -0,0 +1,149 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Sherlock Target Manifest",
"description": "Social media targets to probe for the existence of known usernames",
"type": "object",
"properties": {
"$schema": { "type": "string" }
},
"patternProperties": {
"^(?!\\$).*?$": {
"type": "object",
"description": "Target name and associated information (key should be human readable name)",
"required": ["url", "urlMain", "errorType", "username_claimed"],
"properties": {
"url": { "type": "string" },
"urlMain": { "type": "string" },
"urlProbe": { "type": "string" },
"username_claimed": { "type": "string" },
"regexCheck": { "type": "string" },
"isNSFW": { "type": "boolean" },
"headers": { "type": "object" },
"request_payload": { "type": "object" },
"__comment__": {
"type": "string",
"description": "Used to clarify important target information if (and only if) a commit message would not suffice.\nThis key should not be parsed anywhere within Sherlock."
},
"tags": {
"oneOf": [
{ "$ref": "#/$defs/tag" },
{ "type": "array", "items": { "$ref": "#/$defs/tag" } }
]
},
"request_method": {
"type": "string",
"enum": ["GET", "POST", "HEAD", "PUT"]
},
"errorType": {
"oneOf": [
{
"type": "string",
"enum": ["message", "response_url", "status_code"]
},
{
"type": "array",
"items": {
"type": "string",
"enum": ["message", "response_url", "status_code"]
}
}
]
},
"errorMsg": {
"oneOf": [
{ "type": "string" },
{ "type": "array", "items": { "type": "string" } }
]
},
"errorCode": {
"oneOf": [
{ "type": "integer" },
{ "type": "array", "items": { "type": "integer" } }
]
},
"errorUrl": { "type": "string" },
"response_url": { "type": "string" }
},
"dependencies": {
"errorMsg": {
"oneOf": [
{ "properties": { "errorType": { "const": "message" } } },
{
"properties": {
"errorType": {
"type": "array",
"contains": { "const": "message" }
}
}
}
]
},
"errorUrl": {
"oneOf": [
{ "properties": { "errorType": { "const": "response_url" } } },
{
"properties": {
"errorType": {
"type": "array",
"contains": { "const": "response_url" }
}
}
}
]
},
"errorCode": {
"oneOf": [
{ "properties": { "errorType": { "const": "status_code" } } },
{
"properties": {
"errorType": {
"type": "array",
"contains": { "const": "status_code" }
}
}
}
]
}
},
"allOf": [
{
"if": {
"anyOf": [
{ "properties": { "errorType": { "const": "message" } } },
{
"properties": {
"errorType": {
"type": "array",
"contains": { "const": "message" }
}
}
}
]
},
"then": { "required": ["errorMsg"] }
},
{
"if": {
"anyOf": [
{ "properties": { "errorType": { "const": "response_url" } } },
{
"properties": {
"errorType": {
"type": "array",
"contains": { "const": "response_url" }
}
}
}
]
},
"then": { "required": ["errorUrl"] }
}
],
"additionalProperties": false
}
},
"additionalProperties": false,
"$defs": {
"tag": { "type": "string", "enum": ["adult", "gaming"] }
}
}

View File

@ -7,30 +7,43 @@ This module contains the main logic to search for usernames at social
networks.
"""
import sys
try:
from sherlock_project.__init__ import import_error_test_var # noqa: F401
except ImportError:
print("Did you run Sherlock with `python3 sherlock/sherlock.py ...`?")
print("This is an outdated method. Please see https://sherlockproject.xyz/installation for up to date instructions.")
sys.exit(1)
import csv
import signal
import pandas as pd
import os
import platform
import re
import sys
from argparse import ArgumentParser, RawDescriptionHelpFormatter
from json import loads as json_loads
from time import monotonic
from typing import Optional
import requests
from requests_futures.sessions import FuturesSession
from torrequest import TorRequest
from result import QueryStatus
from result import QueryResult
from notify import QueryNotifyPrint
from sites import SitesInformation
from sherlock_project.__init__ import (
__longname__,
__shortname__,
__version__,
forge_api_latest_release,
)
from sherlock_project.result import QueryStatus
from sherlock_project.result import QueryResult
from sherlock_project.notify import QueryNotify
from sherlock_project.notify import QueryNotifyPrint
from sherlock_project.sites import SitesInformation
from colorama import init
from argparse import ArgumentTypeError
module_name = "Sherlock: Find Usernames Across Social Networks"
__version__ = "0.14.4"
class SherlockFuturesSession(FuturesSession):
def request(self, method, url, hooks=None, *args, **kwargs):
@ -143,7 +156,6 @@ def check_for_parameter(username):
return "{?}" in username
checksymbols = []
checksymbols = ["_", "-", "."]
@ -156,14 +168,13 @@ def multiple_usernames(username):
def sherlock(
username,
site_data,
query_notify,
tor=False,
unique_tor=False,
proxy=None,
timeout=60,
):
username: str,
site_data: dict[str, dict[str, str]],
query_notify: QueryNotify,
dump_response: bool = False,
proxy: Optional[str] = None,
timeout: int = 60,
) -> dict[str, dict[str, str | QueryResult]]:
"""Run Sherlock Analysis.
Checks for existence of username on various social media sites.
@ -175,8 +186,6 @@ def sherlock(
query_notify -- Object with base type of QueryNotify().
This will be used to notify the caller about
query results.
tor -- Boolean indicating whether to use a tor circuit for the requests.
unique_tor -- Boolean indicating whether to use a new tor circuit for each request.
proxy -- String indicating the proxy URL
timeout -- Time in seconds to wait before timing out request.
Default is 60 seconds.
@ -197,15 +206,9 @@ def sherlock(
# Notify caller that we are starting the query.
query_notify.start(username)
# Create session based on request methodology
if tor or unique_tor:
# Requests using Tor obfuscation
underlying_request = TorRequest()
underlying_session = underlying_request.session
else:
# Normal requests
underlying_session = requests.session()
underlying_request = requests.Request()
# Normal requests
underlying_session = requests.session()
# Limit number of workers to 20.
# This is probably vastly overkill.
@ -232,7 +235,7 @@ def sherlock(
# A user agent is needed because some sites don't return the correct
# information since they think that we are bots (Which we actually are...)
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:129.0) Gecko/20100101 Firefox/129.0",
}
if "headers" in net_info:
@ -329,15 +332,10 @@ def sherlock(
# Store future in data for access later
net_info["request_future"] = future
# Reset identify for tor (if needed)
if unique_tor:
underlying_request.reset_identity()
# Add this site's results into final dictionary with all the other results.
results_total[social_network] = results_site
# Open the file containing account links
# Core logic: If tor requests, make them here. If multi-threaded requests, wait for responses
for social_network, net_info in site_data.items():
# Retrieve results again
results_site = results_total.get(social_network)
@ -351,6 +349,8 @@ def sherlock(
# Get the expected error type
error_type = net_info["errorType"]
if isinstance(error_type, str):
error_type: list[str] = [error_type]
# Retrieve future and ensure it has finished
future = net_info["request_future"]
@ -377,12 +377,16 @@ def sherlock(
query_status = QueryStatus.UNKNOWN
error_context = None
# As WAFs advance and evolve, they will occasionally block Sherlock and lead to false positives
# and negatives. Fingerprints should be added here to filter results that fail to bypass WAFs.
# Fingerprints should be highly targetted. Comment at the end of each fingerprint to indicate target and date.
# As WAFs advance and evolve, they will occasionally block Sherlock and
# lead to false positives and negatives. Fingerprints should be added
# here to filter results that fail to bypass WAFs. Fingerprints should
# be highly targetted. Comment at the end of each fingerprint to
# indicate target and date fingerprinted.
WAFHitMsgs = [
'.loading-spinner{visibility:hidden}body.no-js .challenge-running{display:none}body.dark{background-color:#222;color:#d9d9d9}body.dark a{color:#fff}body.dark a:hover{color:#ee730a;text-decoration:underline}body.dark .lds-ring div{border-color:#999 transparent transparent}body.dark .font-red{color:#b20f03}body.dark .big-button,body.dark .pow-button{background-color:#4693ff;color:#1d1d1d}body.dark #challenge-success-text{background-image:url(data:image/svg+xml;base64,', # 2024-04-08 Cloudflare
'{return l.onPageView}}),Object.defineProperty(r,"perimeterxIdentifiers",{enumerable:' # 2024-04-09 PerimeterX / Human Security
r'.loading-spinner{visibility:hidden}body.no-js .challenge-running{display:none}body.dark{background-color:#222;color:#d9d9d9}body.dark a{color:#fff}body.dark a:hover{color:#ee730a;text-decoration:underline}body.dark .lds-ring div{border-color:#999 transparent transparent}body.dark .font-red{color:#b20f03}body.dark', # 2024-05-13 Cloudflare
r'<span id="challenge-error-text">', # 2024-11-11 Cloudflare error page
r'AwsWafIntegration.forceRefreshToken', # 2024-11-11 Cloudfront (AWS)
r'{return l.onPageView}}),Object.defineProperty(r,"perimeterxIdentifiers",{enumerable:' # 2024-04-09 PerimeterX / Human Security
]
if error_text is not None:
@ -391,61 +395,91 @@ def sherlock(
elif any(hitMsg in r.text for hitMsg in WAFHitMsgs):
query_status = QueryStatus.WAF
elif error_type == "message":
# error_flag True denotes no error found in the HTML
# error_flag False denotes error found in the HTML
error_flag = True
errors = net_info.get("errorMsg")
# errors will hold the error message
# it can be string or list
# by isinstance method we can detect that
# and handle the case for strings as normal procedure
# and if its list we can iterate the errors
if isinstance(errors, str):
# Checks if the error message is in the HTML
# if error is present we will set flag to False
if errors in r.text:
error_flag = False
else:
# If it's list, it will iterate all the error message
for error in errors:
if error in r.text:
error_flag = False
break
if error_flag:
query_status = QueryStatus.CLAIMED
else:
query_status = QueryStatus.AVAILABLE
elif error_type == "status_code":
error_codes = net_info.get("errorCode")
query_status = QueryStatus.CLAIMED
# Type consistency, allowing for both singlets and lists in manifest
if isinstance(error_codes, int):
error_codes = [error_codes]
if error_codes is not None and r.status_code in error_codes:
query_status = QueryStatus.AVAILABLE
elif r.status_code >= 300 or r.status_code < 200:
query_status = QueryStatus.AVAILABLE
elif error_type == "response_url":
# For this detection method, we have turned off the redirect.
# So, there is no need to check the response URL: it will always
# match the request. Instead, we will ensure that the response
# code indicates that the request was successful (i.e. no 404, or
# forward to some odd redirect).
if 200 <= r.status_code < 300:
query_status = QueryStatus.CLAIMED
else:
query_status = QueryStatus.AVAILABLE
else:
# It should be impossible to ever get here...
raise ValueError(
f"Unknown Error Type '{error_type}' for " f"site '{social_network}'"
)
if any(errtype not in ["message", "status_code", "response_url"] for errtype in error_type):
error_context = f"Unknown error type '{error_type}' for {social_network}"
query_status = QueryStatus.UNKNOWN
else:
if "message" in error_type:
# error_flag True denotes no error found in the HTML
# error_flag False denotes error found in the HTML
error_flag = True
errors = net_info.get("errorMsg")
# errors will hold the error message
# it can be string or list
# by isinstance method we can detect that
# and handle the case for strings as normal procedure
# and if its list we can iterate the errors
if isinstance(errors, str):
# Checks if the error message is in the HTML
# if error is present we will set flag to False
if errors in r.text:
error_flag = False
else:
# If it's list, it will iterate all the error message
for error in errors:
if error in r.text:
error_flag = False
break
if error_flag:
query_status = QueryStatus.CLAIMED
else:
query_status = QueryStatus.AVAILABLE
if "status_code" in error_type and query_status is not QueryStatus.AVAILABLE:
error_codes = net_info.get("errorCode")
query_status = QueryStatus.CLAIMED
# Type consistency, allowing for both singlets and lists in manifest
if isinstance(error_codes, int):
error_codes = [error_codes]
if error_codes is not None and r.status_code in error_codes:
query_status = QueryStatus.AVAILABLE
elif r.status_code >= 300 or r.status_code < 200:
query_status = QueryStatus.AVAILABLE
if "response_url" in error_type and query_status is not QueryStatus.AVAILABLE:
# For this detection method, we have turned off the redirect.
# So, there is no need to check the response URL: it will always
# match the request. Instead, we will ensure that the response
# code indicates that the request was successful (i.e. no 404, or
# forward to some odd redirect).
if 200 <= r.status_code < 300:
query_status = QueryStatus.CLAIMED
else:
query_status = QueryStatus.AVAILABLE
if dump_response:
print("+++++++++++++++++++++")
print(f"TARGET NAME : {social_network}")
print(f"USERNAME : {username}")
print(f"TARGET URL : {url}")
print(f"TEST METHOD : {error_type}")
try:
print(f"STATUS CODES : {net_info['errorCode']}")
except KeyError:
pass
print("Results...")
try:
print(f"RESPONSE CODE : {r.status_code}")
except Exception:
pass
try:
print(f"ERROR TEXT : {net_info['errorMsg']}")
except KeyError:
pass
print(">>>>> BEGIN RESPONSE TEXT")
try:
print(r.text)
except Exception:
pass
print("<<<<< END RESPONSE TEXT")
print("VERDICT : " + str(query_status))
print("+++++++++++++++++++++")
# Notify caller about results of query.
result = QueryResult(
result: QueryResult = QueryResult(
username=username,
site_name=social_network,
site_url_user=url,
@ -502,20 +536,14 @@ def handler(signal_received, frame):
def main():
version_string = (
f"%(prog)s {__version__}\n"
+ f"{requests.__description__}: {requests.__version__}\n"
+ f"Python: {platform.python_version()}"
)
parser = ArgumentParser(
formatter_class=RawDescriptionHelpFormatter,
description=f"{module_name} (Version {__version__})",
description=f"{__longname__} (Version {__version__})",
)
parser.add_argument(
"--version",
action="version",
version=version_string,
version=f"{__shortname__} v{__version__}",
help="Display version information and dependencies.",
)
parser.add_argument(
@ -540,22 +568,6 @@ def main():
dest="output",
help="If using single username, the output of the result will be saved to this file.",
)
parser.add_argument(
"--tor",
"-t",
action="store_true",
dest="tor",
default=False,
help="Make requests over Tor; increases runtime; requires Tor to be installed and in system path.",
)
parser.add_argument(
"--unique-tor",
"-u",
action="store_true",
dest="unique_tor",
default=False,
help="Make requests over Tor with new Tor circuit after each request; increases runtime; requires Tor to be installed and in system path.",
)
parser.add_argument(
"--csv",
action="store_true",
@ -587,13 +599,20 @@ def main():
default=None,
help="Make requests over a proxy. e.g. socks5://127.0.0.1:1080",
)
parser.add_argument(
"--dump-response",
action="store_true",
dest="dump_response",
default=False,
help="Dump the HTTP response to stdout for targeted debugging.",
)
parser.add_argument(
"--json",
"-j",
metavar="JSON_FILE",
dest="json_file",
default=None,
help="Load data from a JSON file or an online, valid, JSON file.",
help="Load data from a JSON file or an online, valid, JSON file. Upstream PR numbers also accepted.",
)
parser.add_argument(
"--timeout",
@ -656,6 +675,32 @@ def main():
help="Include checking of NSFW sites from default list.",
)
# TODO deprecated in favor of --txt, retained for workflow compatibility, to be removed
# in future release
parser.add_argument(
"--no-txt",
action="store_true",
dest="no_txt",
default=False,
help="Disable creation of a txt file - WILL BE DEPRECATED",
)
parser.add_argument(
"--txt",
action="store_true",
dest="output_txt",
default=False,
help="Enable creation of a txt file",
)
parser.add_argument(
"--ignore-exclusions",
action="store_true",
dest="ignore_exclusions",
default=False,
help="Ignore upstream exclusions (may return more false positives)",
)
args = parser.parse_args()
# If the user presses CTRL-C, exit gracefully without throwing errors
@ -663,38 +708,23 @@ def main():
# Check for newer version of Sherlock. If it exists, let the user know about it
try:
r = requests.get(
"https://raw.githubusercontent.com/sherlock-project/sherlock/master/sherlock/sherlock.py"
)
latest_release_raw = requests.get(forge_api_latest_release, timeout=10).text
latest_release_json = json_loads(latest_release_raw)
latest_remote_tag = latest_release_json["tag_name"]
remote_version = str(re.findall('__version__ = "(.*)"', r.text)[0])
local_version = __version__
if remote_version != local_version:
if latest_remote_tag[1:] != __version__:
print(
"Update Available!\n"
+ f"You are running version {local_version}. Version {remote_version} is available at https://github.com/sherlock-project/sherlock"
f"Update available! {__version__} --> {latest_remote_tag[1:]}"
f"\n{latest_release_json['html_url']}"
)
except Exception as error:
print(f"A problem occurred while checking for an update: {error}")
# Argument check
# TODO regex check on args.proxy
if args.tor and (args.proxy is not None):
raise Exception("Tor and Proxy cannot be set at the same time.")
# Make prompts
if args.proxy is not None:
print("Using the proxy: " + args.proxy)
if args.tor or args.unique_tor:
print("Using Tor to make requests")
print(
"Warning: some websites might refuse connecting over Tor, so note that using this option might increase connection errors."
)
if args.no_color:
# Disable color output.
init(strip=True, convert=False)
@ -716,10 +746,32 @@ def main():
try:
if args.local:
sites = SitesInformation(
os.path.join(os.path.dirname(__file__), "resources/data.json")
os.path.join(os.path.dirname(__file__), "resources/data.json"),
honor_exclusions=False,
)
else:
sites = SitesInformation(args.json_file)
json_file_location = args.json_file
if args.json_file:
# If --json parameter is a number, interpret it as a pull request number
if args.json_file.isnumeric():
pull_number = args.json_file
pull_url = f"https://api.github.com/repos/sherlock-project/sherlock/pulls/{pull_number}"
pull_request_raw = requests.get(pull_url, timeout=10).text
pull_request_json = json_loads(pull_request_raw)
# Check if it's a valid pull request
if "message" in pull_request_json:
print(f"ERROR: Pull request #{pull_number} not found.")
sys.exit(1)
head_commit_sha = pull_request_json["head"]["sha"]
json_file_location = f"https://raw.githubusercontent.com/sherlock-project/sherlock/{head_commit_sha}/sherlock_project/resources/data.json"
sites = SitesInformation(
data_file_path=json_file_location,
honor_exclusions=not args.ignore_exclusions,
do_not_exclude=args.site_list,
)
except Exception as error:
print(f"ERROR: {error}")
sys.exit(1)
@ -773,8 +825,7 @@ def main():
username,
site_data,
query_notify,
tor=args.tor,
unique_tor=args.unique_tor,
dump_response=args.dump_response,
proxy=args.proxy,
timeout=args.timeout,
)
@ -789,14 +840,15 @@ def main():
else:
result_file = f"{username}.txt"
with open(result_file, "w", encoding="utf-8") as file:
exists_counter = 0
for website_name in results:
dictionary = results[website_name]
if dictionary.get("status").status == QueryStatus.CLAIMED:
exists_counter += 1
file.write(dictionary["url_user"] + "\n")
file.write(f"Total Websites Username Detected On : {exists_counter}\n")
if args.output_txt:
with open(result_file, "w", encoding="utf-8") as file:
exists_counter = 0
for website_name in results:
dictionary = results[website_name]
if dictionary.get("status").status == QueryStatus.CLAIMED:
exists_counter += 1
file.write(dictionary["url_user"] + "\n")
file.write(f"Total Websites Username Detected On : {exists_counter}\n")
if args.csv:
result_file = f"{username}.csv"
@ -873,8 +925,8 @@ def main():
{
"username": usernames,
"name": names,
"url_main": url_main,
"url_user": url_user,
"url_main": [f'=HYPERLINK(\"{u}\")' for u in url_main],
"url_user": [f'=HYPERLINK(\"{u}\")' for u in url_user],
"exists": exists,
"http_status": http_status,
"response_time_s": response_time_s,

View File

@ -7,6 +7,10 @@ import json
import requests
import secrets
MANIFEST_URL = "https://raw.githubusercontent.com/sherlock-project/sherlock/master/sherlock_project/resources/data.json"
EXCLUSIONS_URL = "https://raw.githubusercontent.com/sherlock-project/sherlock/refs/heads/exclusions/false_positive_exclusions.txt"
class SiteInformation:
def __init__(self, name, url_home, url_username_format, username_claimed,
information, is_nsfw, username_unclaimed=secrets.token_urlsafe(10)):
@ -67,12 +71,17 @@ class SiteInformation:
Return Value:
Nicely formatted string to get information about this object.
"""
return f"{self.name} ({self.url_home})"
class SitesInformation:
def __init__(self, data_file_path=None):
def __init__(
self,
data_file_path: str|None = None,
honor_exclusions: bool = True,
do_not_exclude: list[str] = [],
):
"""Create Sites Information Object.
Contains information about all supported websites.
@ -110,7 +119,7 @@ class SitesInformation:
# The default data file is the live data.json which is in the GitHub repo. The reason why we are using
# this instead of the local one is so that the user has the most up-to-date data. This prevents
# users from creating issue about false positives which has already been fixed or having outdated data
data_file_path = "https://raw.githubusercontent.com/sherlock-project/sherlock/master/sherlock/resources/data.json"
data_file_path = MANIFEST_URL
# Ensure that specified data file has correct extension.
if not data_file_path.lower().endswith(".json"):
@ -120,7 +129,7 @@ class SitesInformation:
if data_file_path.lower().startswith("http"):
# Reference is to a URL.
try:
response = requests.get(url=data_file_path)
response = requests.get(url=data_file_path, timeout=30)
except Exception as error:
raise FileNotFoundError(
f"Problem while attempting to access data file URL '{data_file_path}': {error}"
@ -152,9 +161,31 @@ class SitesInformation:
raise FileNotFoundError(f"Problem while attempting to access "
f"data file '{data_file_path}'."
)
site_data.pop('$schema', None)
if honor_exclusions:
try:
response = requests.get(url=EXCLUSIONS_URL, timeout=10)
if response.status_code == 200:
exclusions = response.text.splitlines()
exclusions = [exclusion.strip() for exclusion in exclusions]
for site in do_not_exclude:
if site in exclusions:
exclusions.remove(site)
for exclusion in exclusions:
try:
site_data.pop(exclusion, None)
except KeyError:
pass
except Exception:
# If there was any problem loading the exclusions, just continue without them
print("Warning: Could not load exclusions, continuing without them.")
honor_exclusions = False
self.sites = {}
# Add all site information from the json file to internal site list.
@ -174,7 +205,7 @@ class SitesInformation:
raise ValueError(
f"Problem parsing json contents at '{data_file_path}': Missing attribute {error}."
)
except TypeError as error:
except TypeError:
print(f"Encountered TypeError parsing json contents for target '{site_name}' at {data_file_path}\nSkipping target.\n")
return
@ -194,7 +225,7 @@ class SitesInformation:
for site in self.sites:
if self.sites[site].is_nsfw and site.casefold() not in do_not_remove:
continue
sites[site] = self.sites[site]
sites[site] = self.sites[site]
self.sites = sites
def site_name_list(self):

View File

@ -1,31 +0,0 @@
#!/usr/bin/env python
# This module generates the listing of supported sites which can be found in
# sites.md. It also organizes all the sites in alphanumeric order
import json
# Read the data.json file
with open("sherlock/resources/data.json", "r", encoding="utf-8") as data_file:
data: dict = json.load(data_file)
# Removes schema-specific keywords for proper processing
social_networks: dict = dict(data)
social_networks.pop('$schema', None)
# Sort the social networks in alphanumeric order
social_networks: list = sorted(social_networks.items())
# Write the list of supported sites to sites.md
with open("sites.md", "w") as site_file:
site_file.write(f"## List Of Supported Sites ({len(social_networks)} Sites In Total!)\n")
for social_network, info in social_networks:
url_main = info["urlMain"]
is_nsfw = "**(NSFW)**" if info.get("isNSFW") else ""
site_file.write(f"1. ![](https://www.google.com/s2/favicons?domain={url_main}) [{social_network}]({url_main}) {is_nsfw}\n")
# Overwrite the data.json file with sorted data
with open("sherlock/resources/data.json", "w") as data_file:
sorted_data = json.dumps(data, indent=2, sort_keys=True)
data_file.write(sorted_data)
data_file.write("\n")
print("Finished updating supported site listing!")

409
sites.md
View File

@ -1,409 +0,0 @@
## List Of Supported Sites (408 Sites In Total!)
1. ![](https://www.google.com/s2/favicons?domain=https://www.1337x.to/) [1337x](https://www.1337x.to/)
1. ![](https://www.google.com/s2/favicons?domain=https://2Dimensions.com/) [2Dimensions](https://2Dimensions.com/)
1. ![](https://www.google.com/s2/favicons?domain=http://forum.3dnews.ru/) [3dnews](http://forum.3dnews.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.7cups.com/) [7Cups](https://www.7cups.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://8tracks.com/) [8tracks](https://8tracks.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.9gag.com/) [9GAG](https://www.9gag.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://apclips.com/) [APClips](https://apclips.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://about.me/) [About.me](https://about.me/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.academia.edu/) [Academia.edu](https://www.academia.edu/)
1. ![](https://www.google.com/s2/favicons?domain=https://admireme.vip/) [AdmireMe.Vip](https://admireme.vip/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://airlinepilot.life/) [Air Pilot Life](https://airlinepilot.life/)
1. ![](https://www.google.com/s2/favicons?domain=https://airbit.com/) [Airbit](https://airbit.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.airliners.net/) [Airliners](https://www.airliners.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.alik.cz/) [Alik.cz](https://www.alik.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.allthingsworn.com) [All Things Worn](https://www.allthingsworn.com) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://allmylinks.com/) [AllMyLinks](https://allmylinks.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://aminoapps.com) [Amino](https://aminoapps.com)
1. ![](https://www.google.com/s2/favicons?domain=https://aniworld.to/) [AniWorld](https://aniworld.to/)
1. ![](https://www.google.com/s2/favicons?domain=https://anilist.co/) [Anilist](https://anilist.co/)
1. ![](https://www.google.com/s2/favicons?domain=https://developer.apple.com) [Apple Developer](https://developer.apple.com)
1. ![](https://www.google.com/s2/favicons?domain=https://discussions.apple.com) [Apple Discussions](https://discussions.apple.com)
1. ![](https://www.google.com/s2/favicons?domain=https://archiveofourown.org/) [Archive of Our Own](https://archiveofourown.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://archive.org) [Archive.org](https://archive.org)
1. ![](https://www.google.com/s2/favicons?domain=https://www.artstation.com/) [ArtStation](https://www.artstation.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://asciinema.org) [Asciinema](https://asciinema.org)
1. ![](https://www.google.com/s2/favicons?domain=https://ask.fedoraproject.org/) [Ask Fedora](https://ask.fedoraproject.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://ask.fm/) [AskFM](https://ask.fm/)
1. ![](https://www.google.com/s2/favicons?domain=https://audiojungle.net/) [Audiojungle](https://audiojungle.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.autofrage.net/) [Autofrage](https://www.autofrage.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.avizo.cz/) [Avizo](https://www.avizo.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://blip.fm/) [BLIP.fm](https://blip.fm/)
1. ![](https://www.google.com/s2/favicons?domain=https://booth.pm/) [BOOTH](https://booth.pm/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.bandcamp.com/) [Bandcamp](https://www.bandcamp.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.bazar.cz/) [Bazar.cz](https://www.bazar.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.behance.net/) [Behance](https://www.behance.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://bezuzyteczna.pl) [Bezuzyteczna](https://bezuzyteczna.pl)
1. ![](https://www.google.com/s2/favicons?domain=https://www.biggerpockets.com/) [BiggerPockets](https://www.biggerpockets.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.bikemap.net/) [Bikemap](https://www.bikemap.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.dangerousthings.com/) [BioHacking](https://forum.dangerousthings.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://bitbucket.org/) [BitBucket](https://bitbucket.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://bitwarden.com/) [Bitwarden Forum](https://bitwarden.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.blipfoto.com/) [Blipfoto](https://www.blipfoto.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.blogger.com/) [Blogger](https://www.blogger.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://bodyspace.bodybuilding.com/) [BodyBuilding](https://bodyspace.bodybuilding.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://pt.bongacams.com) [BongaCams](https://pt.bongacams.com) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://www.bookcrossing.com/) [Bookcrossing](https://www.bookcrossing.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.brave.com/) [BraveCommunity](https://community.brave.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://bugcrowd.com/) [BugCrowd](https://bugcrowd.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.buymeacoffee.com/) [BuyMeACoffee](https://www.buymeacoffee.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://buzzfeed.com/) [BuzzFeed](https://buzzfeed.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.cgtrader.com) [CGTrader](https://www.cgtrader.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.cnet.com/) [CNET](https://www.cnet.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://cssbattle.dev) [CSSBattle](https://cssbattle.dev)
1. ![](https://www.google.com/s2/favicons?domain=https://ctan.org/) [CTAN](https://ctan.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://caddy.community/) [Caddy Community](https://caddy.community/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.cartalk.com/) [Car Talk Community](https://community.cartalk.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://carbonmade.com/) [Carbonmade](https://carbonmade.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://career.habr.com/) [Career.habr](https://career.habr.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.championat.com/) [Championat](https://www.championat.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://chaos.social/) [Chaos](https://chaos.social/)
1. ![](https://www.google.com/s2/favicons?domain=https://chatujme.cz/) [Chatujme.cz](https://chatujme.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://chaturbate.com) [ChaturBate](https://chaturbate.com) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://www.chess.com/) [Chess](https://www.chess.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://choice.community/) [Choice Community](https://choice.community/)
1. ![](https://www.google.com/s2/favicons?domain=https://clapperapp.com/) [Clapper](https://clapperapp.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.cloudflare.com/) [CloudflareCommunity](https://community.cloudflare.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.clozemaster.com) [Clozemaster](https://www.clozemaster.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.clubhouse.com) [Clubhouse](https://www.clubhouse.com)
1. ![](https://www.google.com/s2/favicons?domain=https://codesnippets.fandom.com) [Code Snippet Wiki](https://codesnippets.fandom.com)
1. ![](https://www.google.com/s2/favicons?domain=https://codeberg.org/) [Codeberg](https://codeberg.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.codecademy.com/) [Codecademy](https://www.codecademy.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.codechef.com/) [Codechef](https://www.codechef.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://codeforces.com/) [Codeforces](https://codeforces.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://codepen.io/) [Codepen](https://codepen.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://codersrank.io/) [Coders Rank](https://codersrank.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://coderwall.com) [Coderwall](https://coderwall.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.codewars.com) [Codewars](https://www.codewars.com)
1. ![](https://www.google.com/s2/favicons?domain=https://coinvote.cc/) [Coinvote](https://coinvote.cc/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.colourlovers.com/) [ColourLovers](https://www.colourlovers.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://contently.com/) [Contently](https://contently.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://coroflot.com/) [Coroflot](https://coroflot.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.cracked.com/) [Cracked](https://www.cracked.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://crevado.com/) [Crevado](https://crevado.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://crowdin.com/) [Crowdin](https://crowdin.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.cryptomator.org/) [Cryptomator Forum](https://community.cryptomator.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://cults3d.com/en) [Cults3D](https://cults3d.com/en)
1. ![](https://www.google.com/s2/favicons?domain=https://cyberdefenders.org/) [CyberDefenders](https://cyberdefenders.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://dev.to/) [DEV Community](https://dev.to/)
1. ![](https://www.google.com/s2/favicons?domain=https://dmoj.ca/) [DMOJ](https://dmoj.ca/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.dailymotion.com/) [DailyMotion](https://www.dailymotion.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.dealabs.com/) [Dealabs](https://www.dealabs.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://deviantart.com) [DeviantART](https://deviantart.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.discogs.com/) [Discogs](https://www.discogs.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://discuss.elastic.co/) [Discuss.Elastic.co](https://discuss.elastic.co/)
1. ![](https://www.google.com/s2/favicons?domain=https://disqus.com/) [Disqus](https://disqus.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://hub.docker.com/) [Docker Hub](https://hub.docker.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://dribbble.com/) [Dribbble](https://dribbble.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://duolingo.com/) [Duolingo](https://duolingo.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.eintracht.de/) [Eintracht Frankfurt Forum](https://community.eintracht.de/)
1. ![](https://www.google.com/s2/favicons?domain=https://forums.envato.com/) [Envato Forum](https://forums.envato.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.erome.com/) [Erome](https://www.erome.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://www.etsy.com/) [Etsy](https://www.etsy.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://euw.op.gg/) [Euw](https://euw.op.gg/)
1. ![](https://www.google.com/s2/favicons?domain=https://exposure.co/) [Exposure](https://exposure.co/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.eyeem.com/) [EyeEm](https://www.eyeem.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://f3.cool/) [F3.cool](https://f3.cool/)
1. ![](https://www.google.com/s2/favicons?domain=https://fameswap.com/) [Fameswap](https://fameswap.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.fandom.com/) [Fandom](https://www.fandom.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.finanzfrage.net/) [Finanzfrage](https://www.finanzfrage.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.fiverr.com/) [Fiverr](https://www.fiverr.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.flickr.com/) [Flickr](https://www.flickr.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.flightradar24.com/) [Flightradar24](https://www.flightradar24.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://flipboard.com/) [Flipboard](https://flipboard.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.rusfootball.info/) [Football](https://www.rusfootball.info/)
1. ![](https://www.google.com/s2/favicons?domain=https://fortnitetracker.com/challenges) [FortniteTracker](https://fortnitetracker.com/challenges)
1. ![](https://www.google.com/s2/favicons?domain=https://www.forumophilia.com/) [Forum Ophilia](https://www.forumophilia.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://fosstodon.org/) [Fosstodon](https://fosstodon.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://freelance.habr.com/) [Freelance.habr](https://freelance.habr.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.freelancer.com/) [Freelancer](https://www.freelancer.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://freesound.org/) [Freesound](https://freesound.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://gitlab.gnome.org/) [GNOME VCS](https://gitlab.gnome.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.gaiaonline.com/) [GaiaOnline](https://www.gaiaonline.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.gamespot.com/) [Gamespot](https://www.gamespot.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.geeksforgeeks.org/) [GeeksforGeeks](https://www.geeksforgeeks.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://genius.com/) [Genius (Artists)](https://genius.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://genius.com/) [Genius (Users)](https://genius.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.gesundheitsfrage.net/) [Gesundheitsfrage](https://www.gesundheitsfrage.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://getmyuni.com/) [GetMyUni](https://getmyuni.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.giantbomb.com/) [Giant Bomb](https://www.giantbomb.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://giphy.com/) [Giphy](https://giphy.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://gitbook.com/) [GitBook](https://gitbook.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.github.com/) [GitHub](https://www.github.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://gitlab.com/) [GitLab](https://gitlab.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://gitee.com/) [Gitee](https://gitee.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.goodreads.com/) [GoodReads](https://www.goodreads.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://play.google.com) [Google Play](https://play.google.com)
1. ![](https://www.google.com/s2/favicons?domain=https://gradle.org/) [Gradle](https://gradle.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.grailed.com/) [Grailed](https://www.grailed.com/)
1. ![](https://www.google.com/s2/favicons?domain=http://en.gravatar.com/) [Gravatar](http://en.gravatar.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.gumroad.com/) [Gumroad](https://www.gumroad.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.gutefrage.net/) [Gutefrage](https://www.gutefrage.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.hackthebox.eu/) [HackTheBox](https://forum.hackthebox.eu/)
1. ![](https://www.google.com/s2/favicons?domain=https://hackaday.io/) [Hackaday](https://hackaday.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://hackenproof.com/) [HackenProof (Hackers)](https://hackenproof.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://hackerearth.com/) [HackerEarth](https://hackerearth.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://news.ycombinator.com/) [HackerNews](https://news.ycombinator.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://hackerone.com/) [HackerOne](https://hackerone.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://hackerrank.com/) [HackerRank](https://hackerrank.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://scholar.harvard.edu/) [Harvard Scholar](https://scholar.harvard.edu/)
1. ![](https://www.google.com/s2/favicons?domain=https://hashnode.com) [Hashnode](https://hashnode.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.heavy-r.com/) [Heavy-R](https://www.heavy-r.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://holopin.io) [Holopin](https://holopin.io)
1. ![](https://www.google.com/s2/favicons?domain=https://houzz.com/) [Houzz](https://houzz.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://hubpages.com/) [HubPages](https://hubpages.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://hubski.com/) [Hubski](https://hubski.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://hudsonrock.com) [HudsonRock](https://hudsonrock.com)
1. ![](https://www.google.com/s2/favicons?domain=https://icq.com/) [ICQ](https://icq.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.ifttt.com/) [IFTTT](https://www.ifttt.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://irc-galleria.net/) [IRC-Galleria](https://irc-galleria.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.icons8.com/) [Icons8 Community](https://community.icons8.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.imagefap.com/) [Image Fap](https://www.imagefap.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://imgup.cz/) [ImgUp.cz](https://imgup.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://imgur.com/) [Imgur](https://imgur.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://instagram.com/) [Instagram](https://instagram.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.instructables.com/) [Instructables](https://www.instructables.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://app.intigriti.com) [Intigriti](https://app.intigriti.com)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.ionicframework.com/) [Ionic Forum](https://forum.ionicframework.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://issuu.com/) [Issuu](https://issuu.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://itch.io/) [Itch.io](https://itch.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.itemfix.com/) [Itemfix](https://www.itemfix.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://translate.jellyfin.org/) [Jellyfin Weblate](https://translate.jellyfin.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://jimdosite.com/) [Jimdo](https://jimdosite.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://discourse.joplinapp.org/) [Joplin Forum](https://discourse.joplinapp.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.keakr.com/) [KEAKR](https://www.keakr.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.kaggle.com/) [Kaggle](https://www.kaggle.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://keybase.io/) [Keybase](https://keybase.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://kick.com/) [Kick](https://kick.com/)
1. ![](https://www.google.com/s2/favicons?domain=http://kik.me/) [Kik](http://kik.me/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.kongregate.com/) [Kongregate](https://www.kongregate.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://linux.org.ru/) [LOR](https://linux.org.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://launchpad.net/) [Launchpad](https://launchpad.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://leetcode.com/) [LeetCode](https://leetcode.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.lesswrong.com/) [LessWrong](https://www.lesswrong.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://letterboxd.com/) [Letterboxd](https://letterboxd.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.librarything.com/) [LibraryThing](https://www.librarything.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://lichess.org) [Lichess](https://lichess.org)
1. ![](https://www.google.com/s2/favicons?domain=https://linkedin.com) [LinkedIn](https://linkedin.com)
1. ![](https://www.google.com/s2/favicons?domain=https://linktr.ee/) [Linktree](https://linktr.ee/)
1. ![](https://www.google.com/s2/favicons?domain=https://listed.to/) [Listed](https://listed.to/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.livejournal.com/) [LiveJournal](https://www.livejournal.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://lobste.rs/) [Lobsters](https://lobste.rs/)
1. ![](https://www.google.com/s2/favicons?domain=https://lottiefiles.com/) [LottieFiles](https://lottiefiles.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.lushstories.com/) [LushStories](https://www.lushstories.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://forums.mmorpg.com/) [MMORPG Forum](https://forums.mmorpg.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://mapify.travel/) [Mapify](https://mapify.travel/)
1. ![](https://www.google.com/s2/favicons?domain=https://medium.com/) [Medium](https://medium.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.memrise.com/) [Memrise](https://www.memrise.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://minecraft.net/) [Minecraft](https://minecraft.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.mixcloud.com/) [MixCloud](https://www.mixcloud.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://monkeytype.com/) [Monkeytype](https://monkeytype.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://motherless.com/) [Motherless](https://motherless.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://www.motorradfrage.net/) [Motorradfrage](https://www.motorradfrage.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://myanimelist.net/) [MyAnimeList](https://myanimelist.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.myminifactory.com/) [MyMiniFactory](https://www.myminifactory.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://mydramalist.com) [Mydramalist](https://mydramalist.com)
1. ![](https://www.google.com/s2/favicons?domain=https://myspace.com/) [Myspace](https://myspace.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.native-instruments.com/forum/) [NICommunityForum](https://www.native-instruments.com/forum/)
1. ![](https://www.google.com/s2/favicons?domain=https://nationstates.net) [NationStates Nation](https://nationstates.net)
1. ![](https://www.google.com/s2/favicons?domain=https://nationstates.net) [NationStates Region](https://nationstates.net)
1. ![](https://www.google.com/s2/favicons?domain=https://naver.com) [Naver](https://naver.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.needrom.com/) [Needrom](https://www.needrom.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://newgrounds.com) [Newgrounds](https://newgrounds.com)
1. ![](https://www.google.com/s2/favicons?domain=https://nextcloud.com/) [Nextcloud Forum](https://nextcloud.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://nightbot.tv/) [Nightbot](https://nightbot.tv/)
1. ![](https://www.google.com/s2/favicons?domain=https://ninjakiwi.com/) [Ninja Kiwi](https://ninjakiwi.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.nintendolife.com/) [NintendoLife](https://www.nintendolife.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.nitrotype.com/) [NitroType](https://www.nitrotype.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://notabug.org/) [NotABug.org](https://notabug.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://nyaa.si/) [Nyaa.si](https://nyaa.si/)
1. ![](https://www.google.com/s2/favicons?domain=https://ogu.gg/) [OGUsers](https://ogu.gg/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.openstreetmap.org/) [OpenStreetMap](https://www.openstreetmap.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://opensource.com/) [Opensource](https://opensource.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://ourdjtalk.com/) [OurDJTalk](https://ourdjtalk.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://pcgamer.com) [PCGamer](https://pcgamer.com)
1. ![](https://www.google.com/s2/favicons?domain=https://psnprofiles.com/) [PSNProfiles.com](https://psnprofiles.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://packagist.org/) [Packagist](https://packagist.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://pastebin.com/) [Pastebin](https://pastebin.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.patreon.com/) [Patreon](https://www.patreon.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://pentesterlab.com/) [PentesterLab](https://pentesterlab.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.pepper.it) [PepperIT](https://www.pepper.it)
1. ![](https://www.google.com/s2/favicons?domain=https://www.periscope.tv/) [Periscope](https://www.periscope.tv/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.pinkbike.com/) [Pinkbike](https://www.pinkbike.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://play.google.com/store) [PlayStore](https://play.google.com/store)
1. ![](https://www.google.com/s2/favicons?domain=https://pocketstars.com/) [PocketStars](https://pocketstars.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://pokemonshowdown.com) [Pokemon Showdown](https://pokemonshowdown.com)
1. ![](https://www.google.com/s2/favicons?domain=https://polarsteps.com/) [Polarsteps](https://polarsteps.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.polygon.com/) [Polygon](https://www.polygon.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://polymart.org/) [Polymart](https://polymart.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://pornhub.com/) [Pornhub](https://pornhub.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://www.producthunt.com/) [ProductHunt](https://www.producthunt.com/)
1. ![](https://www.google.com/s2/favicons?domain=http://promodj.com/) [PromoDJ](http://promodj.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://pypi.org) [PyPi](https://pypi.org)
1. ![](https://www.google.com/s2/favicons?domain=https://www.rajce.idnes.cz/) [Rajce.net](https://www.rajce.idnes.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://rateyourmusic.com/) [Rate Your Music](https://rateyourmusic.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.rclone.org/) [Rclone Forum](https://forum.rclone.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.redtube.com/) [RedTube](https://www.redtube.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://www.redbubble.com/) [Redbubble](https://www.redbubble.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.reddit.com/) [Reddit](https://www.reddit.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.reisefrage.net/) [Reisefrage](https://www.reisefrage.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://replit.com/) [Replit.com](https://replit.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.researchgate.net/) [ResearchGate](https://www.researchgate.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.reverbnation.com/) [ReverbNation](https://www.reverbnation.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.roblox.com/) [Roblox](https://www.roblox.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.rockettube.com/) [RocketTube](https://www.rockettube.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://royalcams.com) [RoyalCams](https://royalcams.com)
1. ![](https://www.google.com/s2/favicons?domain=https://rubygems.org/) [RubyGems](https://rubygems.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://rumble.com/) [Rumble](https://rumble.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.runescape.com/) [RuneScape](https://www.runescape.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://swapd.co/) [SWAPD](https://swapd.co/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.sbazar.cz/) [Sbazar.cz](https://www.sbazar.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://scratch.mit.edu/) [Scratch](https://scratch.mit.edu/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.scribd.com/) [Scribd](https://www.scribd.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.shitpostbot.com/) [ShitpostBot5000](https://www.shitpostbot.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.shpock.com/) [Shpock](https://www.shpock.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.signalusers.org) [Signal](https://community.signalusers.org)
1. ![](https://www.google.com/s2/favicons?domain=https://sketchfab.com/) [Sketchfab](https://sketchfab.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://slack.com) [Slack](https://slack.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.slant.co/) [Slant](https://www.slant.co/)
1. ![](https://www.google.com/s2/favicons?domain=https://slashdot.org) [Slashdot](https://slashdot.org)
1. ![](https://www.google.com/s2/favicons?domain=https://slideshare.net/) [SlideShare](https://slideshare.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://slides.com/) [Slides](https://slides.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://smugmug.com) [SmugMug](https://smugmug.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.smule.com/) [Smule](https://www.smule.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.snapchat.com) [Snapchat](https://www.snapchat.com)
1. ![](https://www.google.com/s2/favicons?domain=https://soundcloud.com/) [SoundCloud](https://soundcloud.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://sourceforge.net/) [SourceForge](https://sourceforge.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://soylentnews.org) [SoylentNews](https://soylentnews.org)
1. ![](https://www.google.com/s2/favicons?domain=https://speedrun.com/) [Speedrun.com](https://speedrun.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://spells8.com) [Spells8](https://spells8.com)
1. ![](https://www.google.com/s2/favicons?domain=https://splice.com/) [Splice](https://splice.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://splits.io) [Splits.io](https://splits.io)
1. ![](https://www.google.com/s2/favicons?domain=https://www.sporcle.com/) [Sporcle](https://www.sporcle.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.sportlerfrage.net/) [Sportlerfrage](https://www.sportlerfrage.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.sports.ru/) [SportsRU](https://www.sports.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://open.spotify.com/) [Spotify](https://open.spotify.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://robertsspaceindustries.com/) [Star Citizen](https://robertsspaceindustries.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://steamcommunity.com/) [Steam Community (Group)](https://steamcommunity.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://steamcommunity.com/) [Steam Community (User)](https://steamcommunity.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.strava.com/) [Strava](https://www.strava.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.sublimetext.com/) [SublimeForum](https://forum.sublimetext.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://tetr.io) [TETR.IO](https://tetr.io)
1. ![](https://www.google.com/s2/favicons?domain=https://tldrlegal.com/) [TLDR Legal](https://tldrlegal.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://traktrain.com/) [TRAKTRAIN](https://traktrain.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://t.me/) [Telegram](https://t.me/)
1. ![](https://www.google.com/s2/favicons?domain=https://tellonym.me/) [Tellonym.me](https://tellonym.me/)
1. ![](https://www.google.com/s2/favicons?domain=https://tenor.com/) [Tenor](https://tenor.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://themeforest.net/) [ThemeForest](https://themeforest.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.tnaflix.com/) [TnAFlix](https://www.tnaflix.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://torrentgalaxy.to/) [TorrentGalaxy](https://torrentgalaxy.to/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.tradingview.com/) [TradingView](https://www.tradingview.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.trakt.tv/) [Trakt](https://www.trakt.tv/)
1. ![](https://www.google.com/s2/favicons?domain=https://trashbox.ru/) [TrashboxRU](https://trashbox.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://traewelling.de/) [Trawelling](https://traewelling.de/)
1. ![](https://www.google.com/s2/favicons?domain=https://trello.com/) [Trello](https://trello.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://tryhackme.com/) [TryHackMe](https://tryhackme.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://tuna.voicemod.net/) [Tuna](https://tuna.voicemod.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://tweakers.net) [Tweakers](https://tweakers.net)
1. ![](https://www.google.com/s2/favicons?domain=https://www.twitch.tv/) [Twitch](https://www.twitch.tv/)
1. ![](https://www.google.com/s2/favicons?domain=https://twitter.com/) [Twitter](https://twitter.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://typeracer.com) [Typeracer](https://typeracer.com)
1. ![](https://www.google.com/s2/favicons?domain=https://ultimate-guitar.com/) [Ultimate-Guitar](https://ultimate-guitar.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://unsplash.com/) [Unsplash](https://unsplash.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://untappd.com/) [Untappd](https://untappd.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://vk.com/) [VK](https://vk.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://vsco.co/) [VSCO](https://vsco.co/)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.velomania.ru/) [Velomania](https://forum.velomania.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://venmo.com/) [Venmo](https://venmo.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://vero.co/) [Vero](https://vero.co/)
1. ![](https://www.google.com/s2/favicons?domain=https://vimeo.com/) [Vimeo](https://vimeo.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.virustotal.com/) [VirusTotal](https://www.virustotal.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://discourse.wicg.io/) [WICG Forum](https://discourse.wicg.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.warriorforum.com/) [Warrior Forum](https://www.warriorforum.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.wattpad.com/) [Wattpad](https://www.wattpad.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.webnode.cz/) [WebNode](https://www.webnode.cz/)
1. ![](https://www.google.com/s2/favicons?domain=https://hosted.weblate.org/) [Weblate](https://hosted.weblate.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://weebly.com/) [Weebly](https://weebly.com/)
1. ![](https://www.google.com/s2/favicons?domain=http://www.wikidot.com/) [Wikidot](http://www.wikidot.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.wikipedia.org/) [Wikipedia](https://www.wikipedia.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://windy.com/) [Windy](https://windy.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://wix.com/) [Wix](https://wix.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://community.wolfram.com/) [WolframalphaForum](https://community.wolfram.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://wordpress.com) [WordPress](https://wordpress.com)
1. ![](https://www.google.com/s2/favicons?domain=https://wordpress.org/) [WordPressOrg](https://wordpress.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.wordnik.com/) [Wordnik](https://www.wordnik.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.wykop.pl) [Wykop](https://www.wykop.pl)
1. ![](https://www.google.com/s2/favicons?domain=https://xboxgamertag.com/) [Xbox Gamertag](https://xboxgamertag.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://xvideos.com/) [Xvideos](https://xvideos.com/) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://music.yandex) [YandexMusic](https://music.yandex)
1. ![](https://www.google.com/s2/favicons?domain=https://www.younow.com/) [YouNow](https://www.younow.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://youpic.com/) [YouPic](https://youpic.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://youporn.com) [YouPorn](https://youporn.com) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://www.youtube.com/) [YouTube](https://www.youtube.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.zhihu.com/) [Zhihu](https://www.zhihu.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://akniga.org/profile/blue/) [akniga](https://akniga.org/profile/blue/)
1. ![](https://www.google.com/s2/favicons?domain=http://www.authorstream.com/) [authorSTREAM](http://www.authorstream.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.baby.ru/) [babyRU](https://www.baby.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.babyblog.ru/) [babyblogRU](https://www.babyblog.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://chaos.social/) [chaos.social](https://chaos.social/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.couchsurfing.com/) [couchsurfing](https://www.couchsurfing.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://d3.ru/) [d3RU](https://d3.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.dailykos.com) [dailykos](https://www.dailykos.com)
1. ![](https://www.google.com/s2/favicons?domain=http://dating.ru) [datingRU](http://dating.ru)
1. ![](https://www.google.com/s2/favicons?domain=https://devrant.com/) [devRant](https://devrant.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.drive2.ru/) [drive2](https://www.drive2.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://egpu.io/) [eGPU](https://egpu.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://eintracht.de) [eintracht](https://eintracht.de)
1. ![](https://www.google.com/s2/favicons?domain=https://www.fixya.com) [fixya](https://www.fixya.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.fl.ru/) [fl](https://www.fl.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.guns.ru/) [forum_guns](https://forum.guns.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.freecodecamp.org/) [freecodecamp](https://www.freecodecamp.org/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.furaffinity.net) [furaffinity](https://www.furaffinity.net)
1. ![](https://www.google.com/s2/favicons?domain=https://www.geocaching.com/) [geocaching](https://www.geocaching.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://gfycat.com/) [gfycat](https://gfycat.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://habr.com/) [habr](https://habr.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.hackster.io) [hackster](https://www.hackster.io)
1. ![](https://www.google.com/s2/favicons?domain=https://www.hunting.ru/forum/) [hunting](https://www.hunting.ru/forum/)
1. ![](https://www.google.com/s2/favicons?domain=https://imgsrc.ru/) [iMGSRC.RU](https://imgsrc.ru/)
1. ![](https://www.google.com/s2/favicons?domain=http://forum.igromania.ru/) [igromania](http://forum.igromania.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.interpals.net/) [interpals](https://www.interpals.net/)
1. ![](https://www.google.com/s2/favicons?domain=https://irecommend.ru/) [irecommend](https://irecommend.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://jbzd.com.pl/) [jbzd.com.pl](https://jbzd.com.pl/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.jeuxvideo.com) [jeuxvideo](https://www.jeuxvideo.com)
1. ![](https://www.google.com/s2/favicons?domain=https://ko-fi.com) [kofi](https://ko-fi.com)
1. ![](https://www.google.com/s2/favicons?domain=https://www.kwork.ru/) [kwork](https://www.kwork.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://lab.pentestit.ru/) [labpentestit](https://lab.pentestit.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://last.fm/) [last.fm](https://last.fm/)
1. ![](https://www.google.com/s2/favicons?domain=https://forum.leasehackr.com/) [leasehackr](https://forum.leasehackr.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.livelib.ru/) [livelib](https://www.livelib.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://mastodon.cloud/) [mastodon.cloud](https://mastodon.cloud/)
1. ![](https://www.google.com/s2/favicons?domain=https://chaos.social/) [mastodon.social](https://chaos.social/)
1. ![](https://www.google.com/s2/favicons?domain=https://mastodon.xyz/) [mastodon.technology](https://mastodon.xyz/)
1. ![](https://www.google.com/s2/favicons?domain=https://mastodon.xyz/) [mastodon.xyz](https://mastodon.xyz/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.mercadolivre.com.br) [mercadolivre](https://www.mercadolivre.com.br)
1. ![](https://www.google.com/s2/favicons?domain=https://www.minds.com) [minds](https://www.minds.com)
1. ![](https://www.google.com/s2/favicons?domain=https://moikrug.ru/) [moikrug](https://moikrug.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://mstdn.io/) [mstdn.io](https://mstdn.io/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.nairaland.com/) [nairaland.com](https://www.nairaland.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.nn.ru/) [nnRU](https://www.nn.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://note.com/) [note](https://note.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.npmjs.com/) [npm](https://www.npmjs.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.opennet.ru/) [opennet](https://www.opennet.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://osu.ppy.sh/) [osu!](https://osu.ppy.sh/)
1. ![](https://www.google.com/s2/favicons?domain=https://php.ru/forum/) [phpRU](https://php.ru/forum/)
1. ![](https://www.google.com/s2/favicons?domain=https://pikabu.ru/) [pikabu](https://pikabu.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://pr0gramm.com/) [pr0gramm](https://pr0gramm.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://prog.hu/) [prog.hu](https://prog.hu/)
1. ![](https://www.google.com/s2/favicons?domain=https://queer.af/) [queer.af](https://queer.af/)
1. ![](https://www.google.com/s2/favicons?domain=https://satsis.info/) [satsisRU](https://satsis.info/)
1. ![](https://www.google.com/s2/favicons?domain=https://sessionize.com/) [sessionize](https://sessionize.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://skyrock.com/) [skyrock](https://skyrock.com/)
1. ![](https://www.google.com/s2/favicons?domain=https://social.tchncs.de/) [social.tchncs.de](https://social.tchncs.de/)
1. ![](https://www.google.com/s2/favicons?domain=https://spletnik.ru/) [spletnik](https://spletnik.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.svidbook.ru/) [svidbook](https://www.svidbook.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://www.toster.ru/) [toster](https://www.toster.ru/)
1. ![](https://www.google.com/s2/favicons?domain=https://uid.me/) [uid](https://uid.me/)
1. ![](https://www.google.com/s2/favicons?domain=https://wiki.vg/) [wiki.vg](https://wiki.vg/)
1. ![](https://www.google.com/s2/favicons?domain=https://xhamster.com) [xHamster](https://xhamster.com) **(NSFW)**
1. ![](https://www.google.com/s2/favicons?domain=https://znanylekarz.pl) [znanylekarz.pl](https://znanylekarz.pl)

51
tests/conftest.py Normal file
View File

@ -0,0 +1,51 @@
import os
import json
import urllib
import pytest
from sherlock_project.sites import SitesInformation
def fetch_local_manifest(honor_exclusions: bool = True) -> dict[str, dict[str, str]]:
sites_obj = SitesInformation(data_file_path=os.path.join(os.path.dirname(__file__), "../sherlock_project/resources/data.json"), honor_exclusions=honor_exclusions)
sites_iterable: dict[str, dict[str, str]] = {site.name: site.information for site in sites_obj}
return sites_iterable
@pytest.fixture()
def sites_obj():
sites_obj = SitesInformation(data_file_path=os.path.join(os.path.dirname(__file__), "../sherlock_project/resources/data.json"))
yield sites_obj
@pytest.fixture(scope="session")
def sites_info():
yield fetch_local_manifest()
@pytest.fixture(scope="session")
def remote_schema():
schema_url: str = 'https://raw.githubusercontent.com/sherlock-project/sherlock/master/sherlock_project/resources/data.schema.json'
with urllib.request.urlopen(schema_url) as remoteschema:
schemadat = json.load(remoteschema)
yield schemadat
def pytest_addoption(parser):
parser.addoption(
"--chunked-sites",
action="store",
default=None,
help="For tests utilizing chunked sites, include only the (comma-separated) site(s) specified.",
)
def pytest_generate_tests(metafunc):
if "chunked_sites" in metafunc.fixturenames:
sites_info = fetch_local_manifest(honor_exclusions=False)
# Ingest and apply site selections
site_filter: str | None = metafunc.config.getoption("--chunked-sites")
if site_filter:
selected_sites: list[str] = [site.strip() for site in site_filter.split(",")]
sites_info = {
site: data for site, data in sites_info.items()
if site in selected_sites
}
params = [{name: data} for name, data in sites_info.items()]
ids = list(sites_info.keys())
metafunc.parametrize("chunked_sites", params, ids=ids)

7
tests/few_test_basic.py Normal file
View File

@ -0,0 +1,7 @@
import sherlock_project
#from sherlock.sites import SitesInformation
#local_manifest = data_file_path=os.path.join(os.path.dirname(__file__), "../sherlock/resources/data.json")
def test_username_via_message():
sherlock_project.__main__("--version")

View File

@ -0,0 +1,38 @@
import os
import platform
import re
import subprocess
class Interactives:
def run_cli(args:str = "") -> str:
"""Pass arguments to Sherlock as a normal user on the command line"""
# Adapt for platform differences (Windows likes to be special)
if platform.system() == "Windows":
command:str = f"py -m sherlock_project {args}"
else:
command:str = f"sherlock {args}"
proc_out:str = ""
try:
proc_out = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
return proc_out.decode()
except subprocess.CalledProcessError as e:
raise InteractivesSubprocessError(e.output.decode())
def walk_sherlock_for_files_with(pattern: str) -> list[str]:
"""Check all files within the Sherlock package for matching patterns"""
pattern:re.Pattern = re.compile(pattern)
matching_files:list[str] = []
for root, dirs, files in os.walk("sherlock_project"):
for file in files:
file_path = os.path.join(root,file)
if "__pycache__" in file_path:
continue
with open(file_path, 'r', errors='ignore') as f:
if pattern.search(f.read()):
matching_files.append(file_path)
return matching_files
class InteractivesSubprocessError(Exception):
pass

39
tests/test_manifest.py Normal file
View File

@ -0,0 +1,39 @@
import os
import json
import pytest
from jsonschema import validate
def test_validate_manifest_against_local_schema():
"""Ensures that the manifest matches the local schema, for situations where the schema is being changed."""
json_relative: str = '../sherlock_project/resources/data.json'
schema_relative: str = '../sherlock_project/resources/data.schema.json'
json_path: str = os.path.join(os.path.dirname(__file__), json_relative)
schema_path: str = os.path.join(os.path.dirname(__file__), schema_relative)
with open(json_path, 'r') as f:
jsondat = json.load(f)
with open(schema_path, 'r') as f:
schemadat = json.load(f)
validate(instance=jsondat, schema=schemadat)
@pytest.mark.online
def test_validate_manifest_against_remote_schema(remote_schema):
"""Ensures that the manifest matches the remote schema, so as to not unexpectedly break clients."""
json_relative: str = '../sherlock_project/resources/data.json'
json_path: str = os.path.join(os.path.dirname(__file__), json_relative)
with open(json_path, 'r') as f:
jsondat = json.load(f)
validate(instance=jsondat, schema=remote_schema)
# Ensure that the expected values are beind returned by the site list
@pytest.mark.parametrize("target_name,target_expected_err_type", [
('GitHub', 'status_code'),
('GitLab', 'message'),
])
def test_site_list_iterability (sites_info, target_name, target_expected_err_type):
assert sites_info[target_name]['errorType'] == target_expected_err_type

105
tests/test_probes.py Normal file
View File

@ -0,0 +1,105 @@
import pytest
import random
import string
import re
from sherlock_project.sherlock import sherlock
from sherlock_project.notify import QueryNotify
from sherlock_project.result import QueryStatus
#from sherlock_interactives import Interactives
def simple_query(sites_info: dict, site: str, username: str) -> QueryStatus:
query_notify = QueryNotify()
site_data: dict = {}
site_data[site] = sites_info[site]
return sherlock(
username=username,
site_data=site_data,
query_notify=query_notify,
)[site]['status'].status
@pytest.mark.online
class TestLiveTargets:
"""Actively test probes against live and trusted targets"""
# Known positives should only use sites trusted to be reliable and unchanging
@pytest.mark.parametrize('site,username',[
('GitLab', 'ppfeister'),
('AllMyLinks', 'blue'),
])
def test_known_positives_via_message(self, sites_info, site, username):
assert simple_query(sites_info=sites_info, site=site, username=username) is QueryStatus.CLAIMED
# Known positives should only use sites trusted to be reliable and unchanging
@pytest.mark.parametrize('site,username',[
('GitHub', 'ppfeister'),
('GitHub', 'sherlock-project'),
('Docker Hub', 'ppfeister'),
('Docker Hub', 'sherlock'),
])
def test_known_positives_via_status_code(self, sites_info, site, username):
assert simple_query(sites_info=sites_info, site=site, username=username) is QueryStatus.CLAIMED
# Known positives should only use sites trusted to be reliable and unchanging
@pytest.mark.parametrize('site,username',[
('Keybase', 'blue'),
('devRant', 'blue'),
])
def test_known_positives_via_response_url(self, sites_info, site, username):
assert simple_query(sites_info=sites_info, site=site, username=username) is QueryStatus.CLAIMED
# Randomly generate usernames of high length and test for positive availability
# Randomly generated usernames should be simple alnum for simplicity and high
# compatibility. Several attempts may be made ~just in case~ a real username is
# generated.
@pytest.mark.parametrize('site,random_len',[
('GitLab', 255),
('Codecademy', 30)
])
def test_likely_negatives_via_message(self, sites_info, site, random_len):
num_attempts: int = 3
attempted_usernames: list[str] = []
status: QueryStatus = QueryStatus.CLAIMED
for i in range(num_attempts):
acceptable_types = string.ascii_letters + string.digits
random_handle = ''.join(random.choice(acceptable_types) for _ in range (random_len))
attempted_usernames.append(random_handle)
status = simple_query(sites_info=sites_info, site=site, username=random_handle)
if status is QueryStatus.AVAILABLE:
break
assert status is QueryStatus.AVAILABLE, f"Could not validate available username after {num_attempts} attempts with randomly generated usernames {attempted_usernames}."
# Randomly generate usernames of high length and test for positive availability
# Randomly generated usernames should be simple alnum for simplicity and high
# compatibility. Several attempts may be made ~just in case~ a real username is
# generated.
@pytest.mark.parametrize('site,random_len',[
('GitHub', 39),
('Docker Hub', 30)
])
def test_likely_negatives_via_status_code(self, sites_info, site, random_len):
num_attempts: int = 3
attempted_usernames: list[str] = []
status: QueryStatus = QueryStatus.CLAIMED
for i in range(num_attempts):
acceptable_types = string.ascii_letters + string.digits
random_handle = ''.join(random.choice(acceptable_types) for _ in range (random_len))
attempted_usernames.append(random_handle)
status = simple_query(sites_info=sites_info, site=site, username=random_handle)
if status is QueryStatus.AVAILABLE:
break
assert status is QueryStatus.AVAILABLE, f"Could not validate available username after {num_attempts} attempts with randomly generated usernames {attempted_usernames}."
def test_username_illegal_regex(sites_info):
site: str = 'BitBucket'
invalid_handle: str = '*#$Y&*JRE'
pattern = re.compile(sites_info[site]['regexCheck'])
# Ensure that the username actually fails regex before testing sherlock
assert pattern.match(invalid_handle) is None
assert simple_query(sites_info=sites_info, site=site, username=invalid_handle) is QueryStatus.ILLEGAL

43
tests/test_ux.py Normal file
View File

@ -0,0 +1,43 @@
import pytest
from sherlock_project import sherlock
from sherlock_interactives import Interactives
from sherlock_interactives import InteractivesSubprocessError
def test_remove_nsfw(sites_obj):
nsfw_target: str = 'Pornhub'
assert nsfw_target in {site.name: site.information for site in sites_obj}
sites_obj.remove_nsfw_sites()
assert nsfw_target not in {site.name: site.information for site in sites_obj}
# Parametrized sites should *not* include Motherless, which is acting as the control
@pytest.mark.parametrize('nsfwsites', [
['Pornhub'],
['Pornhub', 'Xvideos'],
])
def test_nsfw_explicit_selection(sites_obj, nsfwsites):
for site in nsfwsites:
assert site in {site.name: site.information for site in sites_obj}
sites_obj.remove_nsfw_sites(do_not_remove=nsfwsites)
for site in nsfwsites:
assert site in {site.name: site.information for site in sites_obj}
assert 'Motherless' not in {site.name: site.information for site in sites_obj}
def test_wildcard_username_expansion():
assert sherlock.check_for_parameter('test{?}test') is True
assert sherlock.check_for_parameter('test{.}test') is False
assert sherlock.check_for_parameter('test{}test') is False
assert sherlock.check_for_parameter('testtest') is False
assert sherlock.check_for_parameter('test{?test') is False
assert sherlock.check_for_parameter('test?}test') is False
assert sherlock.multiple_usernames('test{?}test') == ["test_test" , "test-test" , "test.test"]
@pytest.mark.parametrize('cliargs', [
'',
'--site urghrtuight --egiotr',
'--',
])
def test_no_usernames_provided(cliargs):
with pytest.raises(InteractivesSubprocessError, match=r"error: the following arguments are required: USERNAMES"):
Interactives.run_cli(cliargs)

View File

@ -0,0 +1,100 @@
import pytest
import re
import rstr
from sherlock_project.sherlock import sherlock
from sherlock_project.notify import QueryNotify
from sherlock_project.result import QueryResult, QueryStatus
FALSE_POSITIVE_ATTEMPTS: int = 2 # Since the usernames are randomly generated, it's POSSIBLE that a real username can be hit
FALSE_POSITIVE_QUANTIFIER_UPPER_BOUND: int = 15 # If a pattern uses quantifiers such as `+` `*` or `{n,}`, limit the upper bound (0 to disable)
FALSE_POSITIVE_DEFAULT_PATTERN: str = r'^[a-zA-Z0-9]{7,20}$' # Used in absence of a regexCheck entry
def set_pattern_upper_bound(pattern: str, upper_bound: int = FALSE_POSITIVE_QUANTIFIER_UPPER_BOUND) -> str:
"""Set upper bound for regex patterns that use quantifiers such as `+` `*` or `{n,}`."""
def replace_upper_bound(match: re.Match) -> str: # type: ignore
lower_bound: int = int(match.group(1)) if match.group(1) else 0 # type: ignore
nonlocal upper_bound
upper_bound = upper_bound if lower_bound < upper_bound else lower_bound # type: ignore # noqa: F823
return f'{{{lower_bound},{upper_bound}}}'
pattern = re.sub(r'(?<!\\)\{(\d+),\}', replace_upper_bound, pattern) # {n,} # type: ignore
pattern = re.sub(r'(?<!\\)\+', f'{{1,{upper_bound}}}', pattern) # +
pattern = re.sub(r'(?<!\\)\*', f'{{0,{upper_bound}}}', pattern) # *
return pattern
def false_positive_check(sites_info: dict[str, dict[str, str]], site: str, pattern: str) -> QueryStatus:
"""Check if a site is likely to produce false positives."""
status: QueryStatus = QueryStatus.UNKNOWN
for _ in range(FALSE_POSITIVE_ATTEMPTS):
query_notify: QueryNotify = QueryNotify()
username: str = rstr.xeger(pattern)
result: QueryResult | str = sherlock(
username=username,
site_data=sites_info,
query_notify=query_notify,
)[site]['status']
if not hasattr(result, 'status'):
raise TypeError(f"Result for site {site} does not have 'status' attribute. Actual result: {result}")
if type(result.status) is not QueryStatus: # type: ignore
raise TypeError(f"Result status for site {site} is not of type QueryStatus. Actual type: {type(result.status)}") # type: ignore
status = result.status # type: ignore
if status in (QueryStatus.AVAILABLE, QueryStatus.WAF):
return status
return status
def false_negative_check(sites_info: dict[str, dict[str, str]], site: str) -> QueryStatus:
"""Check if a site is likely to produce false negatives."""
status: QueryStatus = QueryStatus.UNKNOWN
query_notify: QueryNotify = QueryNotify()
result: QueryResult | str = sherlock(
username=sites_info[site]['username_claimed'],
site_data=sites_info,
query_notify=query_notify,
)[site]['status']
if not hasattr(result, 'status'):
raise TypeError(f"Result for site {site} does not have 'status' attribute. Actual result: {result}")
if type(result.status) is not QueryStatus: # type: ignore
raise TypeError(f"Result status for site {site} is not of type QueryStatus. Actual type: {type(result.status)}") # type: ignore
status = result.status # type: ignore
return status
@pytest.mark.validate_targets
@pytest.mark.online
class Test_All_Targets:
@pytest.mark.validate_targets_fp
def test_false_pos(self, chunked_sites: dict[str, dict[str, str]]):
"""Iterate through all sites in the manifest to discover possible false-positive inducting targets."""
pattern: str
for site in chunked_sites:
try:
pattern = chunked_sites[site]['regexCheck']
except KeyError:
pattern = FALSE_POSITIVE_DEFAULT_PATTERN
if FALSE_POSITIVE_QUANTIFIER_UPPER_BOUND > 0:
pattern = set_pattern_upper_bound(pattern)
result: QueryStatus = false_positive_check(chunked_sites, site, pattern)
assert result is QueryStatus.AVAILABLE, f"{site} produced false positive with pattern {pattern}, result was {result}"
@pytest.mark.validate_targets_fn
def test_false_neg(self, chunked_sites: dict[str, dict[str, str]]):
"""Iterate through all sites in the manifest to discover possible false-negative inducting targets."""
for site in chunked_sites:
result: QueryStatus = false_negative_check(chunked_sites, site)
assert result is QueryStatus.CLAIMED, f"{site} produced false negative, result was {result}"

16
tests/test_version.py Normal file
View File

@ -0,0 +1,16 @@
import os
from sherlock_interactives import Interactives
import sherlock_project
def test_versioning() -> None:
# Ensure __version__ matches version presented to the user
assert sherlock_project.__version__ in Interactives.run_cli("--version")
# Ensure __init__ is single source of truth for __version__ in package
# Temporarily allows sherlock.py so as to not trigger early upgrades
found:list = Interactives.walk_sherlock_for_files_with(r'__version__ *= *')
expected:list = [
# Normalization is REQUIRED for Windows ( / vs \ )
os.path.normpath("sherlock_project/__init__.py"),
]
# Sorting is REQUIRED for Mac
assert sorted(found) == sorted(expected)

42
tox.ini Normal file
View File

@ -0,0 +1,42 @@
[tox]
requires =
tox >= 3
envlist =
lint
py313
py312
py311
py310
[testenv]
description = Attempt to build and install the package
deps =
coverage
jsonschema
pytest
rstr
allowlist_externals = coverage
commands =
coverage run --source=sherlock_project --module pytest -v
coverage report --show-missing
[testenv:offline]
deps =
jsonschema
pytest
commands =
pytest -v -m "not online"
[testenv:lint]
description = Lint with Ruff
deps =
ruff
commands =
ruff check
[gh-actions]
python =
3.13: py313
3.12: py312
3.11: py311
3.10: py310