Is this secure? Concept for private info in replies

(Rohmann) #1

I really need a way for users to add sensitive data to a post without using private messages. I have this in a plugin:

require_dependency "plugin/filter"

  Plugin::Filter.register(:after_post_cook) do |post, cooked|
    cooked.gsub(/\[secret\].*?\[\/secret\]/) { |a| index+=1; "<div class="secret-info" data-secret-post-id=\"#{}\" data-secret-post-index=\"#{index}\">#{I18n.t('secret_replies.cooked_message')}</div>" }

Effectively, it takes this content:

Anyone can see this.
[secret]but not this[/secret]
[secret]and DEFINITELY not this[/secret]

and cooks down to:

<p>Anyone can see this.</p>
<div class="secret-info" data-secret-post-id="42" data-secret-post-index="1">This content has been marked as secret. It is visible to staff and the original poster.</div>
<div class="secret-info" data-secret-post-id="42" data-secret-post-index="2">This content has been marked as secret. It is visible to staff and the original poster.</div>

Assuming this is safe to do, the rest of the plugin can be built around this concept. For example, there can be a protected endpoint for retrieving the raw content, and client modifications to add it back to the cooked content.

I do understand that if a user is given the ability to edit a post they will get raw content. I’m ok with this since those users are already staff, or are otherwise trustworthy with these secrets.

Main question: Is there any unguarded context where Discourse outputs raw post content instead of cooked content?

Any other security concerns? Thanks!

Whispering to non-moderators?
(Jay Pfaffman) #2

LIke this?

In other words, yes. If someone can read the post, they can read the raw content.

(Tobias Eigen) #3

Sounds like you want whispers. This exists but only for moderators.

(Rohmann) #4

@tobiaseigen I looked at whispers but I really need the functionality for everyone. Whispers are also completely hidden instead of inline with the reply which would be ideal (although if I had something working I could live without it).

Thanks! Yes, stuff like that is what I meant. So back to the drawing board…

(Matt Palmer) #5

Perhaps if you describe the bigger picture of what you’re trying to achieve, you’ll avoid falling foul of the XY problem.

(Jay Pfaffman) #6

Thanks, @mpalmer! That’s awesome. I’ve been aware of the XY Problem for at least 30 years, but never knew what to call it.

(Rohmann) #7

Sure! I’m using a Discourse category for handling product support, and other categories for discussion. Sometimes users need to share their site URL or even login information with us in a way that keeps the topic itself readable to others, but our staff can still see that info.

(Jay Pfaffman) #8

Maybe you want to do something that puts the information in a PM and inserts a link to the PM (perhaps semi-hidden as you’ve attempted previously)

(Rohmann) #9

It would be really great if the information was just inline somehow. It’s a bit more involved, but the next concept I’m currently exploring involves using add_to_serializer to supply a custom field when viewed by the post owner or admin/moderator. Instead of the shortcode style method I originally wanted, I’ll probably need to make a custom UI in the composer.

(Jeff Atwood) #10

The fact that you sent a PM to someone in reference to a post is noted below the post, but this might be a staff-only thing.

(Rohmann) #11

Let me know what you guys think of this method. It will need a custom UI put together, but the idea is that a custom post field is used to store the private information. It’s added to the serializer if the user is staff or the OP, and can be piped down into the post stream.

Does this look secure? Is there a way people could otherwise find the custom field contents?

(Matt Palmer) #12

For me, personally, I’d just say “PM me the <details>”, and save writing a custom plugin…

(Rohmann) #13

@mpalmer That works, but really slows down the process. It isn’t very scalable. For example, with inline private data the user can attach a private URL before the topic even gets a response. The next person able to work on the ticket may not have been the one requesting the login credentials. If the ticket needs escalation to another user they’d have to coordinate to get that information (more potential exposure) or annoyingly request the user to PM someone else. And if the user needs to change any of the information along the way, they need to resend it to any of the involved parties. For me it is definitely worth a custom plugin if I can get private data per post accessible by the OP and staff.

The plugin in the gist above gets custom field content into the post stream, and only when the user should be able to see it.

It also accepts a PUT to /secure-note/update allowing permissible users to set the note content. It seems to be working minus the UI. Being new to Rails and Discourse plugin development, I’m just concerned about that custom field somehow being exposed to users who shouldn’t see it somehow.

Is it ok to store sensitive info in custom fields?

(Jeff Atwood) #14

You need to make these people staff and use whispers. That is exactly what whispers are for – if staff are the ones with the secret.

Granted with customer secrets you can’t but in this case use incoming email to trigger a group PM. That is how works for example. Then the topic, instantiated by an email, is private and visible only to the team group and that one customer… who can either log in to reply (with the same email address), or rely via email.

(Rohmann) #15

Thanks @codinghorror That sounds like you’re creating an entirely private conversation though right? What I’m hoping to achieve is public/open forum support with a quick way for users to share info with our team. Whispers would be perfect if it could be extended it to work for regular users.

Building a plugin seems like the only way to get what I need. Just hoping I can do it securely and not expose the information anywhere.

(Rafael dos Santos Silva) #16

I really get what you want to archive, and skimming through your code the back end of things looks good.

I’m really curious about how you gonna wire stuff up on the front end. The balance between easy for users to use and not intrusive when not needed is hard.

(Jeff Atwood) #17

It’s just a very peculiar request since you are insisting the normal method of PM is somehow not acceptable and the information must be inline.

(Matt Palmer) #18

The UX on this is going to be epic… how to make sure users put their private info in the private boxes and not in the public post, and vice versa. I just don’t see people, in general, navigating this particularly well.

I’m also not convinced that having public discussions that “the public” can only partially see is really valuable. If the question requires private information to answer, then how does having the discussion in public help? Nobody who doesn’t have access to the private information can help, and any answers from staff are dependent on the details of the private information, so the answers aren’t generally useful for future visitors.

(Rohmann) #19

@mpalmer Most people aren’t quick to share sensitive info without knowing it’s safe. I’m comfortable placing a “Secure Note” button right of “Reply” since you’ll almost never reply to your own post. Finished the UI:

Post with a secure note

Editing Modal

Staff button when not the OP

For now, I’ve got the plugin here: GitHub - rohmann/discourse-secure-note