저는 주로 HTTP 통신을 했었는데 고성능 프로세스 간 통신을 원하시는 분들은 BinaryFormatter 를 자주 사용하셨던 것 같습니다.
MSDN 에서는 BinaryFormatter를 제거하면서 대신 JsonSerializer나 XmlSerializer를 사용하라고 하지만 , 아무래도 사람이 읽을 수 있는 데이터는 통신 속도가 느리다고 생각해서인지? 이것을 부정적으로 생각하는 분들이 계시네요.
또한 BinaryFormatter가 빠른 이유는 불안전하기 때문이라는 주장도 보입니다.
역시 이런 분야에서도 트레이드오프는 불변의 진리네요…
저도 그런 부류입니다. (포멧터에 대해 자세히는 알지 못하나 느낌적인 느낌으로요!)
아래는 BinaryFormatter 제거에 대한 Github 토론입니다.
opened 07:01PM - 21 Jun 19 UTC
closed 04:38PM - 14 Jul 20 UTC
api-suggestion
area-System.Runtime
We've known for a long while that `BinaryFormatter` is a dangerous type and that… it's responsible for many of the security vulnerabilities real-world .NET applications have seen in recent years. In .NET Core 1.x, the type was removed from the product entirely, and it was brought back in .NET Core 2.0 under the guise of "app compat".
Though as of the time of this writing there are no known types in .NET Core which can be leveraged by `BinaryFormatter` to achieve RCE, it is impractical to make this guarantee going forward. As new types are introduced (or existing types from the full Framework are re-introduced) I have no doubt that one of them will contain such a vector that we weren't able to catch during development due to the complexity of this system.
Some applications use a custom `SerializationBinder` to mitigate attacks both on .NET Core and in full Framework. The engineering team's current understanding is that a properly-written `SerializationBinder` is sufficient to block RCE attacks. However, _this is not a guarantee_, and even so, a custom `SerializationBinder` cannot mitigate other attacks like DoS within the `BinaryFormatter` infrastructure itself.
All of this said, the conclusion is that __`BinaryFormatter` is not an appropriate serialization format for application developers to be using in a cloud-connected world.__ It was a mistake for us to bring it back in .NET Core 2.0, as us re-introducing it into the shared framework gives the type an undeserved air of respectability, like we're nodding and implicitly approving its usage by modern applications.
To address this, and to eventually migrate applications off of `BinaryFormatter`, I propose the following steps. These steps will _only_ affect customers who target .NET 5 or above for their applications.
1. Remove `BinaryFormatter` from the shared framework and into its own standalone package that must be manually retrieved and installed into the application.
2. Mark the `BinaryFormatter` type itself with `[Obsolete]`, or include in the package a code analyzer which warns on the type's usage. Force developers to explicitly acknowledge that they're calling an extremely dangerous API and that they must be certain the data is coming from a trusted location.
3. Document the `BinaryFormatter` code base as legacy only. Clearly communicate that Microsoft is making no further investments in this code base, and all bug reports or feature requests will be immediately closed.
4. Create a separate "safe" (type-limiting, bounds-checking, etc.) serializer whose payload format is `BinaryFormatter`-compatible and which can be used to deserialize existing payloads in a safe fashion, even if those payloads originate from an untrusted source. The API surface will look different than the traditional `BinaryFormatter.Deserialze` call due to needing to configure the serializer on a per-call basis, but at minimum it gives applications a way to read existing payloads. This allows them to migrate their data without leaving them hanging. This serializer could be in the same package that `BinaryFormatter` is in.
These steps would serve to modernize the runtime and SDK by eliminating a type which has no place in today's development cycle, it serves as a forcing function to get application developers to fix potential vulnerabilities in their code, and it provides _on an opt-in basis_ a way for applications to continue to work if they really must continue using the type going forward.
구글 번역기를 통해 대충 이해한 바에 따르면 이 스레드는 Google의 grpc에 사용되는 ProtoBuf의 .NET Wrapper를 대안을 이용하자는 듯한데, mconnew 라는 분이 그것에 대해 반대 를 하면서 다른 토론 스레드가 생성 됩니다.
그리고 또한 BinaryFormatter를 이용했을 때 .NET App이 공격을 받을 수 있는 상황을 설명하는 링크도 있습니다.
opened 07:01PM - 21 Jun 19 UTC
closed 04:38PM - 14 Jul 20 UTC
api-suggestion
area-System.Runtime
We've known for a long while that `BinaryFormatter` is a dangerous type and that… it's responsible for many of the security vulnerabilities real-world .NET applications have seen in recent years. In .NET Core 1.x, the type was removed from the product entirely, and it was brought back in .NET Core 2.0 under the guise of "app compat".
Though as of the time of this writing there are no known types in .NET Core which can be leveraged by `BinaryFormatter` to achieve RCE, it is impractical to make this guarantee going forward. As new types are introduced (or existing types from the full Framework are re-introduced) I have no doubt that one of them will contain such a vector that we weren't able to catch during development due to the complexity of this system.
Some applications use a custom `SerializationBinder` to mitigate attacks both on .NET Core and in full Framework. The engineering team's current understanding is that a properly-written `SerializationBinder` is sufficient to block RCE attacks. However, _this is not a guarantee_, and even so, a custom `SerializationBinder` cannot mitigate other attacks like DoS within the `BinaryFormatter` infrastructure itself.
All of this said, the conclusion is that __`BinaryFormatter` is not an appropriate serialization format for application developers to be using in a cloud-connected world.__ It was a mistake for us to bring it back in .NET Core 2.0, as us re-introducing it into the shared framework gives the type an undeserved air of respectability, like we're nodding and implicitly approving its usage by modern applications.
To address this, and to eventually migrate applications off of `BinaryFormatter`, I propose the following steps. These steps will _only_ affect customers who target .NET 5 or above for their applications.
1. Remove `BinaryFormatter` from the shared framework and into its own standalone package that must be manually retrieved and installed into the application.
2. Mark the `BinaryFormatter` type itself with `[Obsolete]`, or include in the package a code analyzer which warns on the type's usage. Force developers to explicitly acknowledge that they're calling an extremely dangerous API and that they must be certain the data is coming from a trusted location.
3. Document the `BinaryFormatter` code base as legacy only. Clearly communicate that Microsoft is making no further investments in this code base, and all bug reports or feature requests will be immediately closed.
4. Create a separate "safe" (type-limiting, bounds-checking, etc.) serializer whose payload format is `BinaryFormatter`-compatible and which can be used to deserialize existing payloads in a safe fashion, even if those payloads originate from an untrusted source. The API surface will look different than the traditional `BinaryFormatter.Deserialze` call due to needing to configure the serializer on a per-call basis, but at minimum it gives applications a way to read existing payloads. This allows them to migrate their data without leaving them hanging. This serializer could be in the same package that `BinaryFormatter` is in.
These steps would serve to modernize the runtime and SDK by eliminating a type which has no place in today's development cycle, it serves as a forcing function to get application developers to fix potential vulnerabilities in their code, and it provides _on an opt-in basis_ a way for applications to continue to work if they really must continue using the type going forward.
opened 07:01PM - 21 Jun 19 UTC
closed 04:38PM - 14 Jul 20 UTC
api-suggestion
area-System.Runtime
We've known for a long while that `BinaryFormatter` is a dangerous type and that… it's responsible for many of the security vulnerabilities real-world .NET applications have seen in recent years. In .NET Core 1.x, the type was removed from the product entirely, and it was brought back in .NET Core 2.0 under the guise of "app compat".
Though as of the time of this writing there are no known types in .NET Core which can be leveraged by `BinaryFormatter` to achieve RCE, it is impractical to make this guarantee going forward. As new types are introduced (or existing types from the full Framework are re-introduced) I have no doubt that one of them will contain such a vector that we weren't able to catch during development due to the complexity of this system.
Some applications use a custom `SerializationBinder` to mitigate attacks both on .NET Core and in full Framework. The engineering team's current understanding is that a properly-written `SerializationBinder` is sufficient to block RCE attacks. However, _this is not a guarantee_, and even so, a custom `SerializationBinder` cannot mitigate other attacks like DoS within the `BinaryFormatter` infrastructure itself.
All of this said, the conclusion is that __`BinaryFormatter` is not an appropriate serialization format for application developers to be using in a cloud-connected world.__ It was a mistake for us to bring it back in .NET Core 2.0, as us re-introducing it into the shared framework gives the type an undeserved air of respectability, like we're nodding and implicitly approving its usage by modern applications.
To address this, and to eventually migrate applications off of `BinaryFormatter`, I propose the following steps. These steps will _only_ affect customers who target .NET 5 or above for their applications.
1. Remove `BinaryFormatter` from the shared framework and into its own standalone package that must be manually retrieved and installed into the application.
2. Mark the `BinaryFormatter` type itself with `[Obsolete]`, or include in the package a code analyzer which warns on the type's usage. Force developers to explicitly acknowledge that they're calling an extremely dangerous API and that they must be certain the data is coming from a trusted location.
3. Document the `BinaryFormatter` code base as legacy only. Clearly communicate that Microsoft is making no further investments in this code base, and all bug reports or feature requests will be immediately closed.
4. Create a separate "safe" (type-limiting, bounds-checking, etc.) serializer whose payload format is `BinaryFormatter`-compatible and which can be used to deserialize existing payloads in a safe fashion, even if those payloads originate from an untrusted source. The API surface will look different than the traditional `BinaryFormatter.Deserialze` call due to needing to configure the serializer on a per-call basis, but at minimum it gives applications a way to read existing payloads. This allows them to migrate their data without leaving them hanging. This serializer could be in the same package that `BinaryFormatter` is in.
These steps would serve to modernize the runtime and SDK by eliminating a type which has no place in today's development cycle, it serves as a forcing function to get application developers to fix potential vulnerabilities in their code, and it provides _on an opt-in basis_ a way for applications to continue to work if they really must continue using the type going forward.
아래는 BinaryFormatter 제거에 관련된 MSDN 링크입니다.
아래는 BinaryFormatter 제거에 관련된
C#의 언어 디자인 입니다. 언제 어느 방향으로 제거할 것인지 계획을 설명하고 있습니다.
# BinaryFormatter Obsoletion Strategy
**Owner** [Levi Broderick](https://github.com/GrabYourPitchforks)
This document applies to the following framework versions:
* .NET 5.0+
Applications which target .NET Framework 2.x, .NET Framework 4.x, or .NET Core 3.1 are _not affected_ by this proposal. `BinaryFormatter` will continue to work as expected in those applications. Consumers of `BinaryFormatter` are still advised to consult the [`BinaryFormatter` security guide](https://github.com/dotnet/docs/pull/19442) to help inform their risk assessment.
## Introduction
As part of modernizing the .NET development stack and improving the overall health of the .NET ecosystem, it is time to sunset the `BinaryFormatter` type. `BinaryFormatter` is the mechanism by which many .NET applications find themselves exposed to critical security vulnerabilities, and its continued usage results in numerous such incidents every year across both first-party and third-party code.
We have messaged previously that `BinaryFormatter` is not safe for untrusted input, but outside of the security community this guidance hasn't really taken root. This is partly because there's already a critical mass of code using `BinaryFormatter`, and developers are generally disincentivized from changing existing code. It's also partly due to the fact that threat modeling is an advanced topic not well understood by the majority of developers. Without the .NET team introducing a forcing function, the ecosystem holistically does not feel the need to improve.
See the [`BinaryFormatter` security guide](https://github.com/dotnet/docs/pull/19442) for more information on the problem space.
`BinaryFormatter` also leads to the creation of fragile and non-versionable types. Its operation relies primarily on private reflection over an object's instance fields. This ties the serialized payload format to internal implementation details of the target types. Updating or improving the implementation details of the target type often creates compatibility problems between serialized versions.
This file has been truncated. show original
어쨌든 .NET에선 좋던 싫든 장기적으로 BinaryFormatter에 대한 제거 계획을 확정한 것 같고, 대안을 찾아 도메인에 맞는 테스트와 리펙토링을 해야할 것 같습니다.
9개의 좋아요
BinaryFormatter는 형식이 포함되어 생성된 스트림 데이터의 양이 큰 편입니다.
그리고 Protobuf나 MessagePack에 비해 성능이 떨어진다는 단점도 있습니다.
아래 자료는 2011년 자료이긴 하나 BinaryFormatter가 이후의 성능 향상이 없었던 것으로 알고 있어서 성능은 되려 좀 더 벌어지지 않았을까 합니다.
다른 대안으로 MessagePack 을 대신 사용할 수 있습니다. 또는 ProtoBuf 를 사용할 수도 있습니다.
5개의 좋아요
부가 설명 감사드립니다.
구글 번역기를 통해 대충 이해한 바에 따르면 이 스레드는 Google의 grpc에 사용되는 ProtoBuf의 .NET Wrapper를 대안을 이용하자는 듯한데, mconnew 라는 분이 그것에 대해 반대 를 하면서 다른 토론 스레드가 생성 됩니다.
해당 토론 글에 mconnew의 protobuf가 BinaryFormatter의 대안이 되지 않는 이유 도 설명하고 있어서 함께 보시면 좋을 거 같습니다.
비교 대상이 아니다 라는 느낌으로 저는 다가오네요.
4개의 좋아요
어떤 목적으로 사용할 것 인가에 따라 다를 것 같네요. MessagePack의 C# 구현체도 역시 순환참조를 지원하지 않습니다. 문제는 원론적으로 성능(속도 및 크기)과 밀접한 관계가 있습니다.
관련 문제를 해결한 범용 이진 시리얼라이저로 Ceras 라는게 있습니다. 아쉽지만 아직까지는 보편적으로 활성화된 솔루션은 아닌 듯 합니다.
5개의 좋아요
오…새로운 오픈소스를 알아갑니다.
저는 꽤 컨트리뷰터가 많다고…보여지는 오픈소스네요 ㅎㅎ 나중에 기회가 되면 써보고 싶습니다.
다시 따로 떨어져 나간 스레드 를 읽어보면 관점의 차이라고 생각해서 mconnew는 직렬화 형식이라고 생각하지 않는 것 같습니다.
제가 이해되는 mconnew의 맥락은
예를 들면 Object Model (Entity)를 정의하고 Json String 으로 직렬화 했을 때 그것은 객체를 기반으로 직렬화가 된 것으로 직렬화라고 보는 것이 맞고,
ProtoBuf의 경우에는 해당 Object Model 자체만으로는 직렬화가 어렵고 ProtoBuf의 계약형식을 따로 파일로 정의해야 하기 때문에, '직렬화’가 되는 주체가 'OM’인지 '계약’인지 에 따라서 토론 참여자들의 주장이 엇갈리는 것 같습니다.
그래서 제가 생각하는 결론은 말씀하신대로
문제는 원론적으로 성능(속도 및 크기)과 밀접한 관계가 있습니다.
에 동의하며 주요하게 신경 쓸 부분은 아니지만 저런 관점도 있다는 것도 알아가면 된다라고 생각이 됩니다.
2개의 좋아요