글쎄, 그 질문은 자명하다. 보안 위험이있는 경우 사용자가 수행 할 수있는 작업의 예를 제공하십시오. 이 경우 기본 키는 다음과 같습니다. "제품 ID"잠재적 인 보안 위험이 대중에게 기본 키를 보여 주겠습니까?
감사합니다!
글쎄, 그 질문은 자명하다. 보안 위험이있는 경우 사용자가 수행 할 수있는 작업의 예를 제공하십시오. 이 경우 기본 키는 다음과 같습니다. "제품 ID"잠재적 인 보안 위험이 대중에게 기본 키를 보여 주겠습니까?
감사합니다!
다른 어떤 데이터도 표시 할 수 없습니다. SQL 인젝션 공격에 취약한 경우 기본 키를 표시하는 것이 가장 우려 할 사항은 아닙니다.
누군가가 db에 대해 임의의 SQL을 실행할 수 있다고 생각하면 피해가 더 많이 발생합니다 : delete from users where id = 100
또는 delete from users where surname = 'smith'
?
고마워, 너의 많은 반응! – Bilzac
일부 기밀 데이터 요소에 대해 읽을 수있는 정보가 포함 된 경우에는 그렇습니다.
답장을 보내 주셔서 감사합니다. – Bilzac
@Bilzak, 플립 답변 죄송합니다, 저항 할 수 없었습니다 ... 예, 분명히, 그것에 두 가지 수준이 있습니다 ... 첫 번째 수준의 답변은 전적으로 yr 시스템의 나머지 부분의 디자인에 기초하고 있으며, 두 번째 수준의 대답은 명백한 ... 나는 그 구별에 유창하게 말하려고 노력했다. 나는 분명히 실패했다. –
기본 키 필드가 노출 될 수있는 고유 한 위험이 있다고 생각하지 않지만 그러한 것으로 광고하는 데는 이점이 없습니다. (나는 당신이 의도 한 것보다 더 깊이 질문을 읽고있을 수도 있음을 알고 있습니다.)
ProductId
고객이 일부 제품을 식별 할 수 있으면 표시해도 좋습니다. 보안 위험은 최소화됩니다, IMO. 난 그냥 ProductId
기본 키로 사용 사실을 폭로하지 않을거야 - 구현 세부 사항은 심지어 내용을 노출하는 동안 숨겨져 있어야합니다.
답장을 보내 주셔서 감사합니다. – Bilzac
반드시 그렇지는 않습니다. 그러나 기본 키 유형을 변경하면서 (또는 데이터베이스 제공자가 모두 변경을 필요로하는 경우) 기본 키를 응용 프로그램 수준 개발자로 추상화하는 것이 좋습니다. 당신이하는 일은 그 레벨에서 기본 키를 추상화하는 인터페이스를 만드는 것이지만, 데이터 레이어는 그 구현을 통해 기본 키를 알고 있습니다. 다음은 예입니다 :
namespace Aesop.DataAccess
{
// System namespaces
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Xml.Serialization;
/// <summary>
/// Represents an object's unique key in order to abstract out the
/// underlying key generation/maintenance mechanism.
/// </summary>
/// <typeparam name="T">The type the key is representing.</typeparam>
[ServiceContract]
public interface IModelIdentifier<T> : ISerializable, IXmlSerializable
{
/// <summary>
/// Gets a string representation of the domain the model originated
/// from.
/// </summary>
string Origin
{
[OperationContract]
get;
}
/// <summary>
/// The model instance identifier for the model object that this
/// <see cref="IModelIdentifier{T}"/> refers to. Typically, this
/// is a database key, file name, or some other unique identifier.
/// </summary>
/// <typeparam name="TKeyDataType">The expected data type of the
/// identifier.</typeparam>
/// <returns>The unique key as the data type specified.</returns>
[OperationContract]
TKeyDataType GetKey<TKeyDataType>();
/// <summary>
/// Performs an equality check on the two model identifiers and returns
/// <c>true</c> if they are equal; otherwise <c>false</c> is returned.
/// All implementations must also override the equal operator.
/// </summary>
/// <param name="obj">The identifier to compare against.</param>
/// <returns>
/// <c>true</c> if the identifiers are equal; otherwise
/// <c>false</c> is returned.
/// </returns>
[OperationContract]
bool Equals(IModelIdentifier<T> obj);
}
}
그리고 여기에 "표준"INT 기본 키에 대한 구현의 :
namespace Aesop.DataAccess
{
// System namespaces
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
/// <summary>
/// Represents an abstraction of the database key for a Model Identifier.
/// </summary>
/// <typeparam name="T">The expected owner data type for this identifier.
/// </typeparam>
[DebuggerDisplay("Integer Identifier={id}, Origin={Origin}")]
[Serializable]
public sealed class IntegerIdentifier<T> : IModelIdentifier<T> where T : class, ISerializable, IXmlSerializable
{
/// <summary>
/// The unique ID.
/// </summary>
private int id;
/// <summary>
/// Initializes a new instance of the <see cref="IntegerIdentifier<T>"/> class.
/// </summary>
/// <param name="id">The unique ID.</param>
public IntegerIdentifier(int id)
{
this.id = id;
}
/// <summary>
/// Initializes a new instance of the <see cref="IntegerIdentifier<T>"/> class.
/// </summary>
/// <param name="info">The
/// <see cref="T:System.Runtime.Serialization.SerializationInfo"/> from
/// which to retrieve the data.</param>
/// <param name="context">The source (see
/// <see cref="T:System.Runtime.Serialization.StreamingContext"/>) for
/// this deserialization.</param>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
private IntegerIdentifier(
SerializationInfo info,
StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
this.id = info.GetInt32("id");
}
/// <summary>
/// Prevents a default instance of the <see cref="IntegerIdentifier<T>"/> class from being created.
/// </summary>
private IntegerIdentifier()
{
}
/// <summary>
/// Gets a string representation of the domain the model originated
/// from.
/// </summary>
public string Origin
{
get
{
return this.GetType().Namespace;
}
}
/// <summary>
/// Implements the operator ==.
/// </summary>
/// <param name="integerIdentifier1">The first Model Identifier to
/// compare.</param>
/// <param name="integerIdentifier2">The second Model Identifier to
/// compare.</param>
/// <returns>
/// <c>true</c> if the instances are equal; otherwise
/// <c>false</c> is returned.
/// </returns>
public static bool operator ==(
IntegerIdentifier<T> integerIdentifier1,
IntegerIdentifier<T> integerIdentifier2)
{
return object.Equals(integerIdentifier1, integerIdentifier2);
}
/// <summary>
/// Implements the operator !=.
/// </summary>
/// <param name="integerIdentifier1">The first Model Identifier to
/// compare.</param>
/// <param name="integerIdentifier2">The second Model Identifier to
/// compare.</param>
/// <returns>
/// <c>true</c> if the instances are equal; otherwise
/// <c>false</c> is returned.
/// </returns>
public static bool operator !=(
IntegerIdentifier<T> integerIdentifier1,
IntegerIdentifier<T> integerIdentifier2)
{
return !object.Equals(integerIdentifier1, integerIdentifier2);
}
/// <summary>
/// Determines whether the specified <see cref="T:System.Object"/> is
/// equal to the current <see cref="T:System.Object"/>.
/// </summary>
/// <param name="obj">The <see cref="T:System.Object"/> to compare with
/// the current <see cref="T:System.Object"/>.</param>
/// <returns>true if the specified <see cref="T:System.Object"/> is
/// equal to the current <see cref="T:System.Object"/>; otherwise,
/// false.</returns>
/// <exception cref="T:System.NullReferenceException">The
/// <paramref name="obj"/> parameter is null.</exception>
public override bool Equals(object obj)
{
return this.Equals(obj as IModelIdentifier<T>);
}
/// <summary>
/// Serves as a hash function for a particular type.
/// </summary>
/// <returns>
/// A hash code for the current <see cref="T:System.Object"/>.
/// </returns>
public override int GetHashCode()
{
return this.id.GetHashCode();
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString()
{
return this.id.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// The model instance identifier for the model object that this
/// <see cref="IModelIdentifier{T}"/> refers to. Typically, this is a
/// database key, file name, or some other unique identifier.
/// </summary>
/// <typeparam name="TKeyDataType">The expected data type of the
/// identifier.</typeparam>
/// <returns>The unique key as the data type specified</returns>
public TKeyDataType GetKey<TKeyDataType>()
{
return (TKeyDataType)Convert.ChangeType(
this.id,
typeof(TKeyDataType),
CultureInfo.InvariantCulture);
}
/// <summary>
/// Performs an equality check on the two model identifiers and
/// returns <c>true</c> if they are equal; otherwise <c>false</c>
/// is returned. All implementations must also override the equal
/// operator.
/// </summary>
/// <param name="obj">The identifier to compare against.</param>
/// <returns>
/// <c>true</c> if the identifiers are equal; otherwise
/// <c>false</c> is returned.
/// </returns>
public bool Equals(IModelIdentifier<T> obj)
{
if (obj == null)
{
return false;
}
return obj.GetKey<int>() == this.GetKey<int>();
}
/// <summary>
/// Populates a
/// <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with
/// the data needed to serialize the target object.
/// </summary>
/// <param name="info">The
/// <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to
/// populate with data.</param>
/// <param name="context">The destination (see
/// <see cref="T:System.Runtime.Serialization.StreamingContext"/>) for
/// this serialization.</param>
/// <exception cref="T:System.Security.SecurityException">The caller
/// does not have the required permission. </exception>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public void GetObjectData(
SerializationInfo info,
StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("id", this.id);
}
/// <summary>
/// This method is reserved and should not be used. When implementing
/// the IXmlSerializable interface, you should return null (Nothing in
/// Visual Basic) from this method, and instead, if specifying a custom
/// schema is required, apply the
/// <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"/>
/// to the class.
/// </summary>
/// <returns>
/// An <see cref="T:System.Xml.Schema.XmlSchema"/> that describes the
/// XML representation of the object that is produced by the
/// <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"/>
/// method and consumed by the
/// <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"/>
/// method.
/// </returns>
public XmlSchema GetSchema()
{
return null;
}
/// <summary>
/// Generates an object from its XML representation.
/// </summary>
/// <param name="reader">The <see cref="T:System.Xml.XmlReader"/>
/// stream from which the object is deserialized.</param>
public void ReadXml(XmlReader reader)
{
if (reader != null)
{
this.id = Convert.ToInt32(
reader.GetAttribute("id"),
CultureInfo.InvariantCulture);
}
}
/// <summary>
/// Converts an object into its XML representation.
/// </summary>
/// <param name="writer">The <see cref="T:System.Xml.XmlWriter"/>
/// stream to which the object is serialized.</param>
public void WriteXml(XmlWriter writer)
{
if (writer != null)
{
writer.WriteAttributeString(
"id",
this.id.ToString(CultureInfo.InvariantCulture));
}
}
/// <summary>
/// Generates an object from its string representation.
/// </summary>
/// <param name="value">The value of the model's type.</param>
/// <returns>A new instance of this class as it's interface containing
/// the value from the string.</returns>
internal static IModelIdentifier<T> FromString(string value)
{
int id;
if (int.TryParse(
value,
NumberStyles.None,
CultureInfo.InvariantCulture,
out id))
{
return new IntegerIdentifier<T>(id);
}
return null;
}
/// <summary>
/// Generates an object from its XML representation.
/// </summary>
/// <param name="reader">The <see cref="T:System.Xml.XmlReader"/>
/// stream from which the object is deserialized.</param>
/// <returns>A new instance of this class as it's interface containing
/// the value from the XmlReader.</returns>
internal static IModelIdentifier<T> FromXml(XmlReader reader)
{
if (reader != null)
{
return new IntegerIdentifier<T>(Convert.ToInt32(
reader.GetAttribute("id"),
CultureInfo.InvariantCulture));
}
return null;
}
}
}
은 분명히 그 키가 포함되어있는 정보에 따라 달라집니다. 민감 할 수도 있습니다 (계정 번호 일 가능성이 있음). 어쩌면 제품 ID가 응용 프로그램의 보안 정보가 될 수도 있지만 기본 키라는 사실이 보안 위험을 줄여야하는 이유는 알 수 없습니다.
가능한 복제본 [내 사용자의 데이터베이스 ID를 난독 화해야합니까?] (http://stackoverflow.com/questions/1676012/should-i-be-obfuscating-database-ids-from-my-users) – balpha