Un API es un contrato entre un autor de llamada y un receptor de llamada. Las formas de abuso de API más comunes los produce el autor de llamada cuando no consigue atender su fin de este contrato. Por ejemplo, si un programa no consigue llamar chdir() después de llamar chroot(), se viola el contrato que especifica cómo cambiar el directorio de origen activo de una forma segura. Otro buen ejemplo de un abuso de manual es esperar que el receptor devuelva una información de DNS de confianza al autor de llamada. En este caso, el autor de llamada abusa el API del receptor haciendo determinadas suposiciones sobre su comportamiento (que el valor de retorno se puede usar con fines de autenticación). También se puede violar el contrato entre el autor de llamada y el receptor desde el otro lado. Por ejemplo, si un codificador envía SecureRandom y devuelve un valor no aleatorio, se viola el contrato.
private
y final
y, a continuación, crea erróneamente un método que modifica el Set.
@Immutable
public final class ThreeStooges {
private final Set stooges = new HashSet>();
...
public void addStooge(String name) {
stooges.add(name);
}
...
}
final
.Immutable
, desde el paquete de anotaciones de JCIP. Un campo no final infringe la inmutabilidad de la clase al permitir la modificación del valor.public
y no final
.
@Immutable
public class ImmutableInteger {
public int value;
}
public
y 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
en true
. Como resultado, la instancia etcd usa certificados autofirmados para las conexiones TLS con los clientes.
...
spec:
containers:
- command:
...
- etcd
...
- --auto-tls=true
...
RegisterModel
o Details
:
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
try
{
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", "");
}
}
return View(model);
}
RegisterModel
se define como:
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
se define como:Ejemplo 2: Al utilizar
public class Details
{
public bool IsAdmin { get; set; }
...
}
TryUpdateModel()
o UpdateModel()
en ASP.NET MVC o aplicaciones web API, el enlazador de modelos intentará enlazar automáticamente todos los parámetros de solicitud HTTP de forma predeterminada:Ejemplo 3: En las aplicaciones de formulario web ASP.NET, el enlazador de modelos intentará enlazar automáticamente todos los parámetros de solicitud HTTP cuando se utilice
public ViewResult Register()
{
var model = new RegisterModel();
TryUpdateModel<RegisterModel>(model);
return View("detail", model);
}
TryUpdateModel()
o UpdateModel()
con la interfaz IValueProvider.
Employee emp = new Employee();
TryUpdateModel(emp, new System.Web.ModelBinding.FormValueProvider(ModelBindingExecutionContext));
if (ModelState.IsValid)
{
db.SaveChanges();
}
Employee
se define como:
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
se define como:
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
y Profile
son clases persistentes de 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
es la clase controlador MVC de ASP.NET que trata la solicitud:
public class OrderController : Controller{
StoreEntities db = new StoreEntities();
...
public String updateOrder(Order order) {
...
db.Orders.Add(order);
db.SaveChanges();
}
}
Order
, Customer
y Profile
son clases Hibernate persistentes.
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
es la clase de controlador que administra la solicitud:
@Controller
public class OrderController {
...
@RequestMapping("/updateOrder")
public String updateOrder(Order order) {
...
session.save(order);
}
}
[FromBody]
.[FromBody]
se aplica a un parámetro complejo de una acción, y después a cualquier otro atributo vinculante, como [Bind]
o [BindNever]
aplicados al tipo de parámetro o cualquiera de sus campos se ignoran efectivamente, lo que significa que la mitigación mediante anotaciones vinculantes es imposible.[FromBody]
se aplica a un parámetro de una acción, el enlazador de modelos intenta vincular automáticamente todos los parámetros especificados en el cuerpo de la solicitud mediante un formateador de entrada. De forma predeterminada, el enlazador utiliza el formateador de entrada JSON para intentar vincular todos los parámetros posibles que provienen del cuerpo de la solicitud:
[HttpPost]
public ActionResult Create([FromBody] Product p)
{
return View(p.Name);
}
[Bind]
o [BindNever]
aplicada al tipo Product
que sigue se ignoran debido a que se utilizan formateadores de entrada cuando la anotación [FromBody]
está presente.
public class Product
{
...
public string Name { get; set; }
public bool IsAdmin { get; set; }
...
}
null
.Item
es null
antes de llamar a la función miembro Equals()
, lo que podría provocar una eliminación de referencia de un valor null
.
string itemName = request.Item(ITEM_NAME);
if (itemName.Equals(IMPORTANT_ITEM)) {
...
}
...
null
".null
.malloc()
.
buf = (char*) malloc(req_size);
strncpy(buf, xfer, req_size);
malloc()
presentó errores debido a que req_size
era demasiado grande o a que se estaban administrando demasiadas solicitudes al mismo tiempo? ¿O el error lo provocó una pérdida de memoria que se acumuló a lo largo de un periodo? Si no se administra el error, es imposible saberlo.null
.getParameter()
es null
antes de llamar a la función miembro compareTo()
, lo que podría provocar una desreferencia de null
.Ejemplo 2:. en el siguiente código se muestra una propiedad del sistema que se establece en un valor
String itemName = request.getParameter(ITEM_NAME);
if (itemName.compareTo(IMPORTANT_ITEM)) {
...
}
...
null
y un programador elimina posteriormente su referencia al presuponer de forma incorrecta que siempre está definida.
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()
y Comparator.compare()
devuelvan un valor especificado si sus parámetros son null
. De no cumplir el contrato se daría lugar a un comportamiento inesperado.equals()
no compara su parámetro con null
.
public boolean equals(Object object)
{
return (toString().equals(object.toString()));
}
clone()
debe llamar super.clone()
para obtener el nuevo objeto.clone()
deben obtener el nuevo objeto llamando super.clone()
. Si una clase no puede seguir esta convención, un método clone()
de subclase devolverá un objeto del tipo incorrecto.super.clone()
. Dada la forma en que Kibitzer
implementa clone()
, el método de clonación de FancyKibitzer
devolverá un objeto de tipo Kibitzer
en lugar de FancyKibitzer
.
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()
y GetHashCode()
.a.Equals(b) == true
, entonces a.GetHashCode() == b.GetHashCode()
. Equals()
pero no GetHashCode()
.
public class Halfway() {
public override boolean Equals(object obj) {
...
}
}
equals()
y hashCode()
.a.equals(b) == true
, entonces a.hashCode() == b.hashCode()
. equals()
pero no hashCode()
.
public class halfway() {
public boolean equals(Object obj) {
...
}
}
saveState()
y restoreState()
.saveState(javax.faces.context.FacesContext)
como restoreState(javax.faces.context.FacesContext, java.lang.Object)
, o no implementar ninguna de ellos. Como estos dos métodos tienen una relación estrecha, no se pueden tener los métodos saveState(javax.faces.context.FacesContext)
y restoreState(javax.faces.context.FacesContext, java.lang.Object)
residiendo en diferentes niveles de la jerarquía de herencia.saveState()
y no restoreState()
, de forma que siempre está equivocada, independientemente de lo que pueda hacer cualquier clase
public class KibitzState implements StateHolder {
public Object saveState(FacesContext fc) {
...
}
}
checkCallingOrSelfPermission()
o checkCallingOrSelfUriPermission()
determina si el programa que realiza la llamada cuenta con el permiso necesario para acceder a determinado servicio o URI. Sin embargo, estas funciones deben utilizarse con cuidado, ya que pueden conceder acceso a aplicaciones malintencionadas, que carecen de los permisos correspondientes, adoptando los permisos de las aplicaciones.Assert()
con un permiso concreto, es una forma de decir que el flujo de control actual tiene el permiso especificado. Esto provoca que .NET Framework detenga cualquier comprobación de permisos adicional, siempre y cuando se hayan satisfecho los permisos necesarios, por lo que el código que llama al código que realiza la llamada a Assert()
podría no tener el permiso requerido. Usar Assert()
es útil en ciertos casos, pero puede dar lugar a vulnerabilidades cuando permite que un usuario malintencionado tome el control de un recurso que no tendría derecho a controlar de otro modo.
IPAddress hostIPAddress = IPAddress.Parse(RemoteIpAddress);
IPHostEntry hostInfo = Dns.GetHostByAddress(hostIPAddress);
if (hostInfo.HostName.EndsWith("trustme.com")) {
trusted = true;
}
getlogin()
es fácil de reemplazar. Por eso, no confíe en el nombre que devuelva.getlogin()
devuelve una cadena que contiene el nombre del usuario registrado actualmente en el terminal. Sin embargo, un atacante podría hacer que getlogin()
devuelva el nombre de todos los usuarios registrado en el equipo. No confíe en el nombre devuelto por getlogin()
cuando tome decisiones relacionadas con la seguridad.getlogin()
para determinar si un usuario es de confianza o no. Es fácil de subvertir.
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()
se confunde a menudo con las llamadas a métodos Boolean.valueOf()
o Boolean.parseBoolean()
.Boolean.getBoolean()
se usa a menudo incorrectamente, ya que se presupone que devuelve el valor booleano representado por el argumento de cadena especificado. Sin embargo, como se indica en el método Boolean.getBoolean(String)
de Javadoc: "Devuelve el valor 'true' solo si existe la propiedad del sistema a la que el argumento ha asignado un nombre y esta es igual a la cadena 'true'".Boolean.valueOf(String)
o Boolean.parseBoolean(String)
.Boolean.getBoolean(String)
no convierte un primitivo de cadena, sino únicamente la propiedad del sistema.
...
String isValid = "true";
if ( Boolean.getBoolean(isValid) ) {
System.out.println("TRUE");
}
else {
System.out.println("FALSE");
}
...
GetChars
en las clases Decoder
y Encoding
, y el método GetBytes
en las clases Encoder
y Encoding
de .NET Framework llevan a cabo aritmética de puntero de forma interna en las matrices de caracteres y bytes para convertir un intervalo de caracteres en un intervalo de bytes y viceversa.
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)
...