cartography 0.94.0rc2__py3-none-any.whl → 0.95.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cartography might be problematic. Click here for more details.

Files changed (30) hide show
  1. cartography/cli.py +42 -24
  2. cartography/config.py +12 -8
  3. cartography/data/indexes.cypher +0 -2
  4. cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +13 -13
  5. cartography/driftdetect/cli.py +1 -1
  6. cartography/graph/job.py +8 -1
  7. cartography/intel/aws/permission_relationships.py +6 -2
  8. cartography/intel/gcp/__init__.py +110 -23
  9. cartography/intel/kandji/__init__.py +1 -1
  10. cartography/intel/semgrep/findings.py +106 -59
  11. cartography/intel/snipeit/__init__.py +30 -0
  12. cartography/intel/snipeit/asset.py +74 -0
  13. cartography/intel/snipeit/user.py +75 -0
  14. cartography/intel/snipeit/util.py +35 -0
  15. cartography/models/semgrep/findings.py +3 -1
  16. cartography/models/snipeit/__init__.py +0 -0
  17. cartography/models/snipeit/asset.py +81 -0
  18. cartography/models/snipeit/tenant.py +17 -0
  19. cartography/models/snipeit/user.py +49 -0
  20. cartography/sync.py +2 -2
  21. {cartography-0.94.0rc2.dist-info → cartography-0.95.0rc1.dist-info}/LICENSE +1 -1
  22. {cartography-0.94.0rc2.dist-info → cartography-0.95.0rc1.dist-info}/METADATA +3 -5
  23. {cartography-0.94.0rc2.dist-info → cartography-0.95.0rc1.dist-info}/RECORD +26 -22
  24. {cartography-0.94.0rc2.dist-info → cartography-0.95.0rc1.dist-info}/WHEEL +1 -1
  25. cartography/data/jobs/cleanup/crxcavator_import_cleanup.json +0 -18
  26. cartography/intel/crxcavator/__init__.py +0 -44
  27. cartography/intel/crxcavator/crxcavator.py +0 -329
  28. cartography-0.94.0rc2.dist-info/NOTICE +0 -4
  29. {cartography-0.94.0rc2.dist-info → cartography-0.95.0rc1.dist-info}/entry_points.txt +0 -0
  30. {cartography-0.94.0rc2.dist-info → cartography-0.95.0rc1.dist-info}/top_level.txt +0 -0
@@ -187,7 +187,7 @@
187
187
  same "printed page" as the copyright notice for easier
188
188
  identification within third-party archives.
189
189
 
190
- Copyright 2019 Lyft, Inc.
190
+ Copyright 2024 The Linux Foundation
191
191
 
192
192
  Licensed under the Apache License, Version 2.0 (the "License");
193
193
  you may not use this file except in compliance with the License.
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cartography
3
- Version: 0.94.0rc2
3
+ Version: 0.95.0rc1
4
4
  Summary: Explore assets and their relationships across your technical infrastructure.
5
- Home-page: https://www.github.com/lyft/cartography
6
- Maintainer: Lyft
7
- Maintainer-email: security@lyft.com
5
+ Home-page: https://www.github.com/cartography-cncf/cartography
6
+ Maintainer: Cartography Contributors
8
7
  License: apache2
9
8
  Classifier: Development Status :: 4 - Beta
10
9
  Classifier: Intended Audience :: Developers
@@ -18,7 +17,6 @@ Classifier: Topic :: Software Development :: Libraries
18
17
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
18
  Description-Content-Type: text/markdown
20
19
  License-File: LICENSE
21
- License-File: NOTICE
22
20
  Requires-Dist: backoff >=2.1.2
23
21
  Requires-Dist: boto3 >=1.15.1
24
22
  Requires-Dist: botocore >=1.18.1
@@ -1,10 +1,10 @@
1
1
  cartography/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  cartography/__main__.py,sha256=JftXT_nUPkqcEh8uxCCT4n-OyHYqbldEgrDS-4ygy0U,101
3
- cartography/cli.py,sha256=ot9_gMxw5_irVS7KYfWf5HIr2Xkb10RDEbOTY1nzUcw,31787
4
- cartography/config.py,sha256=rL1zgxZO47_R7S6E9e0CwxmhzRSN0X_q93NtcPR1G00,11368
3
+ cartography/cli.py,sha256=tfIPOMh3DtQG7Dgmg9rNNqoTcxgocBu45k88CAM09Nk,32368
4
+ cartography/config.py,sha256=QbFqwUb6P8-wdkf4ljE5HJhduXl_3Gt2xzBQRayq0sg,11566
5
5
  cartography/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  cartography/stats.py,sha256=dbybb9V2FuvSuHjjNwz6Vjwnd1hap2C7h960rLoKcl8,4406
7
- cartography/sync.py,sha256=a80r_IzrZcWGSmRDRrxkesNYPiOuLte5YHvDQT3L-Lw,9730
7
+ cartography/sync.py,sha256=ziD63T_774gXSuD5zdz6fLGvv1Kt2ntQySSVbmcCZb8,9708
8
8
  cartography/util.py,sha256=umfnjX8jVLu0rpYA75X-WvRpYzHQxns9qZiPwfyAlwQ,14478
9
9
  cartography/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  cartography/client/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -12,7 +12,7 @@ cartography/client/aws/iam.py,sha256=dYsGikc36DEsSeR2XVOVFFUDwuU9yWj_EVkpgVYCFgM
12
12
  cartography/client/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  cartography/client/core/tx.py,sha256=4_kTBxrtlwsOM-e8Xtjf7wmmzwZ-DGRJL0rPFp0Xj0Q,10805
14
14
  cartography/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- cartography/data/indexes.cypher,sha256=PTQEUbC_Kmjj_wM-j6NJqLvETRIORreeqF6WlKmnHKg,27395
15
+ cartography/data/indexes.cypher,sha256=Ha8VemktSz8ikIS4On-8FTiv2-WwRx5j3l02gQnSWXk,27262
16
16
  cartography/data/permission_relationships.yaml,sha256=RuKGGc_3ZUQ7ag0MssB8k_zaonCkVM5E8I_svBWTmGc,969
17
17
  cartography/data/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  cartography/data/jobs/analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -88,7 +88,6 @@ cartography/data/jobs/cleanup/azure_storage_account_cleanup.json,sha256=XZdjKDOj
88
88
  cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json,sha256=bowUBCjHYlC4Xd60lv33sxRi-bv1wiT5gAOStaHMX4k,430
89
89
  cartography/data/jobs/cleanup/azure_tenant_cleanup.json,sha256=jcjmZH6kfVGZ9q68rfvnroF0kNNHZ2uTZQ17Rmd4FH0,220
90
90
  cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json,sha256=bBPwftvz1iMUKrqKFCFZEH3LgVRzg-t5fRUh6Chx-vo,1426
91
- cartography/data/jobs/cleanup/crxcavator_import_cleanup.json,sha256=IvGVD_lRR-0nEPorq3vhVKmO2R1bKBpivujJIxVo3hE,607
92
91
  cartography/data/jobs/cleanup/digitalocean_droplet_cleanup.json,sha256=f26TdPUPYnIp45ipPys5M6VVfConUZySIbkgSr3iQno,703
93
92
  cartography/data/jobs/cleanup/digitalocean_project_cleanup.json,sha256=5mo9vPshCdUZfgTWd_22_TLSyfe6hd41u7z-B8H1qgY,702
94
93
  cartography/data/jobs/cleanup/gcp_compute_firewall_cleanup.json,sha256=FVNJ8EPaPhmQ_sh4vyTdMyEgs6Y-DIoFTdWJaELgz44,1904
@@ -118,11 +117,11 @@ cartography/data/jobs/cleanup/okta_groups_cleanup.json,sha256=cBI3f_okl4pnVH48L1
118
117
  cartography/data/jobs/cleanup/okta_import_cleanup.json,sha256=4XQwYpY9vITLhnLpijMVa5PxO0Tm38CcMydnbPdQPm0,3798
119
118
  cartography/data/jobs/cleanup/pagerduty_import_cleanup.json,sha256=RJqG_Uw_QEGTer_-s2IuZ3a2kykhUcCdDNZu0S7SEB4,4457
120
119
  cartography/data/jobs/scoped_analysis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
- cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json,sha256=Nlx4xRISmn_RQjVoRO1qAc2KtkiGy8i4mUB1NBPjCVc,6451
120
+ cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json,sha256=eIYxbl5TdgVzN8En2JozWoyKAiIh3Dp8wUMkTDPGZY0,6485
122
121
  cartography/driftdetect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
122
  cartography/driftdetect/__main__.py,sha256=Sz24Kxy5x6RC3GQEkuUDXzjOV3SvlHVkZdvPl1GLl5E,125
124
123
  cartography/driftdetect/add_shortcut.py,sha256=COtcCW9T0ss-bP1B2y9gEk3kN6HA01kkurSiDBNLzco,2377
125
- cartography/driftdetect/cli.py,sha256=0Du2lMSHs6TySrUfTk5TLc2lw1d85kyy93WCJIFqZ-8,9170
124
+ cartography/driftdetect/cli.py,sha256=SiNTsVtxCyMUoTzjCMkSUQ-TYPceGoZ67hp8eejp71k,9172
126
125
  cartography/driftdetect/config.py,sha256=wHx1RmKRU3fJ9xD8Nf62uIFGOoaohgyqrFIAy-Fc_xM,2974
127
126
  cartography/driftdetect/detect_deviations.py,sha256=pfNce5VWfs_oNNI2-PFgOAOzZ8YPprrE7LxdBo27kqU,4349
128
127
  cartography/driftdetect/get_states.py,sha256=iAAoIqItZx-dHV9OmWIhHy0YjhHA1AH8DGtUwp6YO1c,5965
@@ -135,7 +134,7 @@ cartography/driftdetect/util.py,sha256=Lqxv8QoFn3_3Fz18qCOjkjJ6yBwgrHjrxXmArBAEd
135
134
  cartography/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
135
  cartography/graph/cleanupbuilder.py,sha256=87vFrOJo66hOrrqeNwXp18WrNQEheHTlZko9KUkXWhY,8021
137
136
  cartography/graph/context.py,sha256=RGxGb8EnxowcqjR0nFF86baNhgRHeUF9wjIoFUoG8LU,1230
138
- cartography/graph/job.py,sha256=VBKc0VLbDz1zm5jslF49nbPbQS7DkdQwfPG7rdLSc1w,7288
137
+ cartography/graph/job.py,sha256=RZWsbNhHuJlcSpw4C73ZuovRTp7kGrcm3X9yUH8vT1Q,7488
139
138
  cartography/graph/querybuilder.py,sha256=MMXzUEg4td-YmHMNM97KAqDZ6-1wNClO2jmJoG47BTY,20108
140
139
  cartography/graph/statement.py,sha256=VsqG46ty_Mm87fr8YdIwfr6a82OUXU7yZe6S-Py9hZg,5345
141
140
  cartography/intel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -157,7 +156,7 @@ cartography/intel/aws/inspector.py,sha256=S22ZgRKEnmnBTJ-u0rodqRPB7_LkSIek47NeBx
157
156
  cartography/intel/aws/kms.py,sha256=bZUzMxAH_DsAcGTJBs08gg2tLKYu-QWjvMvV9C-6v50,11731
158
157
  cartography/intel/aws/lambda_function.py,sha256=KKTyn53xpaMI9WvIqxmsOASFwflHt-2_5ow-zUFc2wg,9890
159
158
  cartography/intel/aws/organizations.py,sha256=HaQZ3J5XF15BuykuDypqFORDYpnoHuRRr4DuceewH4s,4485
160
- cartography/intel/aws/permission_relationships.py,sha256=PhOnag0a1gZHtUg82546MKhj-8IcGJ7wLbvPASUBXlg,14792
159
+ cartography/intel/aws/permission_relationships.py,sha256=IarV9gt5BaplZ5TPo_mfypt9bTKfT9qDtqC3Ob89qGI,14904
161
160
  cartography/intel/aws/rds.py,sha256=vnlNYmrO2Cc0PNn31CeG2QwYhwjVosbQFE9Ol1vQyLE,25252
162
161
  cartography/intel/aws/redshift.py,sha256=KOqiXIllHmtPTeaNGl-cX4srY5pFE6o12j8MQ5-zWpc,6694
163
162
  cartography/intel/aws/resourcegroupstaggingapi.py,sha256=aq4kPF6t8QZZoTxdkQVLXH65Di41CDJVM9llJNe6iaY,10278
@@ -206,8 +205,6 @@ cartography/intel/crowdstrike/__init__.py,sha256=dAtgI-0vZAQZ3cTFQhMEzzt7aqiNSNu
206
205
  cartography/intel/crowdstrike/endpoints.py,sha256=tdqokMDW3p4fK3dHKKb2T1DTogvOJBCpwyrxdQlbUhw,3815
207
206
  cartography/intel/crowdstrike/spotlight.py,sha256=yNhj44-RYF6ubck-hHMKhKiNU0fCfhQf4Oagopc31EM,4754
208
207
  cartography/intel/crowdstrike/util.py,sha256=gfJ6Ptr6YdbBS9Qj9a_-Jc-IJroADDRcXqjh5TW0qXE,277
209
- cartography/intel/crxcavator/__init__.py,sha256=VM6N_7dMagzuQQjUeFgqrt2_d2Is9ugDMTrgKke2c0g,1606
210
- cartography/intel/crxcavator/crxcavator.py,sha256=tnx6bq8Oz020mhMDmx8gKZ_ro_0UvUGeWrshmFr7bBw,13797
211
208
  cartography/intel/cve/__init__.py,sha256=A7XjKQSanmwMSIXSum1qJSegtYcQCuz_713RU-bFQz8,2504
212
209
  cartography/intel/cve/feed.py,sha256=JkfRV18JoydOuncKR1y3s8esuN2Xk4gIB6viKNXU_X0,10020
213
210
  cartography/intel/digitalocean/__init__.py,sha256=SMYB7LGIQOj_EgGSGVjWZk7SJNbP43hQuOfgOu6xYm4,1526
@@ -222,7 +219,7 @@ cartography/intel/duo/phones.py,sha256=ueJheqSLD2xYcMus5eOiixPYS3_xVjgQzeomjV2a6
222
219
  cartography/intel/duo/tokens.py,sha256=bEEnjfc4waQnkRHVSnZLAeGE8wHOOZL7FA9m80GGQdQ,2396
223
220
  cartography/intel/duo/users.py,sha256=lc7ly_XKeUjJ50szw31WT_GiCrZfGKJv1zVUpmTchh4,4097
224
221
  cartography/intel/duo/web_authn_credentials.py,sha256=IbDf3CWqfEyI7f9zJugUvoDd6vZOECfb_7ANZaRYzuk,2636
225
- cartography/intel/gcp/__init__.py,sha256=kxRvAc1DPNkE2JCy3_QjbwLebZ4irKOlSol3TxnN37E,12158
222
+ cartography/intel/gcp/__init__.py,sha256=jJOT6Ys97qm1W0jGXFwtSOOSGPa7q-Xxr1YIR8fKejo,15849
226
223
  cartography/intel/gcp/compute.py,sha256=CH2cBdOwbLZCAbkfRJkkI-sFybXVKRWEUGDJANQmvyA,48333
227
224
  cartography/intel/gcp/crm.py,sha256=Uw5PILhVFhpM8gq7uu2v7F_YikDW3gsTZ3d7-e8Z1_k,12324
228
225
  cartography/intel/gcp/dns.py,sha256=y2pvbmV04cnrMyuu_nbW3oc7uwHX6yEzn1n7veCsjmk,7748
@@ -238,7 +235,7 @@ cartography/intel/gsuite/api.py,sha256=J0dkNdfBVMrEv8vvStQu7YKVxXSyV45WueFhUS4aO
238
235
  cartography/intel/jamf/__init__.py,sha256=Nof-LrUeevoieo6oP2GyfTwx8k5TUIgreW6hSj53YjQ,419
239
236
  cartography/intel/jamf/computers.py,sha256=EfjlupQ-9HYTjOrmuwrGuJDy9ApAnJvk8WrYcp6_Jkk,1673
240
237
  cartography/intel/jamf/util.py,sha256=EAyP8VpOY2uAvW3HtX6r7qORNjGa1Tr3fuqezuLQ0j4,1017
241
- cartography/intel/kandji/__init__.py,sha256=OHZJNzuNibIfJ51OkL3XL2EdA_ZmvPHPeWCQUld4J64,1079
238
+ cartography/intel/kandji/__init__.py,sha256=Y38bVRmrGVJRy0mSof8xU-cuEyJ7N_oI7KekYjYyuiQ,1076
242
239
  cartography/intel/kandji/devices.py,sha256=j_rP6rQ5VPT_XEcGXx7Yt6eCOm1Oe3I2qWIxXODXEcA,2224
243
240
  cartography/intel/kubernetes/__init__.py,sha256=jaOTEanWnTrYvcBN1XUC5oqBhz1AJbFmzoT9uu_VBSg,1481
244
241
  cartography/intel/kubernetes/namespaces.py,sha256=6o-FgAX_Ai5NCj2xOWM-RNWEvn0gZjVQnZSGCJlcIhw,2710
@@ -271,7 +268,11 @@ cartography/intel/pagerduty/teams.py,sha256=aRubUXgEVVReyLrXAX_be1E_QBJv3Qlr4n77
271
268
  cartography/intel/pagerduty/users.py,sha256=oltGssxrnzYsV6QTGP1SsPoA1rCUDStj6vGlGWY695g,1623
272
269
  cartography/intel/pagerduty/vendors.py,sha256=WlDHExrWRBegDQKtxBV5nJiYgwoTLxNee4HrQDJ-Pdg,1559
273
270
  cartography/intel/semgrep/__init__.py,sha256=94vjdszGEosvXiKtYWKD34BRKwRbJxlBO1PZcKdxnFA,619
274
- cartography/intel/semgrep/findings.py,sha256=hbH_wL1XJDZDDrbIV_FjPv4A7oS2xM_hhMAbZlRm9po,9025
271
+ cartography/intel/semgrep/findings.py,sha256=9MSbDFrRUqb5nkEWN0R9Fx57RJMt27-9obpIHXNd45Y,10836
272
+ cartography/intel/snipeit/__init__.py,sha256=0uIh8NbuI7IbfgaOrPHg4Nfm1yO6mTRC_qaFiIjR2FA,992
273
+ cartography/intel/snipeit/asset.py,sha256=KkGRUgIydvf_6SHtgpVLT-TjtEGz029SrOaoh0qDW6E,1997
274
+ cartography/intel/snipeit/user.py,sha256=hm9v_p29bphHtGe9LKVo1FD_rQcbCigrCRf8YsmteXA,1971
275
+ cartography/intel/snipeit/util.py,sha256=fXlzdFQXm01Oaa2REYNN7x3y3k2l3zCVhf_BxcRUELY,1040
275
276
  cartography/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
276
277
  cartography/models/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
277
278
  cartography/models/aws/emr.py,sha256=TkuwoZnw_VHbJ5bwkac7-ZfwSLe_TeK3gxkuwGQOUk4,3037
@@ -330,12 +331,15 @@ cartography/models/lastpass/tenant.py,sha256=TG-9LFo9Sfzb9UgcTt_gFVTKocLItbgQMMP
330
331
  cartography/models/lastpass/user.py,sha256=SMTTYN6jgccc9k76hY3rVImElJOhHhZ9f1aZ6JzcrHw,3487
331
332
  cartography/models/semgrep/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
332
333
  cartography/models/semgrep/deployment.py,sha256=or5qZDuR51MXzINpH15jZrqmSUvXQevCNYWJ7D6v-JI,745
333
- cartography/models/semgrep/findings.py,sha256=xrn8sgXpNMrNJbKQagaAVxaCG9bVjTATSRR2XRBR4rg,5386
334
+ cartography/models/semgrep/findings.py,sha256=RPd-QzvP38fbTIqFARx6XpcZSsd5JM3KIg-ZlJA7NlE,5490
334
335
  cartography/models/semgrep/locations.py,sha256=kSk7Nn5Mn4Ob84MVZOo2GR0YFi-9Okq9pgA3FfC6_bk,3061
335
- cartography-0.94.0rc2.dist-info/LICENSE,sha256=489ZXeW9G90up6ep-D1n-lJgk9ciNT2yxXpFgRSidtk,11341
336
- cartography-0.94.0rc2.dist-info/METADATA,sha256=UEwu0NxrNz1H3YQWCQT4grTn4p_yvqC1nFoou0HCvig,1991
337
- cartography-0.94.0rc2.dist-info/NOTICE,sha256=YOGAsjFtbyKj5tslYIg6V5jEYRuEvnSsIuDOUKj0Qj4,97
338
- cartography-0.94.0rc2.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
339
- cartography-0.94.0rc2.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
340
- cartography-0.94.0rc2.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
341
- cartography-0.94.0rc2.dist-info/RECORD,,
336
+ cartography/models/snipeit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
337
+ cartography/models/snipeit/asset.py,sha256=FyRAaeXuZjMy0eUQcSDFcgEAF5lbLMlvqp1Tv9d3Lv4,3238
338
+ cartography/models/snipeit/tenant.py,sha256=p4rFnpNNuF1W5ilGBbexDaETWTwavfb38RcQGoImkQI,679
339
+ cartography/models/snipeit/user.py,sha256=MsB4MiCVNTH6JpESime7cOkB89autZOXQpL6Z0l7L6o,2113
340
+ cartography-0.95.0rc1.dist-info/LICENSE,sha256=kvLEBRYaQ1RvUni6y7Ti9uHeooqnjPoo6n_-0JO1ETc,11351
341
+ cartography-0.95.0rc1.dist-info/METADATA,sha256=t7FVdB2ipkDkwlWl-x_N60Oaa_1VBd30eU0virQyKOE,1966
342
+ cartography-0.95.0rc1.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
343
+ cartography-0.95.0rc1.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
344
+ cartography-0.95.0rc1.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
345
+ cartography-0.95.0rc1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (71.1.0)
2
+ Generator: setuptools (75.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,18 +0,0 @@
1
- {
2
- "statements": [{
3
- "query": "MATCH (n:ChromeExtension) WHERE n.lastupdated <> $UPDATE_TAG WITH n LIMIT $LIMIT_SIZE DETACH DELETE (n)",
4
- "iterative": true,
5
- "iterationsize": 100
6
- },
7
- {
8
- "query": "MATCH (n:GSuiteUser) WHERE n.lastupdated <> $UPDATE_TAG WITH n LIMIT $LIMIT_SIZE DETACH DELETE (n)",
9
- "iterative": true,
10
- "iterationsize": 100
11
- },
12
- {
13
- "query": "MATCH (GSuiteUser)-[r:INSTALLS]->(:ChromeExtension) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r)",
14
- "iterative": true,
15
- "iterationsize": 100
16
- }],
17
- "name": "cleanup CRXcavator extensions"
18
- }
@@ -1,44 +0,0 @@
1
- import logging
2
-
3
- import neo4j
4
- from requests import exceptions
5
-
6
- from cartography.config import Config
7
- from cartography.intel.crxcavator.crxcavator import sync_extensions
8
- from cartography.util import run_cleanup_job
9
- from cartography.util import timeit
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
-
14
- @timeit
15
- def start_extension_ingestion(neo4j_session: neo4j.Session, config: Config) -> None:
16
- """
17
- If this module is configured, perform ingestion of CRXcavator data. Otherwise warn and exit
18
- :param neo4j_session: Neo4J session for database interface
19
- :param config: A cartography.config object
20
- :return: None
21
- """
22
- if not config.crxcavator_api_base_uri or not config.crxcavator_api_key:
23
- logger.warning('CRXcavator import is not configured - skipping this module. See docs to configure.')
24
- return
25
-
26
- common_job_parameters = {
27
- "UPDATE_TAG": config.update_tag,
28
- }
29
- # while we typically want to crash sync on failure of module,
30
- # the crxcavator API is still in beta and is not always available.
31
- # if we receive a requests exception from raise_for_status
32
- # we'll handle and continue with other modules, otherwise crash sync
33
- try:
34
- sync_extensions(
35
- neo4j_session, common_job_parameters, config.crxcavator_api_key,
36
- config.crxcavator_api_base_uri,
37
- )
38
- run_cleanup_job(
39
- 'crxcavator_import_cleanup.json',
40
- neo4j_session,
41
- common_job_parameters,
42
- )
43
- except exceptions.RequestException as e:
44
- logger.error("Could not complete request to the CRXcavator API: {}", e)
@@ -1,329 +0,0 @@
1
- import json
2
- import logging
3
- from typing import Any
4
- from typing import Dict
5
- from typing import List
6
- from typing import Tuple
7
-
8
- import neo4j
9
- import requests.auth
10
- from requests import exceptions
11
-
12
- from cartography.util import timeit
13
-
14
- logger = logging.getLogger(__name__)
15
- # Connect and read timeouts of 60 seconds each; see https://requests.readthedocs.io/en/master/user/advanced/#timeouts
16
- _TIMEOUT = (60, 60)
17
-
18
-
19
- @timeit
20
- def get_extension_details(
21
- crxcavator_api_key: str, crxcavator_base_url: str, extension_id: str,
22
- version: str,
23
- ) -> List[Dict]:
24
- """
25
- Get metadata for the specific extension_id and version number provided
26
- :param crxcavator_api_key: The API key to access the CRXcavator service
27
- :param crxcavator_base_url: The URL for the CRXcavator API
28
- :param extension_id: The extension id to request metadata for
29
- :param version: The version number of the extension to request metadata for
30
- :return: JSON text blob containing all extension metadata defined at
31
- https://crxcavator.io/apidocs#tag/group/paths/~1group~1extensions~1combined/get
32
- """
33
- return call_crxcavator_api(f"/report/{extension_id}/{version}", crxcavator_api_key, crxcavator_base_url)
34
-
35
-
36
- @timeit
37
- def get_users_extensions(crxcavator_api_key: str, crxcavator_base_url: str) -> List[Dict]:
38
- """
39
- Gets listing of all users who have installed each extension
40
- :param crxcavator_api_key: The API key to access the CRXcavator service
41
- :param crxcavator_base_url: The URL for the CRXcavator API
42
- :return: JSON text blob containing user email to extension id mapping defined at
43
- https://crxcavator.io/apidocs#tag/group/paths/~1group~1users~1extensions/get
44
- """
45
- return call_crxcavator_api("/group/users/extensions", crxcavator_api_key, crxcavator_base_url)
46
-
47
-
48
- @timeit
49
- def call_crxcavator_api(api_and_parameters: str, crxcavator_api_key: str, crxcavator_base_url: str) -> List[Dict]:
50
- """
51
- Perform the call requested to the CRXcavator API
52
- :param crxcavator_api_key: The API key to access the CRXcavator service
53
- :param crxcavator_base_url: The URL for the CRXcavator API
54
- :param api_and_parameters: Query string for the API including the required parameters
55
- :return: Returns JSON text blob for the API called. API spec is at https://crxcavator.io/apidocs
56
- """
57
- uri = crxcavator_base_url + api_and_parameters
58
- try:
59
- data = requests.get(
60
- uri,
61
- headers={
62
- 'Accept': 'application/json',
63
- 'API-Key': crxcavator_api_key,
64
- },
65
- timeout=_TIMEOUT,
66
- )
67
- except requests.exceptions.Timeout as e:
68
- # Add context and re-raise for callers to handle
69
- logger.warning(f"requests.get('{uri}') timed out", e)
70
- raise
71
- # if call failed, use requests library to raise an exception
72
- data.raise_for_status()
73
- return data.json()
74
-
75
-
76
- @timeit
77
- def get_extensions(crxcavator_api_key: str, crxcavator_base_url: str, extensions_list: List[Dict]) -> List[Dict]:
78
- """
79
- Retrieves the detailed information for all the extension_id and version pairs
80
- :param crxcavator_api_key: The API key to access the CRXcavator service
81
- :param crxcavator_base_url: The URL for the CRXcavator API
82
- :param extensions_list: list of dictonary items containing the extension_id and version pairs
83
- :return: list containing all metadata for extensions
84
- """
85
- extensions_details: List[Dict] = []
86
- for extension in extensions_list:
87
- extension_id = extension['extension_id']
88
- version = extension['version']
89
- name = extension['name']
90
- try:
91
- details = get_extension_details(crxcavator_api_key, crxcavator_base_url, extension_id, version)
92
- if not details:
93
- # we only have the name and version from group API, create minimal version
94
- logger.debug(f"No results returned from report API for extension {extension_id} {version}")
95
- details = {
96
- 'data': dict(
97
- webstore={
98
- 'name': name,
99
- },
100
- ), 'extension_id': extension_id, 'version': version,
101
- }
102
- extensions_details.append(details)
103
- except exceptions.RequestException as e:
104
- logger.info(f"API error retrieving details for extension {extension_id}", e)
105
- except requests.exceptions.Timeout:
106
- logger.info(f"Skipping {extension_id} due to timeout; continuing")
107
- continue
108
- return extensions_details
109
-
110
-
111
- @timeit
112
- def transform_extensions(extension_details: List[Dict]) -> List[Dict]:
113
- """
114
- Transforms the raw extensions JSON from the API into a list of extensions data
115
- :param extension_details: List containing the extension details
116
- :return: List containing extension info for ingestion
117
- """
118
- # the JSON returned from the CRXcavator API does not return well formatted objects
119
- # instead, each object is named after it's key, making enumeration more difficult
120
- # will build a cleaner object for import into graph
121
-
122
- extensions: List[Dict] = []
123
- for extension in extension_details:
124
- extension_id = extension['extension_id']
125
- version = extension['version']
126
- data = extension.get('data')
127
- if not data:
128
- logger.warning(f'Could not retrieve details for extension {extension}')
129
- continue
130
- risk = data.get('risk', {})
131
- webstore = data.get('webstore', {})
132
- extensions.append({
133
- 'id': f"{extension_id}|{version}",
134
- 'extension_id': extension_id,
135
- 'version': version,
136
- 'risk_total': risk.get('total', 0),
137
- 'risk_permissions_score': get_risk_data(risk, 'permissions'),
138
- 'risk_webstore_score': get_risk_data(risk, 'webstore'),
139
- 'risk_metadata': json.dumps(risk.get('metadata')),
140
- 'risk_optional_permissions_score': get_risk_data(risk, 'optional_permissions'),
141
- 'risk_csp_score': get_risk_data(risk, 'csp'),
142
- 'risk_extcalls_score': get_risk_data(risk, 'extcalls'),
143
- 'risk_vuln_score': get_risk_data(risk, 'retire'),
144
- 'address': webstore.get('address'),
145
- 'email': webstore.get('email'),
146
- 'icon': webstore.get('icon'),
147
- 'crxcavator_last_updated': webstore.get('last_updated'),
148
- 'name': webstore.get('name'),
149
- 'offered_by': webstore.get('offered_by'),
150
- 'permissions_warnings': webstore.get('permission_warnings'),
151
- 'privacy_policy': webstore.get('privacy_policy'),
152
- 'rating': webstore.get('rating'),
153
- 'rating_users': webstore.get('rating_users'),
154
- 'short_description': webstore.get('short_description'),
155
- 'size': webstore.get('size'),
156
- 'support_site': webstore.get('support_site'),
157
- 'users': webstore.get('users'),
158
- 'website': webstore.get('website'),
159
- 'type': webstore.get('type'),
160
- 'price': webstore.get('price'),
161
- 'report_link': f"https://crxcavator.io/report/{extension_id}/{version}",
162
- })
163
- return extensions
164
-
165
-
166
- @timeit
167
- def get_risk_data(data_dict: Dict, key: str) -> int:
168
- """
169
- Gets the total risk value from the provided key and returns the value else 0
170
- :param data_dict: input data dictionary to parse
171
- :param key: key name to retrieve
172
- :return:
173
- """
174
- data = data_dict.get(key)
175
- data_score = data.get('total', 0) if data else 0
176
- return data_score
177
-
178
-
179
- @timeit
180
- def load_extensions(extensions: List[Dict], neo4j_session: neo4j.Session, update_tag: int) -> None:
181
- """
182
- Ingests the extension details into Neo4J
183
- :param extensions: List of extension data to load to Neo4J
184
- :param session: Neo4J session object for server communication
185
- :param update_tag: Timestamp used to determine data freshness
186
- :return: None
187
- """
188
- ingestion_cypher = """
189
- UNWIND $ExtensionsData as extension
190
- MERGE (e:ChromeExtension{id: extension.id})
191
- ON CREATE SET
192
- e.extension_id = extension.extension_id,
193
- e.version = extension.version,
194
- e.firstseen = timestamp()
195
- SET
196
- e.extcalls = extension.extcalls,
197
- e.risk_total = extension.risk_total,
198
- e.risk_permissions_score = extension.risk_permissions_score,
199
- e.risk_metadata = extension.risk_metadata,
200
- e.risk_webstore_score = extension.risk_webstore_score,
201
- e.risk_optional_permissions_score = extension.risk_optional_permissions_score,
202
- e.risk_csp_score = extension.risk_csp_score,
203
- e.risk_extcalls_score = extension.risk_extcalls_score,
204
- e.risk_vuln_score = extension.risk_vuln_score,
205
- e.address = extension.address,
206
- e.email = extension.email,
207
- e.icon = extension.icon,
208
- e.crxcavator_last_updated = extension.crxcavator_last_updated,
209
- e.name = extension.name,
210
- e.offered_by = extension.offered_by,
211
- e.permissions_warnings = extension.permissions_warnings,
212
- e.privacy_policy = extension.privacy_policy,
213
- e.rating = extension.rating,
214
- e.rating_users = extension.rating_users,
215
- e.short_description = extension.short_description,
216
- e.size = extension.size,
217
- e.support_site = extension.support_site,
218
- e.users = extension.users,
219
- e.website = extension.website,
220
- e.type = extension.type,
221
- e.price = extension.price,
222
- e.report_link = extension.report_link,
223
- e.lastupdated = $UpdateTag
224
- """
225
-
226
- logger.info(f'Ingesting {len(extensions)} extensions')
227
- neo4j_session.run(ingestion_cypher, ExtensionsData=extensions, UpdateTag=update_tag)
228
-
229
-
230
- @timeit
231
- def transform_user_extensions(user_extension_json: Dict) -> Tuple[List[Any], List[Dict], List[Dict]]:
232
- """
233
- Transforms the raw extensions JSON from the API into a list of extensions mapped to users
234
- :param user_extension_json: The JSON text blob returned from the CRXcavator API
235
- :return: Tuple containing unique users list, unique extension list, and extension mapping for ingestion
236
- """
237
- user_extensions = user_extension_json.items()
238
- users_set = set()
239
- extensions: List[Dict] = []
240
- extensions_by_user: List[Dict] = []
241
- for extension in user_extensions:
242
- for details in extension[1].items():
243
- extension_id = extension[0]
244
- version = details[0]
245
- extensions.append({
246
- 'extension_id': extension_id,
247
- 'version': version,
248
- 'name': details[1]['name'],
249
- })
250
- for user in details[1]['users']:
251
- if user is None:
252
- logger.info(f'bad user for {extension_id}{version}')
253
- continue
254
- users_set.add(user)
255
- extensions_by_user.append({
256
- 'id': f"{extension_id}|{version}",
257
- 'user': user,
258
- })
259
- if len(users_set) == 0:
260
- raise ValueError('No users returned from CRXcavator')
261
- if len(extensions) == 0:
262
- raise ValueError('No extensions information returned from CRXcavator')
263
- if len(extensions_by_user) == 0:
264
- raise ValueError('No user->extension mapping returned from CRXcavator')
265
-
266
- return list(users_set), extensions, extensions_by_user
267
-
268
-
269
- @timeit
270
- def load_user_extensions(
271
- users: List[Dict], extensions_by_user: Dict, neo4j_session: neo4j.Session,
272
- update_tag: int,
273
- ) -> None:
274
- """
275
- Ingests the extension to user mapping details into Neo4J
276
- :param users: List of user objects to create for mapping
277
- :param extensions_by_user: List of user to extension id mappings
278
- :param session: Neo4J session object for server communication
279
- :param update_tag: Timestamp used to determine data freshness
280
- :return: None
281
- """
282
-
283
- user_ingestion_cypher = """
284
- UNWIND $Users as user_email
285
- MERGE (user:GSuiteUser{email: user_email})
286
- ON CREATE SET
287
- user.firstseen = timestamp()
288
- SET user.lastupdated = $UpdateTag
289
- """
290
-
291
- extension_ingestion_cypher = """
292
- UNWIND $ExtensionsUsers as extension_user
293
- MATCH (user:GSuiteUser{email: extension_user.user}),(ext:ChromeExtension{id:extension_user.id})
294
- MERGE (user)-[r:INSTALLS]->(ext)
295
- ON CREATE SET
296
- r.firstseen = timestamp()
297
- SET r.lastupdated = $UpdateTag
298
- """
299
-
300
- logger.info(f'Ingesting {len(users)} users')
301
- neo4j_session.run(user_ingestion_cypher, Users=users, UpdateTag=update_tag)
302
- logger.info(f'Ingesting {len(extensions_by_user)} user->extension relationships')
303
- neo4j_session.run(extension_ingestion_cypher, ExtensionsUsers=extensions_by_user, UpdateTag=update_tag)
304
-
305
-
306
- @timeit
307
- def sync_extensions(
308
- neo4j_session: neo4j.Session, common_job_parameters: Dict, crxcavator_api_key: str,
309
- crxcavator_base_url: str,
310
- ) -> None:
311
- """
312
- Performs the sequential tasks to collect, transform, and sync extension data
313
- :param neo4j_session: Neo4J session for database interface
314
- :param common_job_parameters: Common job parameters containing UPDATE_TAG
315
- :param crxcavator_api_key: The API key to access the CRXcavator service
316
- :param crxcavator_base_url: The URL for the CRXcavator API
317
- :return: None
318
- """
319
-
320
- try:
321
- user_extensions_json = get_users_extensions(crxcavator_api_key, crxcavator_base_url)
322
- except requests.exceptions.Timeout:
323
- logger.warning("get_users_extensions() failed due to timeout. Skipping CRXcavator sync.")
324
- return
325
- users, extensions_list, user_extensions = transform_user_extensions(user_extensions_json)
326
- extension_details = get_extensions(crxcavator_api_key, crxcavator_base_url, extensions_list)
327
- extensions = transform_extensions(extension_details)
328
- load_extensions(extensions, neo4j_session, common_job_parameters['UPDATE_TAG'])
329
- load_user_extensions(users, user_extensions, neo4j_session, common_job_parameters['UPDATE_TAG'])
@@ -1,4 +0,0 @@
1
- cartography
2
- Copyright 2019-2020 Lyft Inc.
3
-
4
- This product includes software developed at Lyft Inc.