Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make PrivacyModule detect sensitive launcher files #674

Merged
merged 1 commit into from
May 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ arisa:
allowedEmailRegex:
- '^(mailer-daemon|postmaster|nobody|noreply|no-reply|hostmaster|usenet|news|webmaster|www|abuse|noc|security|info|support|uucp|ftp|news|admin|root)@.*'
- '.*@(mojang.com|microsoft.com|minecraft.net|zendesk.com)$'
sensitiveFileNames:
- launcher_accounts.json
- launcher_msa_credentials.json
- launcher_profiles.json

removeTriagedMeqs:
resolutions:
Expand Down
2 changes: 2 additions & 0 deletions docs/Modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ Hides privacy information like Email addresses in tickets or comments.
- The ticket is not set to private.
#### For Setting Tickets to Private
- Any of the fields and/or text attachments added after last run contains session ID or Email.
- Or any of the attachments has a name specified by `sensitiveFileNames` in the [config](../config/config.yml)
(defaults to empty list)
#### For Restricting Comments to `staff`
- The comment was added after last run.
- The comment is not restricted.
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/io/github/mojira/arisa/ModuleRegistry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ class ModuleRegistry(private val config: Config) {
PrivacyModule(
config[Modules.Privacy.message],
config[Modules.Privacy.commentNote],
config[Modules.Privacy.allowedEmailRegex].map(String::toRegex)
config[Modules.Privacy.allowedEmailRegex].map(String::toRegex),
config[Modules.Privacy.sensitiveFileNames]
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ object Arisa : ConfigSpec() {
default = emptyList(),
description = "List of regex for allowed emails"
)
val sensitiveFileNames by optional<List<String>>(
default = emptyList(),
description = "Names of attachment files containing sensitive information"
)
}

object Language : ModuleConfigSpec() {
Expand Down
12 changes: 10 additions & 2 deletions src/main/kotlin/io/github/mojira/arisa/modules/PrivacyModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ package io.github.mojira.arisa.modules

import arrow.core.Either
import arrow.core.extensions.fx
import io.github.mojira.arisa.domain.Attachment
import io.github.mojira.arisa.domain.CommentOptions
import io.github.mojira.arisa.domain.Issue
import java.time.Instant

class PrivacyModule(
private val message: String,
private val commentNote: String,
private val allowedEmailsRegex: List<Regex>
private val allowedEmailsRegex: List<Regex>,
private val sensitiveFileNames: List<String>
) : Module {
private val patterns: List<Regex> = listOf(
""".*\(Session ID is token:.*""".toRegex(),
Expand Down Expand Up @@ -46,6 +48,11 @@ class PrivacyModule(
val doesStringMatchPatterns = string.matches(patterns)
val doesEmailMatches = matchesEmail(string)

val doesAttachmentNameMatch = attachments
.asSequence()
.map(Attachment::name)
.any(sensitiveFileNames::contains)

val restrictCommentFunctions = comments
.asSequence()
.filter { it.created.isAfter(lastRun) }
Expand All @@ -62,10 +69,11 @@ class PrivacyModule(
assertEither(
assertTrue(doesStringMatchPatterns),
assertTrue(doesEmailMatches),
assertTrue(doesAttachmentNameMatch),
assertNotEmpty(restrictCommentFunctions)
).bind()

if (doesStringMatchPatterns || doesEmailMatches) {
if (doesStringMatchPatterns || doesEmailMatches || doesAttachmentNameMatch) {
setPrivate()
addComment(CommentOptions(message))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe

private val ALLOWED_REGEX = listOf("allowed@.*".toRegex())
private val MODULE = PrivacyModule("message", "\n----\nRestricted by PrivacyModule ??[~arisabot]??", ALLOWED_REGEX)
private val MODULE = PrivacyModule("message", "\n----\nRestricted by PrivacyModule ??[~arisabot]??", ALLOWED_REGEX, emptyList())
private val TWO_SECONDS_AGO = RIGHT_NOW.minusSeconds(2)
private val TEN_SECONDS_AGO = RIGHT_NOW.minusSeconds(10)

Expand Down Expand Up @@ -306,7 +306,7 @@ class PrivacyModuleTest : StringSpec({
hasSetPrivate shouldBe true
}

"should not mark as private when the change log item contains a allowed email" {
"should not mark as private when the change log item contains an allowed email" {
var hasSetPrivate = false

val issue = mockIssue(
Expand All @@ -326,7 +326,7 @@ class PrivacyModuleTest : StringSpec({
hasSetPrivate shouldBe false
}

"should mark as private when the change log item contains a allowed email and a not allowed email" {
"should mark as private when the change log item contains an allowed email and a not allowed email" {
var hasSetPrivate = false

val issue = mockIssue(
Expand Down Expand Up @@ -369,4 +369,44 @@ class PrivacyModuleTest : StringSpec({
hasSetPrivate shouldBe false
hasRestrictedComment shouldBe true
}

"should mark as private when attachment has sensitive name" {
val sensitiveFileName = "sensitive.txt"
val module = PrivacyModule("message", "comment", ALLOWED_REGEX, listOf(sensitiveFileName))
var hasSetPrivate = false

val issue = mockIssue(
attachments = listOf(
mockAttachment(
name = sensitiveFileName
)
),
setPrivate = { hasSetPrivate = true }
)

val result = module(issue, TWO_SECONDS_AGO)

result.shouldBeRight(ModuleResponse)
hasSetPrivate shouldBe true
}

"should not mark as private when attachment has non-sensitive name" {
val sensitiveFileName = "sensitive.txt"
val module = PrivacyModule("message", "comment", ALLOWED_REGEX, listOf(sensitiveFileName))
var hasSetPrivate = false

val issue = mockIssue(
attachments = listOf(
mockAttachment(
name = "non-$sensitiveFileName"
)
),
setPrivate = { hasSetPrivate = true }
)

val result = module(issue, TWO_SECONDS_AGO)

result.shouldBeLeft(OperationNotNeededModuleResponse)
hasSetPrivate shouldBe false
}
})