mirror of
https://github.com/trufflesecurity/trufflehog.git
synced 2024-11-10 07:04:24 +00:00
[analyze] Add Analyzer for Slack (#3207)
* implement analyzer interface for slack * slack analyzer adjusted for new changes in main, unit test added * link detector with analyzer for slack * added generated permissions for slack analyzer * generate permission fix, keep dot in permissions intact * removed scope from permission and put it metadata. * [chore] moved expected output of test in json file to neat the code. added team id in fully qualified name of user resource. check permissions before adding it in bindings. --------- Co-authored-by: Abdul Basit <abasit@folio3.com>
This commit is contained in:
parent
c449129d75
commit
f235b8a442
7 changed files with 2814 additions and 0 deletions
667
pkg/analyzer/analyzers/slack/expected_output.json
Normal file
667
pkg/analyzer/analyzers/slack/expected_output.json
Normal file
|
@ -0,0 +1,667 @@
|
|||
{
|
||||
"AnalyzerType": 16,
|
||||
"Bindings": [
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "conversations.history",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "conversations.replies",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "channels.info",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "conversations.info",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "conversations.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "conversations.members",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "groups.info",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "im.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "mpim.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "users.conversations",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "emoji.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "files.info",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "files.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "stars.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "pins.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "usergroups.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "usergroups.users.list",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "dnd.info",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "dnd.teamInfo",
|
||||
"Parent": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"Resource": {
|
||||
"Name": "marge.haskell.bridge",
|
||||
"FullyQualifiedName": "TSMCXP5FH/USMD5JM0F",
|
||||
"Type": "user",
|
||||
"Metadata": {
|
||||
"scopes": [
|
||||
"identify",
|
||||
"channels:history",
|
||||
"groups:history",
|
||||
"im:history",
|
||||
"channels:read",
|
||||
"emoji:read",
|
||||
"files:read",
|
||||
"groups:read",
|
||||
"im:read",
|
||||
"stars:read",
|
||||
"pins:read",
|
||||
"usergroups:read",
|
||||
"dnd:read",
|
||||
"calls:read"
|
||||
],
|
||||
"team": "ct.org",
|
||||
"team_id": "TSMCXP5FH",
|
||||
"url": "https://ctorgworkspace.slack.com/"
|
||||
},
|
||||
"Parent": null
|
||||
},
|
||||
"Permission": {
|
||||
"Value": "calls.info",
|
||||
"Parent": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"UnboundedResources": null,
|
||||
"Metadata": null
|
||||
}
|
1711
pkg/analyzer/analyzers/slack/permissions.go
Normal file
1711
pkg/analyzer/analyzers/slack/permissions.go
Normal file
File diff suppressed because it is too large
Load diff
263
pkg/analyzer/analyzers/slack/permissions.yaml
Normal file
263
pkg/analyzer/analyzers/slack/permissions.yaml
Normal file
|
@ -0,0 +1,263 @@
|
|||
permissions:
|
||||
- admin.analytics.getFile
|
||||
- admin.apps.activities.list
|
||||
- admin.apps.approve
|
||||
- admin.apps.clearResolution
|
||||
- admin.apps.config.set
|
||||
- admin.apps.requests.cancel
|
||||
- admin.apps.restrict
|
||||
- admin.apps.uninstall
|
||||
- admin.apps.approved.list
|
||||
- admin.apps.config.lookup
|
||||
- admin.apps.requests.list
|
||||
- admin.apps.restricted.list
|
||||
- admin.auth.policy.assignEntities
|
||||
- admin.auth.policy.removeEntities
|
||||
- admin.users.assign
|
||||
- admin.users.invite
|
||||
- admin.users.remove
|
||||
- admin.users.session.clearSettings
|
||||
- admin.users.session.invalidate
|
||||
- admin.users.session.reset
|
||||
- admin.users.session.resetBulk
|
||||
- admin.users.session.setSettings
|
||||
- admin.users.setAdmin
|
||||
- admin.users.setExpiration
|
||||
- admin.users.setOwner
|
||||
- admin.users.setRegular
|
||||
- admin.auth.policy.getEntities
|
||||
- admin.users.list
|
||||
- admin.users.session.getSettings
|
||||
- admin.users.session.list
|
||||
- admin.users.unsupportedVersions.export
|
||||
- admin.barriers.create
|
||||
- admin.barriers.delete
|
||||
- admin.barriers.update
|
||||
- admin.barriers.list
|
||||
- admin.conversations.archive
|
||||
- admin.conversations.bulkArchive
|
||||
- admin.conversations.bulkDelete
|
||||
- admin.conversations.bulkMove
|
||||
- admin.conversations.convertToPrivate
|
||||
- admin.conversations.convertToPublic
|
||||
- admin.conversations.create
|
||||
- admin.conversations.delete
|
||||
- admin.conversations.disconnectShared
|
||||
- admin.conversations.invite
|
||||
- admin.conversations.removeCustomRetention
|
||||
- admin.conversations.rename
|
||||
- admin.conversations.restrictAccess.addGroup
|
||||
- admin.conversations.restrictAccess.removeGroup
|
||||
- admin.conversations.setConversationPrefs
|
||||
- admin.conversations.setCustomRetention
|
||||
- admin.conversations.setTeams
|
||||
- admin.conversations.unarchive
|
||||
- admin.conversations.ekm.listOriginalConnectedChannelInfo
|
||||
- admin.conversations.getConversationPrefs
|
||||
- admin.conversations.getCustomRetention
|
||||
- admin.conversations.getTeams
|
||||
- admin.conversations.lookup
|
||||
- admin.conversations.restrictAccess.listGroups
|
||||
- admin.conversations.search
|
||||
- admin.emoji.add
|
||||
- admin.emoji.addAlias
|
||||
- admin.emoji.remove
|
||||
- admin.teams.create
|
||||
- admin.teams.settings.setDefaultChannels
|
||||
- admin.teams.settings.setDescription
|
||||
- admin.teams.settings.setDiscoverability
|
||||
- admin.teams.settings.setIcon
|
||||
- admin.teams.settings.setName
|
||||
- admin.usergroups.addTeams
|
||||
- admin.emoji.list
|
||||
- admin.teams.admins.list
|
||||
- admin.teams.list
|
||||
- admin.teams.owners.list
|
||||
- admin.teams.settings.info
|
||||
- admin.functions.list
|
||||
- admin.functions.permissions.lookup
|
||||
- admin.workflows.permissions.lookup
|
||||
- admin.workflows.search
|
||||
- admin.functions.permissions.set
|
||||
- admin.workflows.collaborators.add
|
||||
- admin.workflows.collaborators.remove
|
||||
- admin.workflows.unpublish
|
||||
- admin.inviteRequests.approve
|
||||
- admin.inviteRequests.deny
|
||||
- admin.inviteRequests.approved.list
|
||||
- admin.inviteRequests.denied.list
|
||||
- admin.inviteRequests.list
|
||||
- admin.roles.addAssignments
|
||||
- admin.roles.removeAssignments
|
||||
- admin.roles.listAssignments
|
||||
- admin.usergroups.addChannels
|
||||
- admin.usergroups.removeChannels
|
||||
- admin.usergroups.listChannels
|
||||
- apps.activities.list
|
||||
- apps.connections.open
|
||||
- token
|
||||
- apps.datastore.bulkDelete
|
||||
- apps.datastore.bulkGet
|
||||
- apps.datastore.bulkPut
|
||||
- apps.datastore.delete
|
||||
- apps.datastore.get
|
||||
- apps.datastore.put
|
||||
- apps.datastore.query
|
||||
- apps.datastore.update
|
||||
- apps.datastore.count
|
||||
- apps.event.authorizations.list
|
||||
- bot
|
||||
- auth.revoke
|
||||
- auth.test
|
||||
- chat.getPermalink
|
||||
- chat.scheduledMessages.list
|
||||
- dialog.open
|
||||
- functions.completeError
|
||||
- functions.completeSuccess
|
||||
- rtm.connect
|
||||
- rtm.start
|
||||
- views.open
|
||||
- views.publish
|
||||
- views.push
|
||||
- views.update
|
||||
- bookmarks.add
|
||||
- bookmarks.edit
|
||||
- bookmarks.remove
|
||||
- bookmarks.list
|
||||
- bots.info
|
||||
- users.getPresence
|
||||
- users.info
|
||||
- users.list
|
||||
- calls.add
|
||||
- calls.end
|
||||
- calls.participants.add
|
||||
- calls.participants.remove
|
||||
- calls.update
|
||||
- calls.info
|
||||
- channels.create
|
||||
- channels.mark
|
||||
- conversations.archive
|
||||
- conversations.close
|
||||
- conversations.create
|
||||
- conversations.kick
|
||||
- conversations.leave
|
||||
- conversations.mark
|
||||
- conversations.open
|
||||
- conversations.rename
|
||||
- conversations.unarchive
|
||||
- groups.create
|
||||
- groups.mark
|
||||
- im.mark
|
||||
- im.open
|
||||
- mpim.mark
|
||||
- mpim.open
|
||||
- channels.info
|
||||
- conversations.info
|
||||
- conversations.list
|
||||
- conversations.members
|
||||
- groups.info
|
||||
- im.list
|
||||
- mpim.list
|
||||
- users.conversations
|
||||
- channels.invite
|
||||
- conversations.invite
|
||||
- groups.invite
|
||||
- chat.delete
|
||||
- chat.deleteScheduledMessage
|
||||
- chat.meMessage
|
||||
- chat.postEphemeral
|
||||
- chat.postMessage
|
||||
- chat.scheduleMessage
|
||||
- chat.update
|
||||
- chat.unfurl
|
||||
- conversations.acceptSharedInvite
|
||||
- conversations.inviteShared
|
||||
- conversations.approveSharedInvite
|
||||
- conversations.declineSharedInvite
|
||||
- conversations.listConnectInvites
|
||||
- conversations.history
|
||||
- conversations.replies
|
||||
- conversations.join
|
||||
- conversations.setPurpose
|
||||
- conversations.setTopic
|
||||
- dnd.endDnd
|
||||
- dnd.endSnooze
|
||||
- dnd.setSnooze
|
||||
- dnd.info
|
||||
- dnd.teamInfo
|
||||
- emoji.list
|
||||
- files.comments.delete
|
||||
- files.completeUploadExternal
|
||||
- files.delete
|
||||
- files.getUploadURLExternal
|
||||
- files.revokePublicURL
|
||||
- files.sharedPublicURL
|
||||
- files.upload
|
||||
- files.info
|
||||
- files.list
|
||||
- files.remote.add
|
||||
- files.remote.remove
|
||||
- files.remote.update
|
||||
- files.remote.info
|
||||
- files.remote.list
|
||||
- files.remote.share
|
||||
- functions.distributions.permissions.add
|
||||
- functions.distributions.permissions.remove
|
||||
- functions.distributions.permissions.set
|
||||
- functions.distributions.permissions.list
|
||||
- conversations
|
||||
- groups.open
|
||||
- tokens.basic
|
||||
- migration.exchange
|
||||
- email
|
||||
- openid.connect.userInfo
|
||||
- pins.add
|
||||
- pins.remove
|
||||
- pins.list
|
||||
- reactions.add
|
||||
- reactions.remove
|
||||
- reactions.get
|
||||
- reactions.list
|
||||
- reminders.add
|
||||
- reminders.complete
|
||||
- reminders.delete
|
||||
- reminders.info
|
||||
- reminders.list
|
||||
- search.all
|
||||
- search.files
|
||||
- search.messages
|
||||
- stars.add
|
||||
- stars.remove
|
||||
- stars.list
|
||||
- admin
|
||||
- team.accessLogs
|
||||
- team.billableInfo
|
||||
- team.integrationLogs
|
||||
- team.billing.info
|
||||
- team.info
|
||||
- team.preferences.list
|
||||
- team.profile.get
|
||||
- users.profile.get
|
||||
- usergroups.create
|
||||
- usergroups.disable
|
||||
- usergroups.enable
|
||||
- usergroups.update
|
||||
- usergroups.users.update
|
||||
- usergroups.list
|
||||
- usergroups.users.list
|
||||
- users.deletePhoto
|
||||
- users.profile.set
|
||||
- users.setPhoto
|
||||
- identity.basic
|
||||
- users.identity
|
||||
- users.lookupByEmail
|
||||
- users.setActive
|
||||
- users.setPresence
|
||||
- workflows.stepCompleted
|
||||
- workflows.stepFailed
|
||||
- workflows.updateStep
|
||||
- workflows.triggers.permissions.add
|
||||
- workflows.triggers.permissions.remove
|
||||
- workflows.triggers.permissions.set
|
||||
- workflows.triggers.permissions.list
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
//go:generate generate_permissions permissions.yaml permissions.go slack
|
||||
|
||||
package slack
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -12,8 +15,91 @@ import (
|
|||
"github.com/jedib0t/go-pretty/table"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/config"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/pb/analyzerpb"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
)
|
||||
|
||||
var _ analyzers.Analyzer = (*Analyzer)(nil)
|
||||
|
||||
type Analyzer struct {
|
||||
Cfg *config.Config
|
||||
}
|
||||
|
||||
func (Analyzer) Type() analyzerpb.AnalyzerType { return analyzerpb.AnalyzerType_Slack }
|
||||
|
||||
func (a Analyzer) Analyze(_ context.Context, credInfo map[string]string) (*analyzers.AnalyzerResult, error) {
|
||||
key, ok := credInfo["key"]
|
||||
if !ok {
|
||||
return nil, errors.New("key not found in credentialInfo")
|
||||
}
|
||||
|
||||
info, err := AnalyzePermissions(a.Cfg, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return secretInfoToAnalyzerResult(info), nil
|
||||
}
|
||||
|
||||
func secretInfoToAnalyzerResult(info *SecretInfo) *analyzers.AnalyzerResult {
|
||||
if info == nil {
|
||||
return nil
|
||||
}
|
||||
result := analyzers.AnalyzerResult{
|
||||
AnalyzerType: analyzerpb.AnalyzerType_Slack,
|
||||
Metadata: nil,
|
||||
}
|
||||
|
||||
resourceType := "user"
|
||||
fullyQualifiedName := info.User.TeamId + "/" + info.User.UserId
|
||||
if info.User.BotId != "" {
|
||||
resourceType = "bot"
|
||||
fullyQualifiedName = info.User.BotId
|
||||
}
|
||||
resource := analyzers.Resource{
|
||||
Name: info.User.User,
|
||||
FullyQualifiedName: fullyQualifiedName,
|
||||
Type: resourceType,
|
||||
Metadata: map[string]any{
|
||||
"url": info.User.Url,
|
||||
"team": info.User.Team,
|
||||
"team_id": info.User.TeamId,
|
||||
"scopes": strings.Split(info.Scopes, ","),
|
||||
},
|
||||
}
|
||||
|
||||
// extract all permissions
|
||||
permissions := extractPermissions(info)
|
||||
|
||||
result.Bindings = analyzers.BindAllPermissions(resource, permissions...)
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
func extractPermissions(info *SecretInfo) []analyzers.Permission {
|
||||
var permissions []analyzers.Permission
|
||||
|
||||
for _, scope := range strings.Split(info.Scopes, ",") {
|
||||
perms, ok := scope_mapping[scope]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, perm := range perms {
|
||||
if _, ok := StringToPermission[perm]; !ok {
|
||||
// not in out generated permissions,
|
||||
continue
|
||||
}
|
||||
|
||||
permissions = append(permissions, analyzers.Permission{
|
||||
Value: perm,
|
||||
Parent: nil,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return permissions
|
||||
}
|
||||
|
||||
// Add in showAll to printScopes + deal with testing enterprise + add scope details
|
||||
|
||||
type SlackUserData struct {
|
||||
|
|
83
pkg/analyzer/analyzers/slack/slack_test.go
Normal file
83
pkg/analyzer/analyzers/slack/slack_test.go
Normal file
|
@ -0,0 +1,83 @@
|
|||
package slack
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/config"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
||||
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
||||
)
|
||||
|
||||
//go:embed expected_output.json
|
||||
var expectedOutput []byte
|
||||
|
||||
func TestAnalyzer_Analyze(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors2")
|
||||
if err != nil {
|
||||
t.Fatalf("could not get test secrets from GCP: %s", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
key string
|
||||
want string // JSON string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid Slack key",
|
||||
key: testSecrets.MustGetField("SLACK"),
|
||||
want: string(expectedOutput),
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
a := Analyzer{Cfg: &config.Config{}}
|
||||
got, err := a.Analyze(ctx, map[string]string{"key": tt.key})
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Analyzer.Analyze() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
// Marshal the actual result to JSON
|
||||
gotJSON, err := json.Marshal(got)
|
||||
if err != nil {
|
||||
t.Fatalf("could not marshal got to JSON: %s", err)
|
||||
}
|
||||
|
||||
// Parse the expected JSON string
|
||||
var wantObj analyzers.AnalyzerResult
|
||||
if err := json.Unmarshal([]byte(tt.want), &wantObj); err != nil {
|
||||
t.Fatalf("could not unmarshal want JSON string: %s", err)
|
||||
}
|
||||
|
||||
// Marshal the expected result to JSON (to normalize)
|
||||
wantJSON, err := json.Marshal(wantObj)
|
||||
if err != nil {
|
||||
t.Fatalf("could not marshal want to JSON: %s", err)
|
||||
}
|
||||
|
||||
// Compare the JSON strings
|
||||
if string(gotJSON) != string(wantJSON) {
|
||||
// Pretty-print both JSON strings for easier comparison
|
||||
var gotIndented, wantIndented []byte
|
||||
gotIndented, err = json.MarshalIndent(got, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("could not marshal got to indented JSON: %s", err)
|
||||
}
|
||||
wantIndented, err = json.MarshalIndent(wantObj, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("could not marshal want to indented JSON: %s", err)
|
||||
}
|
||||
t.Errorf("Analyzer.Analyze() = %s, want %s", gotIndented, wantIndented)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -109,6 +109,9 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
|||
} else {
|
||||
s1.SetVerificationError(err, token)
|
||||
}
|
||||
s1.AnalysisInfo = map[string]string{
|
||||
"key": token,
|
||||
}
|
||||
}
|
||||
|
||||
results = append(results, s1)
|
||||
|
|
|
@ -141,6 +141,7 @@ func TestSlack_FromChunk(t *testing.T) {
|
|||
t.Fatal("no raw secret present")
|
||||
}
|
||||
got[i].Raw = nil
|
||||
got[i].AnalysisInfo = nil
|
||||
|
||||
if (got[i].VerificationError() != nil) != tt.wantVerificationErr {
|
||||
t.Fatalf("wantVerificationError = %v, verification error = %v", tt.wantVerificationErr, got[i].VerificationError())
|
||||
|
|
Loading…
Reference in a new issue