199 Commits

Author SHA1 Message Date
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
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
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
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
29 changed files with 957 additions and 3161 deletions
+19
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
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` | arrray | 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
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
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
+45
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
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"
]
}
+9
View File
@@ -19,6 +19,15 @@ body:
- 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:
+80
View File
@@ -0,0 +1,80 @@
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:exclusions.txt >/dev/null 2>&1; then
# If the exclusions branch and file exist, compare
if git diff --quiet origin/exclusions -- 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"
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 add false_positive_exclusions.txt
git commit -m "auto: update exclusions list" || echo "No changes to commit"
git push origin exclusions
+1 -2
View File
@@ -49,11 +49,10 @@ jobs:
macos-latest,
]
python-version: [
'3.8',
'3.9',
'3.10',
'3.11',
'3.12',
'3.13',
]
steps:
- uses: actions/checkout@v4
+2 -3
View File
@@ -2,13 +2,12 @@
# 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.15.0 -t sherlock/sherlock:latest .`
# i.e. `docker build -t sherlock/sherlock:0.16.0 -t sherlock/sherlock:latest .`
FROM python:3.12-slim-bullseye as build
WORKDIR /sherlock
RUN apt-get update \
pip3 install --no-cache-dir --upgrade pip
RUN pip3 install --no-cache-dir --upgrade pip
FROM python:3.12-slim-bullseye
WORKDIR /sherlock
+5 -2
View File
@@ -4,8 +4,11 @@
import json
import os
DATA_REL_URI: str = "sherlock_project/resources/data.json"
# Read the data.json file
with open("sherlock/resources/data.json", "r", encoding="utf-8") as data_file:
with open(DATA_REL_URI, "r", encoding="utf-8") as data_file:
data: dict = json.load(data_file)
# Removes schema-specific keywords for proper processing
@@ -27,7 +30,7 @@ with open("output/sites.mdx", "w") as site_file:
site_file.write(f"1. [{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:
with open(DATA_REL_URI, "w") as data_file:
sorted_data = json.dumps(data, indent=2, sort_keys=True)
data_file.write(sorted_data)
data_file.write("\n")
+35 -13
View File
@@ -1,6 +1,6 @@
<p align=center>
<p align="center">
<br>
<a href="https://sherlock-project.github.io/" target="_blank"><img src="images/sherlock-logo.png"/></a>
<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>
@@ -15,25 +15,27 @@
</p>
<p align="center">
<img width="70%" height="70%" src="images/demo.png"/>
</a>
<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.
| | Command | Notes |
| - | - | - |
| PyPI | `pipx install sherlock-project` | `pip` may be used in place of `pipx` |
| Docker | `docker pull sherlock/sherlock` | |
| Debian family | `apt install sherlock` | Kali, Parrot, Debian Testing and Sid |
| BlackArch | `pacman -S sherlock` | |
| Homebrew | `brew install sherlock` | |
| 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)
## Usage
## General usage
To search for only one user:
```bash
@@ -95,15 +97,35 @@ optional arguments:
--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" noZoom />
<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" />
+105 -29
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.
@@ -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
@@ -1919,3 +1890,108 @@ __2024-06-10 :__ Http request returns 403 forbidden, and tries to verify the con
"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"
},
```
+5 -3
View File
@@ -40,7 +40,7 @@ repository = "https://github.com/sherlock-project/sherlock"
"Bug Tracker" = "https://github.com/sherlock-project/sherlock/issues"
[tool.poetry.dependencies]
python = "^3.8"
python = "^3.9"
certifi = ">=2019.6.16"
colorama = "^0.4.1"
PySocks = "^1.7.0"
@@ -48,8 +48,7 @@ requests = "^2.22.0"
requests-futures = "^1.0.0"
stem = "^1.8.0"
torrequest = "^0.1.0"
# pandas can likely be bumped up to ^2.0.0 after fc39 EOL
pandas = ">=1.0.0,<3.0.0"
pandas = "^2.2.1"
openpyxl = "^3.0.10"
[tool.poetry.extras]
@@ -57,6 +56,9 @@ tor = ["torrequest"]
[tool.poetry.group.dev.dependencies]
jsonschema = "^4.0.0"
rstr = "^3.2.2"
pytest = "^8.4.2"
pytest-xdist = "^3.8.0"
[tool.poetry.scripts]
sherlock = 'sherlock_project.sherlock:main'
+4 -1
View File
@@ -1,4 +1,7 @@
[pytest]
addopts = --strict-markers
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.
File diff suppressed because it is too large Load Diff
-80
View File
@@ -1,80 +0,0 @@
{
"$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": {
"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" ] }
}
}
+1 -1
View File
@@ -10,6 +10,6 @@ import_error_test_var = None
__shortname__ = "Sherlock"
__longname__ = "Sherlock: Find Usernames Across Social Networks"
__version__ = "0.15.0"
__version__ = "0.16.0"
forge_api_latest_release = "https://api.github.com/repos/sherlock-project/sherlock/releases/latest"
+2 -2
View File
@@ -14,8 +14,8 @@ 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, 8):
print(f"Sherlock requires Python 3.8+\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)
from sherlock_project import sherlock
View File
+288 -215
View File
@@ -17,26 +17,12 @@
"urlMain": "https://2Dimensions.com/",
"username_claimed": "blue"
},
"3dnews": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430.",
"errorType": "message",
"url": "http://forum.3dnews.ru/member.php?username={}",
"urlMain": "http://forum.3dnews.ru/",
"username_claimed": "red"
},
"7Cups": {
"errorType": "status_code",
"url": "https://www.7cups.com/@{}",
"urlMain": "https://www.7cups.com/",
"username_claimed": "blue"
},
"8tracks": {
"errorMsg": "This page has vanished",
"errorType": "message",
"url": "https://8tracks.com/{}",
"urlMain": "https://8tracks.com/",
"username_claimed": "blue"
},
"9GAG": {
"errorType": "status_code",
"url": "https://www.9gag.com/u/{}",
@@ -72,13 +58,6 @@
"urlMain": "https://admireme.vip/",
"username_claimed": "DemiDevil"
},
"Air Pilot Life": {
"errorMsg": "Oops! That page doesn\u2019t exist or is private",
"errorType": "message",
"url": "https://airlinepilot.life/u/{}",
"urlMain": "https://airlinepilot.life/",
"username_claimed": "chris"
},
"Airbit": {
"errorType": "status_code",
"url": "https://airbit.com/{}",
@@ -91,12 +70,6 @@
"urlMain": "https://www.airliners.net/",
"username_claimed": "yushinlin"
},
"Alik.cz": {
"errorType": "status_code",
"url": "https://www.alik.cz/u/{}",
"urlMain": "https://www.alik.cz/",
"username_claimed": "julian"
},
"All Things Worn": {
"errorMsg": "Sell Used Panties",
"errorType": "message",
@@ -113,12 +86,6 @@
"urlMain": "https://allmylinks.com/",
"username_claimed": "blue"
},
"Amino": {
"errorType": "status_code",
"url": "https://aminoapps.com/u/{}",
"urlMain": "https://aminoapps.com",
"username_claimed": "blue"
},
"AniWorld": {
"errorMsg": "Dieses Profil ist nicht verf\u00fcgbar",
"errorType": "message",
@@ -165,7 +132,8 @@
"__comment__": "'The resource could not be found' relates to archive downtime",
"errorMsg": [
"could not fetch an account with user item identifier",
"The resource could not be found"
"The resource could not be found",
"Internet Archive services are temporarily offline"
],
"errorType": "message",
"url": "https://archive.org/details/@{}",
@@ -191,13 +159,11 @@
"urlMain": "https://ask.fedoraproject.org/",
"username_claimed": "red"
},
"AskFM": {
"errorMsg": "Well, apparently not anymore.",
"errorType": "message",
"regexCheck": "^[a-zA-Z0-9_]{3,40}$",
"url": "https://ask.fm/{}",
"urlMain": "https://ask.fm/",
"username_claimed": "blue"
"Atcoder": {
"errorType": "status_code",
"url": "https://atcoder.jp/users/{}",
"urlMain": "https://atcoder.jp/",
"username_claimed": "ksun48"
},
"Audiojungle": {
"errorType": "status_code",
@@ -219,17 +185,10 @@
"urlMain": "https://www.avizo.cz/",
"username_claimed": "blue"
},
"BLIP.fm": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9_]{1,30}$",
"url": "https://blip.fm/{}",
"urlMain": "https://blip.fm/",
"username_claimed": "blue"
},
"BOOTH": {
"errorType": "response_url",
"errorUrl": "https://booth.pm/",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.booth.pm/",
"urlMain": "https://booth.pm/",
"username_claimed": "blue"
@@ -265,12 +224,6 @@
"urlMain": "https://www.biggerpockets.com/",
"username_claimed": "blue"
},
"Bikemap": {
"errorType": "status_code",
"url": "https://www.bikemap.net/en/u/{}/routes/created/",
"urlMain": "https://www.bikemap.net/",
"username_claimed": "bikemap"
},
"BioHacking": {
"errorType": "status_code",
"url": "https://forum.dangerousthings.com/u/{}",
@@ -297,6 +250,12 @@
"urlMain": "https://www.blipfoto.com/",
"username_claimed": "blue"
},
"Blitz Tactics": {
"errorType": "status_code",
"url": "https://blitztactics.com/{}",
"urlMain": "https://blitztactics.com/",
"username_claimed": "Lance5500"
},
"Blogger": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$",
@@ -304,11 +263,19 @@
"urlMain": "https://www.blogger.com/",
"username_claimed": "blue"
},
"BodyBuilding": {
"errorType": "response_url",
"errorUrl": "https://bodyspace.bodybuilding.com/",
"url": "https://bodyspace.bodybuilding.com/{}",
"urlMain": "https://bodyspace.bodybuilding.com/",
"Bluesky": {
"errorType": "status_code",
"url": "https://bsky.app/profile/{}.bsky.social",
"urlProbe": "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor={}.bsky.social",
"urlMain": "https://bsky.app/",
"username_claimed": "mcuban"
},
"BoardGameGeek": {
"errorType": "message",
"regexCheck": "^[a-zA-Z0-9_]*$",
"errorMsg": "User not found",
"url": "https://boardgamegeek.com/user/{}",
"urlMain": "https://boardgamegeek.com",
"username_claimed": "blue"
},
"BongaCams": {
@@ -391,7 +358,7 @@
"Carbonmade": {
"errorType": "response_url",
"errorUrl": "https://carbonmade.com/fourohfour?domain={}.carbonmade.com",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.carbonmade.com",
"urlMain": "https://carbonmade.com/",
"username_claimed": "jenny"
@@ -403,6 +370,12 @@
"urlMain": "https://career.habr.com/",
"username_claimed": "blue"
},
"CashApp": {
"errorType": "status_code",
"url": "https://cash.app/${}",
"urlMain": "https://cash.app",
"username_claimed": "hotdiggitydog"
},
"Championat": {
"errorType": "status_code",
"url": "https://www.championat.com/user/{}",
@@ -565,7 +538,7 @@
},
"Crevado": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.crevado.com",
"urlMain": "https://crevado.com/",
"username_claimed": "blue"
@@ -634,12 +607,38 @@
"urlMain": "https://deviantart.com",
"username_claimed": "blue"
},
"DigitalSpy": {
"errorMsg": "The page you were looking for could not be found.",
"errorType": "message",
"url": "https://forums.digitalspy.com/profile/{}",
"urlMain": "https://forums.digitalspy.com/",
"username_claimed": "blue",
"regexCheck": "^\\w{3,20}$"
},
"Discogs": {
"errorType": "status_code",
"url": "https://www.discogs.com/user/{}",
"urlMain": "https://www.discogs.com/",
"username_claimed": "blue"
},
"Discord": {
"errorType": "message",
"url": "https://discord.com",
"urlMain": "https://discord.com/",
"urlProbe": "https://discord.com/api/v9/unique-username/username-attempt-unauthed",
"errorMsg": [
"{\"taken\":false}",
"The resource is being rate limited"
],
"request_method": "POST",
"request_payload": {
"username": "{}"
},
"headers": {
"Content-Type": "application/json"
},
"username_claimed": "blue"
},
"Discuss.Elastic.co": {
"errorType": "status_code",
"url": "https://discuss.elastic.co/u/{}",
@@ -670,9 +669,7 @@
"Duolingo": {
"errorMsg": "{\"users\":[]}",
"errorType": "message",
"headers": {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0"
},
"url": "https://www.duolingo.com/profile/{}",
"urlMain": "https://duolingo.com/",
"urlProbe": "https://www.duolingo.com/2017-06-30/users?username={}",
@@ -685,6 +682,13 @@
"urlMain": "https://community.eintracht.de/",
"username_claimed": "mmammu"
},
"Empretienda AR": {
"__comment__": "Note that Error Connecting responses may be indicative of unclaimed handles",
"errorType": "status_code",
"url": "https://{}.empretienda.com.ar",
"urlMain": "https://empretienda.com",
"username_claimed": "camalote"
},
"Envato Forum": {
"errorType": "status_code",
"url": "https://forums.envato.com/u/{}",
@@ -700,10 +704,17 @@
},
"Exposure": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9-]{1,63}$",
"url": "https://{}.exposure.co/",
"urlMain": "https://exposure.co/",
"username_claimed": "jonasjacobsson"
},
"exophase": {
"errorType": "status_code",
"url": "https://www.exophase.com/user/{}/",
"urlMain": "https://www.exophase.com/",
"username_claimed": "blue"
},
"EyeEm": {
"errorType": "status_code",
"url": "https://www.eyeem.com/u/{}",
@@ -728,25 +739,19 @@
"urlMain": "https://www.fandom.com/",
"username_claimed": "Jungypoo"
},
"Fanpop": {
"errorType": "response_url",
"errorUrl": "https://www.fanpop.com/",
"url": "https://www.fanpop.com/fans/{}",
"urlMain": "https://www.fanpop.com/",
"username_claimed": "blue"
},
"Finanzfrage": {
"errorType": "status_code",
"url": "https://www.finanzfrage.net/nutzer/{}",
"urlMain": "https://www.finanzfrage.net/",
"username_claimed": "finanzfrage"
},
"Fiverr": {
"errorMsg": "\"status\":\"success\"",
"errorType": "message",
"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"
},
"Flickr": {
"errorType": "status_code",
"url": "https://www.flickr.com/people/{}",
@@ -795,6 +800,13 @@
"urlMain": "https://fosstodon.org/",
"username_claimed": "blue"
},
"Framapiaf": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9_]{1,30}$",
"url": "https://framapiaf.org/@{}",
"urlMain": "https://framapiaf.org",
"username_claimed": "pylapp"
},
"Freelance.habr": {
"errorMsg": "<div class=\"icon_user_locked\"></div>",
"errorType": "message",
@@ -877,14 +889,15 @@
"username_claimed": "bob"
},
"Giphy": {
"errorType": "status_code",
"errorType": "message",
"errorMsg": "<title> GIFs - Find &amp; Share on GIPHY</title>",
"url": "https://giphy.com/{}",
"urlMain": "https://giphy.com/",
"username_claimed": "blue"
"username_claimed": "red"
},
"GitBook": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.gitbook.io/",
"urlMain": "https://gitbook.com/",
"username_claimed": "gitbook"
@@ -904,6 +917,12 @@
"urlProbe": "https://gitlab.com/api/v4/users?username={}",
"username_claimed": "blue"
},
"Gitea": {
"errorType": "status_code",
"url": "https://gitea.com/{}",
"urlMain": "https://gitea.com/",
"username_claimed": "xorm"
},
"Gitee": {
"errorType": "status_code",
"url": "https://gitee.com/{}",
@@ -960,8 +979,8 @@
},
"HackTheBox": {
"errorType": "status_code",
"url": "https://forum.hackthebox.eu/profile/{}",
"urlMain": "https://forum.hackthebox.eu/",
"url": "https://forum.hackthebox.com/u/{}",
"urlMain": "https://forum.hackthebox.com/",
"username_claimed": "angar"
},
"Hackaday": {
@@ -971,7 +990,7 @@
"username_claimed": "adam"
},
"HackenProof (Hackers)": {
"errorMsg": "<title>Web3\u2019s Largest Ethical Hackers Community | HackenProof</title>",
"errorMsg": "Page not found",
"errorType": "message",
"regexCheck": "^[\\w-]{,34}$",
"url": "https://hackenproof.com/hackers/{}",
@@ -1044,8 +1063,7 @@
"username_claimed": "red"
},
"Houzz": {
"errorMsg": "The page you requested was not found.",
"errorType": "message",
"errorType": "status_code",
"url": "https://houzz.com/user/{}",
"urlMain": "https://houzz.com/",
"username_claimed": "blue"
@@ -1064,17 +1082,17 @@
"username_claimed": "blue"
},
"HudsonRock": {
"errorMsg": "No results",
"errorMsg": "This username is not associated",
"errorType": "message",
"url": "https://cavalier.hudsonrock.com/api/json/v2/osint-tools/search-by-username?username={}",
"urlMain": "https://hudsonrock.com",
"username_claimed": "testadmin"
},
"ICQ": {
"Hugging Face": {
"errorType": "status_code",
"url": "https://icq.im/{}/en",
"urlMain": "https://icq.com/",
"username_claimed": "Micheal"
"url": "https://huggingface.co/{}",
"urlMain": "https://huggingface.co/",
"username_claimed": "Pasanlaksitha"
},
"IFTTT": {
"errorType": "status_code",
@@ -1121,7 +1139,7 @@
"errorType": "status_code",
"url": "https://instagram.com/{}",
"urlMain": "https://instagram.com/",
"urlProbe": "https://www.picuki.com/profile/{}",
"urlProbe": "https://imginn.com/{}",
"username_claimed": "instagram"
},
"Instructables": {
@@ -1154,7 +1172,7 @@
},
"Itch.io": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.itch.io/",
"urlMain": "https://itch.io/",
"username_claimed": "blue"
@@ -1175,7 +1193,7 @@
},
"Jimdo": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.jimdosite.com",
"urlMain": "https://jimdosite.com/",
"username_claimed": "jenny"
@@ -1186,18 +1204,18 @@
"urlMain": "https://discourse.joplinapp.org/",
"username_claimed": "laurent"
},
"KEAKR": {
"errorType": "status_code",
"url": "https://www.keakr.com/en/profile/{}",
"urlMain": "https://www.keakr.com/",
"username_claimed": "beats"
},
"Kaggle": {
"errorType": "status_code",
"url": "https://www.kaggle.com/{}",
"urlMain": "https://www.kaggle.com/",
"username_claimed": "dansbecker"
},
"kaskus": {
"errorType": "status_code",
"url": "https://www.kaskus.co.id/@{}",
"urlMain": "https://www.kaskus.co.id/",
"username_claimed": "l0mbart"
},
"Keybase": {
"errorType": "status_code",
"url": "https://keybase.io/{}",
@@ -1206,8 +1224,7 @@
},
"Kick": {
"__comment__": "Cloudflare. Only viable when proxied.",
"errorMsg": "Not Found",
"errorType": "message",
"errorType": "status_code",
"url": "https://kick.com/{}",
"urlMain": "https://kick.com/",
"urlProbe": "https://kick.com/api/v2/channels/{}",
@@ -1224,8 +1241,7 @@
"Kongregate": {
"errorType": "status_code",
"headers": {
"Accept": "text/html",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/116.0"
"Accept": "text/html"
},
"regexCheck": "^[a-zA-Z][a-zA-Z0-9_-]*$",
"url": "https://www.kongregate.com/accounts/{}",
@@ -1264,24 +1280,23 @@
"username_claimed": "blue"
},
"LibraryThing": {
"errorMsg": "Catalog your books online",
"errorMsg": "<p>Error: This user doesn't exist</p>",
"errorType": "message",
"headers": {
"Cookie": "LTAnonSessionID=3159599315; LTUnifiedCookie=%7B%22areyouhuman%22%3A1%7D; "
},
"url": "https://www.librarything.com/profile/{}",
"urlMain": "https://www.librarything.com/",
"username_claimed": "blue"
},
"Lichess": {
"errorMsg": "Page not found!",
"errorType": "message",
"errorType": "status_code",
"url": "https://lichess.org/@/{}",
"urlMain": "https://lichess.org",
"username_claimed": "blue"
"username_claimed": "john"
},
"LinkedIn": {
"errorType": "status_code",
"headers": {
"User-Agent": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/W.X.Y.Z Safari/537.36"
},
"regexCheck": "^[a-zA-Z0-9]{3,100}$",
"request_method": "GET",
"url": "https://linkedin.com/in/{}",
@@ -1296,6 +1311,12 @@
"urlMain": "https://linktr.ee/",
"username_claimed": "anne"
},
"LinuxFR.org": {
"errorType": "status_code",
"url": "https://linuxfr.org/users/{}",
"urlMain": "https://linuxfr.org/",
"username_claimed": "pylapp"
},
"Listed": {
"errorType": "response_url",
"errorUrl": "https://listed.to/@{}",
@@ -1336,12 +1357,12 @@
"urlMain": "https://forums.mmorpg.com/",
"username_claimed": "goku"
},
"Mapify": {
"errorType": "response_url",
"errorUrl": "https://mapify.travel/{}",
"url": "https://mapify.travel/{}",
"urlMain": "https://mapify.travel/",
"username_claimed": "mapify"
"Mamot": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9_]{1,30}$",
"url": "https://mamot.fr/@{}",
"urlMain": "https://mamot.fr/",
"username_claimed": "anciensEnssat"
},
"Medium": {
"errorMsg": "<body",
@@ -1358,8 +1379,8 @@
"username_claimed": "blue"
},
"Minecraft": {
"errorCode": 204,
"errorType": "status_code",
"errorMsg": "Couldn't find any profile with name",
"errorType": "message",
"url": "https://api.mojang.com/users/profiles/minecraft/{}",
"urlMain": "https://minecraft.net/",
"username_claimed": "blue"
@@ -1504,11 +1525,12 @@
"urlMain": "https://nyaa.si/",
"username_claimed": "blue"
},
"OGUsers": {
"errorType": "status_code",
"url": "https://ogu.gg/{}",
"urlMain": "https://ogu.gg/",
"username_claimed": "ogusers"
"Open Collective": {
"errorMsg": "Oops! Page not found",
"errorType": "message",
"url": "https://opencollective.com/{}",
"urlMain": "https://opencollective.com/",
"username_claimed": "pylapp"
},
"OpenStreetMap": {
"errorType": "status_code",
@@ -1530,6 +1552,13 @@
"urlMain": "https://ourdjtalk.com/",
"username_claimed": "steve"
},
"Outgress": {
"errorMsg": "Outgress - Error",
"errorType": "message",
"url": "https://outgress.com/agents/{}",
"urlMain": "https://outgress.com/",
"username_claimed": "pylapp"
},
"PCGamer": {
"errorMsg": "The specified member cannot be found. Please enter a member's entire name.",
"errorType": "message",
@@ -1591,12 +1620,31 @@
"urlMain": "https://www.pinkbike.com/",
"username_claimed": "blue"
},
"pixelfed.social": {
"errorType": "status_code",
"url": "https://pixelfed.social/{}/",
"urlMain": "https://pixelfed.social",
"username_claimed": "pylapp"
},
"PlayStore": {
"errorType": "status_code",
"url": "https://play.google.com/store/apps/developer?id={}",
"urlMain": "https://play.google.com/store",
"username_claimed": "Facebook"
},
"Playstrategy": {
"errorType": "status_code",
"url": "https://playstrategy.org/@/{}",
"urlMain": "https://playstrategy.org",
"username_claimed": "oruro"
},
"Plurk": {
"errorMsg": "User Not Found!",
"errorType": "message",
"url": "https://www.plurk.com/{}",
"urlMain": "https://www.plurk.com/",
"username_claimed": "plurkoffice"
},
"PocketStars": {
"errorMsg": "Join Your Favorite Adult Stars",
"errorType": "message",
@@ -1639,12 +1687,25 @@
"username_claimed": "blue"
},
"ProductHunt": {
"errorMsg": "We seem to have lost this page",
"errorType": "message",
"errorType": "status_code",
"url": "https://www.producthunt.com/@{}",
"urlMain": "https://www.producthunt.com/",
"username_claimed": "jenny"
},
"programming.dev": {
"errorMsg": "Error!",
"errorType": "message",
"url": "https://programming.dev/u/{}",
"urlMain": "https://programming.dev",
"username_claimed": "pylapp"
},
"Pychess": {
"errorType": "message",
"errorMsg": "404",
"url": "https://www.pychess.org/@/{}",
"urlMain": "https://www.pychess.org",
"username_claimed": "gbtami"
},
"PromoDJ": {
"errorType": "status_code",
"url": "http://promodj.com/{}",
@@ -1654,16 +1715,23 @@
"PyPi": {
"errorType": "status_code",
"url": "https://pypi.org/user/{}",
"urlProbe": "https://pypi.org/_includes/administer-user-include/{}",
"urlMain": "https://pypi.org",
"username_claimed": "Blue"
},
"Rajce.net": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.rajce.idnes.cz/",
"urlMain": "https://www.rajce.idnes.cz/",
"username_claimed": "blue"
},
"Rarible": {
"errorType": "status_code",
"url": "https://rarible.com/marketplace/api/v4/urls/{}",
"urlMain": "https://rarible.com/",
"username_claimed": "blue"
},
"Rate Your Music": {
"errorType": "status_code",
"url": "https://rateyourmusic.com/~{}",
@@ -1800,12 +1868,6 @@
"urlMain": "https://www.shitpostbot.com/",
"username_claimed": "blue"
},
"Shpock": {
"errorType": "status_code",
"url": "https://www.shpock.com/shop/{}/items",
"urlMain": "https://www.shpock.com/",
"username_claimed": "user"
},
"Signal": {
"errorMsg": "Oops! That page doesn\u2019t exist or is private.",
"errorType": "message",
@@ -1841,7 +1903,8 @@
"username_claimed": "blue"
},
"SlideShare": {
"errorType": "status_code",
"errorType": "message",
"errorMsg": "<title>Username available</title>",
"url": "https://slideshare.net/{}",
"urlMain": "https://slideshare.net/",
"username_claimed": "blue"
@@ -1855,6 +1918,7 @@
},
"SmugMug": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z]{1,35}$",
"url": "https://{}.smugmug.com",
"urlMain": "https://smugmug.com",
"username_claimed": "winchester"
@@ -1893,12 +1957,17 @@
"urlMain": "https://soylentnews.org",
"username_claimed": "adam"
},
"SpeakerDeck": {
"errorType": "status_code",
"url": "https://speakerdeck.com/{}",
"urlMain": "https://speakerdeck.com/",
"username_claimed": "pylapp"
},
"Speedrun.com": {
"errorMsg": "Not found",
"errorType": "message",
"url": "https://speedrun.com/user/{}",
"errorType": "status_code",
"url": "https://speedrun.com/users/{}",
"urlMain": "https://speedrun.com/",
"username_claimed": "3Tau"
"username_claimed": "example"
},
"Spells8": {
"errorType": "status_code",
@@ -1939,9 +2008,7 @@
},
"Spotify": {
"errorType": "status_code",
"headers": {
"user-agent": "PostmanRuntime/7.29.2"
},
"url": "https://open.spotify.com/user/{}",
"urlMain": "https://open.spotify.com/",
"username_claimed": "blue"
@@ -1968,8 +2035,7 @@
"username_claimed": "blue"
},
"Strava": {
"errorMsg": "Strava | Running, Cycling &amp; Hiking App - Train, Track &amp; Share",
"errorType": "message",
"errorType": "status_code",
"regexCheck": "^[^.]*?$",
"url": "https://www.strava.com/athletes/{}",
"urlMain": "https://www.strava.com/",
@@ -1989,12 +2055,19 @@
"urlProbe": "https://ch.tetr.io/api/users/{}",
"username_claimed": "osk"
},
"TLDR Legal": {
"Tiendanube": {
"url": "https://{}.mitiendanube.com/",
"urlMain": "https://www.tiendanube.com/",
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9]{3,20}$",
"url": "https://tldrlegal.com/users/{}/",
"urlMain": "https://tldrlegal.com/",
"username_claimed": "kevin"
"username_claimed": "blue"
},
"Topcoder": {
"errorType": "status_code",
"url": "https://profiles.topcoder.com/{}/",
"urlMain": "https://topcoder.com/",
"username_claimed": "USER",
"urlProbe": "https://api.topcoder.com/v5/members/{}",
"regexCheck": "[a-zA-Z0-9 ]"
},
"TRAKTRAIN": {
"errorType": "status_code",
@@ -2039,14 +2112,6 @@
"urlMain": "https://www.tnaflix.com/",
"username_claimed": "hacker"
},
"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"
},
"TradingView": {
"errorType": "status_code",
"request_method": "GET",
@@ -2104,20 +2169,16 @@
"urlMain": "https://tweakers.net",
"username_claimed": "femme"
},
"Twitch": {
"errorType": "status_code",
"url": "https://www.twitch.tv/{}",
"urlMain": "https://www.twitch.tv/",
"urlProbe": "https://m.twitch.tv/{}",
"username_claimed": "jenny"
},
"Twitter": {
"errorMsg": "<div class=\"error-panel\"><span>User ",
"errorMsg": [
"<div class=\"error-panel\"><span>User ",
"<title>429 Too Many Requests</title>"
],
"errorType": "message",
"regexCheck": "^[a-zA-Z0-9_]{1,15}$",
"url": "https://x.com/{}",
"urlMain": "https://x.com/",
"urlProbe": "https://nitter.net/{}",
"urlProbe": "https://nitter.privacydev.net/{}",
"username_claimed": "blue"
},
"Typeracer": {
@@ -2159,6 +2220,12 @@
"urlMain": "https://vsco.co/",
"username_claimed": "blue"
},
"Velog": {
"errorType": "status_code",
"url": "https://velog.io/@{}/posts",
"urlMain": "https://velog.io/",
"username_claimed": "qlgks1"
},
"Velomania": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430.",
"errorType": "message",
@@ -2180,7 +2247,8 @@
"username_claimed": "jenny"
},
"Vero": {
"errorType": "status_code",
"errorMsg": "Not Found",
"errorType": "message",
"request_method": "GET",
"url": "https://vero.co/{}",
"urlMain": "https://vero.co/",
@@ -2200,6 +2268,12 @@
"urlProbe": "https://www.virustotal.com/ui/users/{}/avatar",
"username_claimed": "blue"
},
"VLR": {
"errorType": "status_code",
"url": "https://www.vlr.gg/user/{}",
"urlMain": "https://www.vlr.gg",
"username_claimed": "optms"
},
"WICG Forum": {
"errorType": "status_code",
"regexCheck": "^(?![.-])[a-zA-Z0-9_.-]{3,20}$",
@@ -2222,7 +2296,7 @@
},
"WebNode": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.webnode.cz/",
"urlMain": "https://www.webnode.cz/",
"username_claimed": "radkabalcarova"
@@ -2236,6 +2310,7 @@
},
"Weebly": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9-]{1,63}$",
"url": "https://{}.weebly.com/",
"urlMain": "https://weebly.com/",
"username_claimed": "blue"
@@ -2262,7 +2337,7 @@
},
"Wix": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.wix.com",
"urlMain": "https://wix.com/",
"username_claimed": "support"
@@ -2350,9 +2425,7 @@
},
"YouTube": {
"errorType": "status_code",
"headers": {
"User-Agent": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/W.X.Y.Z Safari/537.36"
},
"url": "https://www.youtube.com/@{}",
"urlMain": "https://www.youtube.com/",
"username_claimed": "youtube"
@@ -2369,13 +2442,6 @@
"urlMain": "http://www.authorstream.com/",
"username_claimed": "blue"
},
"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",
"errorType": "message",
"url": "https://www.baby.ru/u/{}/",
"urlMain": "https://www.baby.ru/",
"username_claimed": "blue"
},
"babyblogRU": {
"errorType": "response_url",
"errorUrl": "https://www.babyblog.ru/",
@@ -2480,12 +2546,6 @@
"urlMain": "https://www.geocaching.com/",
"username_claimed": "blue"
},
"gfycat": {
"errorType": "status_code",
"url": "https://gfycat.com/@{}",
"urlMain": "https://gfycat.com/",
"username_claimed": "Test"
},
"habr": {
"errorType": "status_code",
"url": "https://habr.com/ru/users/{}",
@@ -2505,13 +2565,6 @@
"urlMain": "https://www.hunting.ru/forum/",
"username_claimed": "red"
},
"iMGSRC.RU": {
"errorType": "response_url",
"errorUrl": "https://imgsrc.ru/",
"url": "https://imgsrc.ru/main/user.php?user={}",
"urlMain": "https://imgsrc.ru/",
"username_claimed": "blue"
},
"igromania": {
"errorMsg": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430.",
"errorType": "message",
@@ -2589,12 +2642,6 @@
"urlMain": "https://chaos.social/",
"username_claimed": "Gargron"
},
"mastodon.technology": {
"errorType": "status_code",
"url": "https://mastodon.technology/@{}",
"urlMain": "https://mastodon.xyz/",
"username_claimed": "ashfurrow"
},
"mastodon.xyz": {
"errorType": "status_code",
"url": "https://mastodon.xyz/@{}",
@@ -2635,7 +2682,7 @@
},
"nnRU": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"regexCheck": "^[\\w@-]+?$",
"url": "https://{}.www.nn.ru/",
"urlMain": "https://www.nn.ru/",
"username_claimed": "blue"
@@ -2652,6 +2699,14 @@
"urlMain": "https://www.npmjs.com/",
"username_claimed": "kennethsweezy"
},
"omg.lol": {
"errorMsg": "\"available\": true",
"errorType": "message",
"url": "https://{}.omg.lol",
"urlMain": "https://home.omg.lol",
"urlProbe": "https://api.omg.lol/address/{}/availability",
"username_claimed": "adam"
},
"opennet": {
"errorMsg": "\u0418\u043c\u044f \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e",
"errorType": "message",
@@ -2693,12 +2748,6 @@
"urlMain": "https://prog.hu/",
"username_claimed": "Sting"
},
"queer.af": {
"errorType": "status_code",
"url": "https://queer.af/@{}",
"urlMain": "https://queer.af/",
"username_claimed": "erincandescent"
},
"satsisRU": {
"errorType": "status_code",
"url": "https://satsis.info/user/{}",
@@ -2711,13 +2760,6 @@
"urlMain": "https://sessionize.com/",
"username_claimed": "jason-mayes"
},
"skyrock": {
"errorType": "status_code",
"regexCheck": "^[a-zA-Z0-9@_-]$",
"url": "https://{}.skyrock.com/",
"urlMain": "https://skyrock.com/",
"username_claimed": "red"
},
"social.tchncs.de": {
"errorType": "status_code",
"url": "https://social.tchncs.de/@{}",
@@ -2736,23 +2778,39 @@
"urlMain": "https://www.svidbook.ru/",
"username_claimed": "green"
},
"threads": {
"errorMsg": "<title>Threads</title>",
"errorType": "message",
"headers": {
"Sec-Fetch-Mode": "navigate"
},
"url": "https://www.threads.net/@{}",
"urlMain": "https://www.threads.net/",
"username_claimed": "zuck"
},
"toster": {
"errorType": "status_code",
"url": "https://www.toster.ru/user/{}/answers",
"urlMain": "https://www.toster.ru/",
"username_claimed": "adam"
},
"tumblr": {
"errorType": "status_code",
"url": "https://{}.tumblr.com/",
"urlMain": "https://www.tumblr.com/",
"username_claimed": "goku"
},
"uid": {
"errorType": "status_code",
"url": "http://uid.me/{}",
"urlMain": "https://uid.me/",
"username_claimed": "blue"
},
"wiki.vg": {
"write.as": {
"errorType": "status_code",
"url": "https://wiki.vg/User:{}",
"urlMain": "https://wiki.vg/",
"username_claimed": "Auri"
"url": "https://write.as/{}",
"urlMain": "https://write.as",
"username_claimed": "pylapp"
},
"xHamster": {
"errorType": "status_code",
@@ -2767,5 +2825,20 @@
"url": "https://www.znanylekarz.pl/{}",
"urlMain": "https://znanylekarz.pl",
"username_claimed": "janusz-nowak"
},
"Bluesky": {
"errorType": "status_code",
"url": "https://bsky.app/profile/{}.bsky.social",
"urlProbe": "https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor={}.bsky.social",
"urlMain": "https://bsky.app/",
"username_claimed": "mcuban"
},
"Platzi": {
"errorType": "status_code",
"errorCode": 404,
"url": "https://platzi.com/p/{}/",
"urlMain": "https://platzi.com/",
"username_claimed": "freddier",
"request_method": "GET"
}
}
+63 -21
View File
@@ -24,6 +24,7 @@ import re
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
@@ -167,15 +168,15 @@ def multiple_usernames(username):
def sherlock(
username,
site_data,
username: str,
site_data: dict[str, dict[str, str]],
query_notify: QueryNotify,
tor: bool = False,
unique_tor: bool = False,
dump_response: bool = False,
proxy=None,
timeout=60,
):
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.
@@ -261,7 +262,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:
@@ -412,8 +413,10 @@ def sherlock(
# 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', # 2024-05-13 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:
@@ -474,7 +477,7 @@ def sherlock(
raise ValueError(
f"Unknown Error Type '{error_type}' for " f"site '{social_network}'"
)
if dump_response:
print("+++++++++++++++++++++")
print(f"TARGET NAME : {social_network}")
@@ -504,7 +507,7 @@ def sherlock(
print("+++++++++++++++++++++")
# Notify caller about results of query.
result = QueryResult(
result: QueryResult = QueryResult(
username=username,
site_name=social_network,
site_url_user=url,
@@ -653,7 +656,7 @@ def main():
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",
@@ -716,6 +719,22 @@ def main():
help="Include checking of NSFW sites from default list.",
)
parser.add_argument(
"--no-txt",
action="store_true",
dest="no_txt",
default=False,
help="Disable 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
@@ -773,10 +792,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).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)
@@ -847,14 +888,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 not args.no_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"
+36 -5
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_project/resources/data.json"
data_file_path = MANIFEST_URL
# Ensure that specified data file has correct extension.
if not data_file_path.lower().endswith(".json"):
@@ -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)
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.
@@ -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):
+13 -3
View File
@@ -4,6 +4,11 @@ import urllib
import pytest
from sherlock_project.sites import SitesInformation
def fetch_local_manifest() -> dict[str, dict[str, str]]:
sites_obj = SitesInformation(data_file_path=os.path.join(os.path.dirname(__file__), "../sherlock_project/resources/data.json"))
sites_iterable = {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"))
@@ -11,9 +16,7 @@ def sites_obj():
@pytest.fixture(scope="session")
def sites_info():
sites_obj = SitesInformation(data_file_path=os.path.join(os.path.dirname(__file__), "../sherlock_project/resources/data.json"))
sites_iterable = {site.name: site.information for site in sites_obj}
yield sites_iterable
yield fetch_local_manifest()
@pytest.fixture(scope="session")
def remote_schema():
@@ -21,3 +24,10 @@ def remote_schema():
with urllib.request.urlopen(schema_url) as remoteschema:
schemadat = json.load(remoteschema)
yield schemadat
def pytest_generate_tests(metafunc):
if "chunked_sites" in metafunc.fixturenames:
sites_info = fetch_local_manifest()
params = [{name: data} for name, data in sites_info.items()]
ids = list(sites_info.keys())
metafunc.parametrize("chunked_sites", params, ids=ids)
+3 -4
View File
@@ -7,8 +7,8 @@ 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 {args}"
if platform.system() == "Windows":
command:str = f"py -m sherlock_project {args}"
else:
command:str = f"sherlock {args}"
@@ -20,8 +20,7 @@ class Interactives:
raise InteractivesSubprocessError(e.output.decode())
# -> list[str] is prefered, but will require deprecation of support for Python 3.8
def walk_sherlock_for_files_with(pattern: str) -> list:
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] = []
+1 -1
View File
@@ -7,7 +7,7 @@ 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)
+1 -1
View File
@@ -44,7 +44,7 @@ class TestLiveTargets:
# Known positives should only use sites trusted to be reliable and unchanging
@pytest.mark.parametrize('site,username',[
('BodyBuilding', 'blue'),
('Keybase', 'blue'),
('devRant', 'blue'),
])
def test_known_positives_via_response_url(self, sites_info, site, username):
+99
View File
@@ -0,0 +1,99 @@
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
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}"
+2 -4
View File
@@ -7,8 +7,6 @@ envlist =
py312
py311
py310
py39
py38
[testenv]
description = Attempt to build and install the package
@@ -16,6 +14,7 @@ deps =
coverage
jsonschema
pytest
rstr
allowlist_externals = coverage
commands =
coverage run --source=sherlock_project --module pytest -v
@@ -37,8 +36,7 @@ commands =
[gh-actions]
python =
3.13: py313
3.12: py312
3.11: py311
3.10: py310
3.9: py39
3.8: py38