API は、呼び出し元と呼び出し先の間のコントラクトです。最も一般的な API の不正使用の形態は、呼び出し元がこのコントラクトの終わりを守らないことによって発生します。たとえば、プログラムが chroot() を呼び出した後に chdir() を呼び出すのに失敗すると、アクティブなルート ディレクトリを安全に変更する方法を指定したコントラクトに違反することになります。ライブラリの悪用のもう 1 つの良い例は、呼び出し先が信頼できる DNS 情報を呼び出し元に返すことを期待することです。この場合、呼び出し元は、呼び出し先の API の動作 (戻り値が認証目的に使用できること) についてある種の仮定をすることで、呼び出し先の API を悪用します。また、相手側から、呼び出し元と呼び出し先のコントラクトを違反することもできます。例えば、コーダーが SecureRandom をサブクラス化し、ランダムではない値を返した場合、コントラクトに違反することになります。
private
および final
と宣言し、Set を変更するメソッドを誤って作成しています。
@Immutable
public final class ThreeStooges {
private final Set stooges = new HashSet>();
...
public void addStooge(String name) {
stooges.add(name);
}
...
}
final
ではありません。Immutable
が付けられています。final 以外のフィールドは、値が変更されるのを許可するため、クラスの不変性が侵害されます。final
と宣言するのではなく、誤って public
に宣言しています。
@Immutable
public class ImmutableInteger {
public int value;
}
public
および final
と宣言しています。
@Immutable
public final class ThreeStooges {
public final Set stooges = new HashSet();
...
}
ctx = new InitialContext();
datasource = (DataSource)ctx.lookup(DB_DATASRC_REF);
conn = datasource.getConnection();
conn = DriverManager.getConnection(CONNECT_STRING);
--auto-tls
フラグを true
に設定します。その結果、etcd インスタンスは、クライアントとの TLS 接続に自己署名証明書を使用します。
...
spec:
containers:
- command:
...
- etcd
...
- --auto-tls=true
...
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; }
...
}
null
を戻すことがある関数の戻り値を確認しないため、NULL ポインタを間接参照する場合があります。Item
プロパティによって戻される文字列が null
かどうかを、メンバー関数 Equals()
をコールする前にチェックしないので、null
Dereference の原因になる可能性があります。
string itemName = request.Item(ITEM_NAME);
if (itemName.Equals(IMPORTANT_ITEM)) {
...
}
...
null
値を間接参照してプログラムが異常終了するのにまかせても同じことです。」null
を返すことがある関数の戻り値を確認しないため、NULL ポインタを間接参照する場合があります。malloc()
で戻されたポインタを使用する前に、メモリの割り当てが正しく行われたかチェックしていません。
buf = (char*) malloc(req_size);
strncpy(buf, xfer, req_size);
malloc()
のコールが失敗に終わった理由が、req_size
の超過によるものか、許容範囲外の同時処理によるものか定かではありません。時間の経過とともに蓄積された Memory Leak によるものかも不明です。エラー処理を怠ると、原因を究明する術はありません。null
を返すことがある関数の戻り値を確認しないため、NULL ポインタを間接参照する場合があります。getParameter()
によって戻される文字列が null
かどうかを、メンバー関数 compareTo()
をコールする前にチェックしないので、null
Dereference の原因になる可能性があります。例 2:次のコードは、
String itemName = request.getParameter(ITEM_NAME);
if (itemName.compareTo(IMPORTANT_ITEM)) {
...
}
...
null
に設定され、それが「常に定義される」という誤った前提でプログラマによって後から間接参照されるシステムプロパティを示します。
System.clearProperty("os.name");
...
String os = System.getProperty("os.name");
if (os.equalsIgnoreCase("Windows 95") )
System.out.println("Not supported");
null
値を間接参照してプログラムが異常終了するのにまかせても同じことです。」null
と比較しなくてはならないという規約に違反しています。Object.equals()
、Comparable.compareTo()
、または Comparator.compare()
の実装のパラメーターが null
である場合には特定の値を返さなくてはならないと定めています。この規約に違反すると、予期せぬ動作が引き起こされる可能性があります。equals()
メソッドの実装では、パラメーターと null
との比較をしていません。
public boolean equals(Object object)
{
return (toString().equals(object.toString()));
}
clone()
メソッドは新規オブジェクトを取得するために super.clone()
をコールします。clone()
のすべての実装は super.clone()
をコールして新規オブジェクトを取得します。クラスがこの規定に従わない場合、サブクラスの clone()
メソッドは不正なタイプのオブジェクトを出力します。super.clone()
のコールをしなかったことが原因で発生したバグを示すものです。Kibitzer
が clone()
を実装する方法のため、FancyKibitzer
の clone メソッドはタイプ FancyKibitzer
ではなく、タイプ Kibitzer
のオブジェクトを返します。
public class Kibitzer implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Object returnMe = new Kibitzer();
...
}
}
public class FancyKibitzer extends Kibitzer
implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Object returnMe = super.clone();
...
}
}
Equals()
と GetHashCode()
のいずれかひとつを定義します。a.Equals(b) == true
の場合は a.GetHashCode() == b.GetHashCode()
です。 Equals()
を上書きしますが、GetHashCode()
は上書きしません。
public class Halfway() {
public override boolean Equals(object obj) {
...
}
}
equals()
と hashCode()
のいずれかひとつを定義します。a.equals(b) == true
の場合は a.hashCode() == b.hashCode()
です。 equals()
を上書きしますが、hashCode()
は上書きしません。
public class halfway() {
public boolean equals(Object obj) {
...
}
}
saveState()
と restoreState()
のいずれかひとつを定義します。saveState(javax.faces.context.FacesContext)
と restoreState(javax.faces.context.FacesContext, java.lang.Object)
の両方を実装するか、どちらも実装しないかのいずれかでなければなりません。これら 2 つのメソッドは密結合の関係にあるため、saveState(javax.faces.context.FacesContext)
と restoreState(javax.faces.context.FacesContext, java.lang.Object)
の各メソッドが継承階層の異なるレベルに存在することは許されません。restoreState()
ではなく saveState()
を定義しています。したがって、拡張するクラスがどのような操作をしたとしても常にエラーとなります。
public class KibitzState implements StateHolder {
public Object saveState(FacesContext fc) {
...
}
}
checkCallingOrSelfPermission()
または checkCallingOrSelfUriPermission()
は、呼び出しプログラムが特定のサービスまたは特定の URI にアクセスするのに必要な権限を持っているかどうかを判定します。しかし、これらの関数は、適切な権限が欠けている悪意のあるアプリケーションに、ご使用のアプリケーションの権限で代用させて、アクセスを許可する可能性があるため、注意深く使用する必要があります。Assert()
を特定の権限で使用する場合、現在の制御フローで権限が指定されていることになります。次にこれによって .NET Framework で必要な権限が満たされている限り追加の権限チェックは停止されます。つまり、Assert()
へのコールを行うコードをコールするコードに必要な権限がない場合があるということです。Assert()
の使用は場合によっては有用ですが、これによって悪意のあるユーザーが権限を持たないリソースを制御できるようになる場合は脆弱性となる可能性があります。
IPAddress hostIPAddress = IPAddress.Parse(RemoteIpAddress);
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress);
if (hostInfo.HostName.EndsWith("trustme.com")) {
trusted = true;
}
getlogin()
関数を偽装するのは簡単です。このため、関数によって戻された名前を信頼しないようにします。getlogin()
関数は、ターミナルで現在ログオン中のユーザー名を含む文字列を戻しますが、攻撃者は getlogin()
を操作し、そのマシンにログオンした任意のユーザー名を戻すことができます。このため、セキュリティに関する決定を行う際に、getlogin()
関数によって戻された名前を信頼しないようにします。getlogin()
の結果を信頼し、信頼できるユーザーかどうかを判断しています。しかし、これは全く当てになりません。
pwd = getpwnam(getlogin());
if (isTrustedGroup(pwd->pw_gid)) {
allow();
} else {
deny();
}
String ip = request.getRemoteAddr();
InetAddress addr = InetAddress.getByName(ip);
if (addr.getCanonicalHostName().endsWith("trustme.com")) {
trusted = true;
}
Boolean.getBoolean()
は、しばしば Boolean.valueOf()
または Boolean.parseBoolean()
のメソッド呼び出しと混同されます。Boolean.getBoolean()
を呼び出す際は、指定した文字列引数で表現されるブール値が戻されるものと誤解されて使用されています。しかし、Javadoc で説明されているように、Boolean.getBoolean(String)
メソッドは「引数で指定されたシステム プロパティが存在し、しかもそれが文字列 'true' に等しい場合にのみ、true を返す」のです。Boolean.valueOf(String)
または Boolean.parseBoolean(String)
の呼び出しです。Boolean.getBoolean(String)
では String プリミティブを解釈しないため、"FALSE" がプリントされます。解釈されるのはシステムプロパティのみです。
...
String isValid = "true";
if ( Boolean.getBoolean(isValid) ) {
System.out.println("TRUE");
}
else {
System.out.println("FALSE");
}
...
Decoder
および Encoding
クラスの GetChars
メソッドと Encoder
および Encoding
クラスの GetBytes
メソッドは、char および byte 配列に対して内部的にポインタ算術を実行し、文字の範囲をバイトの範囲に (およびその逆に) 変換します。
out.println("x = " + encoder.encodeForJavaScript(input) + ";");
...
unichar ellipsis = 0x2026;
NSString *myString = [NSString stringWithFormat:@"My Test String%C", ellipsis];
NSData *asciiData = [myString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *asciiString = [[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding];
NSLog(@"Original: %@ (length %d)", myString, [myString length]);
NSLog(@"Best-fit-mapped: %@ (length %d)", asciiString, [asciiString length]);
// output:
// Original: My Test String... (length 15)
// Best-fit-mapped: My Test String... (length 17)
...
...
let ellipsis = 0x2026;
let myString = NSString(format:"My Test String %C", ellipsis)
let asciiData = myString.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion:true)
let asciiString = NSString(data:asciiData!, encoding:NSASCIIStringEncoding)
NSLog("Original: %@ (length %d)", myString, myString.length)
NSLog("Best-fit-mapped: %@ (length %d)", asciiString!, asciiString!.length)
// output:
// Original: My Test String ... (length 16)
// Best-fit-mapped: My Test String ... (length 18)
...