jonsequitur / Its.Log

Get information out of your code at runtime to send it to log files, perf counters, consoles, services, sensors. Maximum flexibility and maintainability, minimum code.
Other
13 stars 10 forks source link

Channel abstraction for SecureString and other data types #16

Closed jzabroski closed 8 years ago

jzabroski commented 9 years ago

In-betwixt the issuance to Log something and the decision on what to write to the Log Sink, there should be a mediator which can route confidential information to a special log, and even apply masking to it.

A concrete example is logging anything containing SecureString. On the surface, this seems very unsafe, but there are many secure channels for sending and receiving SecureString data, e.g. over an encrypted network.

jonsequitur commented 9 years ago

Its.Log has no default output, so this is left entirely to the consumer of the in-memory Log.Events observable. The type system alone isn't a good indicator of whether data is sensitive.

So, for example, given a class like this:

public class SomeClass
{
    public string NonSensitiveInfo { get; set; }
    public string SensitiveInfo { get; set; } 
}

The general approach is to do something like this:

Formatter<SomeClass>.Register( _ => new { _.NonSensitiveInfo  }.ToLogString() );

There's been some discussion of ways to support doing this via conventions, e.g. allow decorating sensitive members using an attribute. On-demand initialization per type (similar to Formatter.AutoGenerateForType) is a likely approach.

jzabroski commented 9 years ago

I don't think you followed my suggestion.

Log.Events is a "channel" - but you only support a singleton channel currently. This means somebody can tamper with the event stream by hooking in data sinks with unsafe data-in-transit and data-at-rest policies. Log.Events is a single Log Sink. As I originally stated, I want something between the Log Issuer and the Log Sink.

I realize this is a nice-to-have, but let's agree hijacking formatters for serialization of sensitive data is not a general approach. My point in logging this idea was to discuss what it should look like, rather than discuss workarounds. I don't believe any logging framework actually does what I am proposing, so it would be a unique feature.

nathanboktae commented 9 years ago

somebody can tamper with the event stream .... I don't believe any logging framework actually does what I am proposing

Its.Log was designed for web applications in mind, not shipping DLLs to be embedded in other box software. If someone has access to your running bits on a box/vm/container, you have much bigger problems. No other logging framework does this because it's not a real scenario.

jzabroski commented 9 years ago

No other framework logs whole objects by convention, either.

"Web applications" is really a reductionist argument. Web apps are potentially just as open to attack, if not more so, than 'box software'. In particular, consider piping output to a Log Sink via a SignalR log appender. The security concern has nothing to do with the log appender, and nothing to do with the log issuer. It has everything to do with the wiring mechanism and policy put in place. This is just providing ingress and egress data flow security.

To counter this line of thinking by drawing it out to its logical conclusion - I guess System.Web should not need to use SecureString anywhere?

Jon and I discussed on chat outside this issue; it may be OK to have the Log.Events observable filter out stuff and figure out how to disallow direct access to Log.Events to other assemblies (third party code). I am thinking about it.

jonsequitur commented 9 years ago

I wouldn't say it's not a real scenario, I'd just say it's one we've never considered and may fall outside Its.Log's design goals. Keeping the problem space confined is important to a reusable design. That said, I don't think the goal is incompatible with the existing design. It may just be a matter of focusing on message-level rather than channel-level security.

jzabroski commented 9 years ago

Also... just to elaborate more on why this is helpful even for "Web applications" (since that is the second time I have heard that argument): You don't actually control the environment your Web application is deployed to! You owe it to your user's to do everything you can to protect their data, even if you require that data for some telemetry. In most cases, you don't require that data, but it may be commingled with non-secret data. A simple example is ocap security model, where objects pass security tokens with method invocation to designate responsibility and authority. You don't want to serialize that token.

Another ex: Back when cloud was just becoming a thing, it was common for security researchers to show that memory wasn't completely blanked by the host OS, and so if a new guest OS spun up, a process could randomly probe memory looking for passwords. This was a big article on /. about a decade ago.

nathanboktae commented 9 years ago

You don't actually control the environment your Web application is deployed to!

Exactly my point. A host OS can probe your memory anyways and there's nothing Its.Log can do about it. So trust your infrastructure or encrypt it from the client E2E.

Message-level security makes sense and it's good to have the semantics there.