API は、呼び出し元と呼び出し先の間のコントラクトです。最も一般的な API の不正使用の形態は、呼び出し元がこのコントラクトの終わりを守らないことによって発生します。たとえば、プログラムが chroot() を呼び出した後に chdir() を呼び出すのに失敗すると、アクティブなルート ディレクトリを安全に変更する方法を指定したコントラクトに違反することになります。ライブラリの悪用のもう 1 つの良い例は、呼び出し先が信頼できる DNS 情報を呼び出し元に返すことを期待することです。この場合、呼び出し元は、呼び出し先の API の動作 (戻り値が認証目的に使用できること) についてある種の仮定をすることで、呼び出し先の API を悪用します。また、相手側から、呼び出し元と呼び出し先のコントラクトを違反することもできます。例えば、コーダーが SecureRandom をサブクラス化し、ランダムではない値を返した場合、コントラクトに違反することになります。
[Required]
属性でマークされた) プロパティとオプションの ([Required]
属性でマークされていない) プロパティを持つモデルクラスは、攻撃者が想定以上のデータを含む要求を送信した場合に問題を引き起こす可能性があります。[Required]
を含むプロパティと [Required]
を含まないプロパティがあります。
public class MyModel
{
[Required]
public String UserName { get; set; }
[Required]
public String Password { get; set; }
public Boolean IsAdmin { get; set; }
}
[Required]
属性でマークされた) non-nullable プロパティを持つモデルクラスを使用すると、攻撃者から想定より少ないデータを含んでいるリクエストが送信された場合に問題を引き起こす可能性があります。[Required]
検証属性を満たします。この場合、アプリケーションが不測の挙動を起こします。
public enum ArgumentOptions
{
OptionA = 1,
OptionB = 2
}
public class Model
{
[Required]
public String Argument { get; set; }
[Required]
public ArgumentOptions Rounding { get; set; }
}
[Required]
属性なしのプロパティが含まれる場合、攻撃者がそのサブモデルを送信しないと、親プロパティには null
値が与えられ、子モデルの必須フィールドはモデル検証によってアサートされません。これは under-posting 攻撃の 1 つの形態です。
public class ChildModel
{
public ChildModel()
{
}
[Required]
public String RequiredProperty { get; set; }
}
public class ParentModel
{
public ParentModel()
{
}
public ChildModel Child { get; set; }
}
ParentModel.Child
プロパティの値を送信しない場合、ChildModel.RequiredProperty
プロパティにはアサートされない [Required]
が与えられます。この場合、問題となる不測の結果が生じる可能性があります。RegisterModel
または Details
クラス内の属性にバインドします。
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
try
{
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", "");
}
}
return View(model);
}
RegisterModel
クラスは次のように定義されます。
public class RegisterModel
{
[BindRequired]
[Display(Name = "User name")]
public string UserName { get; set; }
[BindRequired]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
public Details Details { get; set; }
public RegisterModel()
{
Details = new Details();
}
}
Details
クラスは次のように定義されます。例 2:
public class Details
{
public bool IsAdmin { get; set; }
...
}
TryUpdateModel()
または UpdateModel()
を ASP.NET MVC または Web API アプリケーションで使用するとき、モデル バインダーはデフォルトで、自動的にすべての HTTP リクエスト パラメーターをバインドするように試みます。例 3: ASP.NET Web Form アプリケーションでは、モデル バインダーは、IValueProvider インターフェイスで
public ViewResult Register()
{
var model = new RegisterModel();
TryUpdateModel<RegisterModel>(model);
return View("detail", model);
}
TryUpdateModel()
または UpdateModel()
を使用する際にすべての HTTP リクエスト パラメーターを自動的にバインドしようとします。
Employee emp = new Employee();
TryUpdateModel(emp, new System.Web.ModelBinding.FormValueProvider(ModelBindingExecutionContext));
if (ModelState.IsValid)
{
db.SaveChanges();
}
Employee
クラスは次のように定義されます。
public class Employee
{
public Employee()
{
IsAdmin = false;
IsManager = false;
}
public string Name { get; set; }
public string Email { get; set; }
public bool IsManager { get; set; }
public bool IsAdmin { get; set; }
}
Booking
クラスの任意の属性にバインドします。
<view-state id="enterBookingDetails" model="booking">
<on-render>
<render fragments="body" />
</on-render>
<transition on="proceed" to="reviewBooking">
</transition>
<transition on="cancel" to="cancel" bind="false" />
</view-state>
Booking
クラスは次のように定義されます。
public class Booking implements Serializable {
private Long id;
private User user;
private Hotel hotel;
private Date checkinDate;
private Date checkoutDate;
private String creditCard;
private String creditCardName;
private int creditCardExpiryMonth;
private int creditCardExpiryYear;
private boolean smoking;
private int beds;
private Set<Amenity> amenities;
// Public Getters and Setters
...
}
Order
、Customer
、および Profile
は、Microsoft .NET Entity の永続的なクラスです。
public class Order {
public string ordered { get; set; }
public List<LineItem> LineItems { get; set; }
pubilc virtual Customer Customer { get; set; }
...
}
public class Customer {
public int CustomerId { get; set; }
...
public virtual Profile Profile { get; set; }
...
}
public class Profile {
public int profileId { get; set; }
public string username { get; set; }
public string password { get; set; }
...
}
OrderController
は、リクエストを処理する ASP.NET MVC コントローラーのクラスです。
public class OrderController : Controller{
StoreEntities db = new StoreEntities();
...
public String updateOrder(Order order) {
...
db.Orders.Add(order);
db.SaveChanges();
}
}
Order
、Customer
、および Profile
は、Hibernate の永続的なクラスです。
public class Order {
String ordered;
List lineItems;
Customer cust;
...
}
public class Customer {
String customerId;
...
Profile p;
...
}
public class Profile {
String profileId;
String username;
String password;
...
}
OrderController
は、リクエストを処理する Spring コントローラのクラスです。
@Controller
public class OrderController {
...
@RequestMapping("/updateOrder")
public String updateOrder(Order order) {
...
session.save(order);
}
}
[FromBody]
アノテーションが使用されている場合は入力フォーマッタに依存します。[FromBody]
アノテーションがアクションの複合パラメーターに適用されると、パラメーターの型またはいずれかのフィールドに適用される [Bind]
や [BindNever]
などのその他のバインディング属性は事実上無視されるため、バインディング アノテーションを使用した緩和策は不可能になります。[FromBody]
アノテーションがアクションのパラメーターに適用されると、モデル バインダーは入力フォーマッタを使用してリクエストの本文で指定されたすべてのパラメーターを自動的にバインドしようとします。デフォルトでは、バインダーは JSON 入力フォーマッタを使用して、リクエストの本文から取得できるすべてのパラメーターをバインドしようとします。
[HttpPost]
public ActionResult Create([FromBody] Product p)
{
return View(p.Name);
}
[FromBody]
アノテーションが存在する場合は入力フォーマッタが使用されるため、後続の Product
型に適用される [Bind]
や [BindNever]
などのバインディング アノテーションは無視されることに注意してください。
public class Product
{
...
public string Name { get; set; }
public bool IsAdmin { get; set; }
...
}