new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

OWASP Cheat Sheets · all subjects

application_security/input_validation

168 notes in this subject, read out of this brain and free to use. This is page 1 of 3.

Express.js query string parsing data types by URL structure

JavaScript dynamically parses URL query strings into different types depending on structure: `?foo=bar` becomes string 'bar'; `?foo=bar&foo=baz` becomes array ['bar', 'baz']; `?foo[]=bar` becomes array ['bar']; `?foo[bar]=baz` becomes object {bar: 'baz'}; `?foo[bar][baz]=bar` becomes nested object tree. Input validation must account for these type variations.

Set request size limits by content type in Express

Limit request body size to prevent DoS attacks from exhausting server memory. Use Express middleware with different limits for different content types: `app.use(express.urlencoded({ extended: true, limit: "1kb" }))` and `app.use(express.json({ limit: "1kb" }))`. Note that attackers can change Content-Type headers, so validate the request content against the stated content type before processing if performance permits.

Use new Set() instead of object literals

Developers should use `new Set()` instead of using object literals for list-like collections. Use the `.add()` method to add items and the `.has()` method to check for membership.

Create objects with Object.create(null)

When objects must be used, they should be created using the `Object.create(null)` API to ensure they do not inherit from the Object prototype, preventing prototype pollution attacks.

Use new Map() instead of object literals

Developers should use `new Map()` instead of using object literals for key-value pairs. Use the `.set()` method to set values and the `.get()` method to retrieve values.

Node.js --disable-proto=delete flag

Node.js offers the `--disable-proto=delete` flag to remove the `__proto__` property completely. This is a defense in depth measure that reduces attack surface and prevents certain prototype pollution attacks, though pollution is still possible via `constructor.prototype` properties.

Use __proto__:null in object literals

If object literals are required, use the `__proto__` property set to null as a last resort: `let obj = {__proto__:null};`. This prevents the object from inheriting from the Object prototype.

Use Object.freeze() and Object.seal()

The `Object.freeze()` and `Object.seal()` APIs can prevent built-in prototypes from being modified. However, this may break the application if libraries being used modify built-in prototypes.

SQL Server sp_executesql with bind variables for SQL Injection prevention

Use SQL Server's sp_executesql system stored procedure to run dynamically constructed SQL with bind variables. Declare parameter placeholders using @ParameterName syntax in the SQL string, provide a parameter definition string with all parameter types, then pass the actual values. Example: EXEC sp_executesql @sql, '@UID VARCHAR(20), @DPT VARCHAR(10)', @UID=@UserID, @DPT=@Dept

ASP.NET SqlCommand with SqlParameter for SQL Injection prevention

Use ASP.NET's SqlCommand class with SqlParameter objects to bind user input. Define the query with named parameter placeholders (e.g., @CustomerId), add SqlParameter objects specifying the parameter name and SQL data type, then assign the value. Example: string sql = "SELECT * FROM Customers WHERE CustomerId = @CustomerId"; SqlCommand command = new SqlCommand(sql); command.Parameters.Add(new SqlParameter("@CustomerId", System.Data.SqlDbType.Int)); command.Parameters["@CustomerId"].Value = 1;

SQL Injection is OWASP Top 10 #3 vulnerability as of 2021

SQL Injection is one of the most dangerous web vulnerabilities, ranked #3 on the 2021 OWASP Top 10. It was ranked #1 on both the 2013 and 2017 OWASP Top 10 lists. SQL Injection allows attackers to change the structure of SQL statements to steal data, modify data, or potentially facilitate command injection to the underlying operating system.

Parameterized queries are the primary defense against SQL Injection

Parameterized queries are the best and most common method to prevent SQL Injection vulnerabilities. They work by separating the SQL code structure from user input data, ensuring that user input is always treated as data values, not executable code.

SQL Server Transact-SQL normal stored procedure with parameters for SQL Injection prevention

Create SQL Server stored procedures with typed parameters (e.g., @UserID varchar(20), @Dept varchar(10)) that are naturally bound without requiring special syntax. Example: PROCEDURE SafeGetBalanceQuery(@UserID varchar(20), @Dept varchar(10)) AS BEGIN SELECT balance FROM accounts_table WHERE user_ID = @UserID AND department = @Dept END

Java PreparedStatement for SQL Injection prevention

Use Java's PreparedStatement class with parameterized queries. Create a PreparedStatement with placeholder symbols (?) in the SQL string, then use setString() and other typed setter methods to bind user input to parameters by index. For example: String query = "SELECT account_balance FROM user_data WHERE user_name = ?"; PreparedStatement pstmt = connection.prepareStatement(query); pstmt.setString(1, custname); ResultSet results = pstmt.executeQuery();

SQL Injection prevention requires server-side parameterization

Query parameterization must be performed server-side. Many client-side frameworks and libraries offer client-side query parameterization, but these often just build queries with string concatenation before sending raw queries to the server. Ensure that query parameterization is done server-side to prevent SQL Injection attacks.

Oracle PL/SQL EXECUTE IMMEDIATE with bind variables for SQL Injection prevention

Use Oracle's EXECUTE IMMEDIATE statement to run dynamically constructed SQL with bind variables. Use :1, :2, etc. as placeholders in the SQL string and pass the actual values in the USING clause to ensure inputs are treated as data. Example: stmt := 'SELECT balance FROM accounts_table WHERE user_ID = :1 AND department = :2'; EXECUTE IMMEDIATE stmt INTO result USING UserID, Dept;

Oracle PL/SQL normal stored procedure with parameters for SQL Injection prevention

Create Oracle stored procedures that do not use dynamic SQL. Parameters passed to the procedure are naturally bound to their location in the query without requiring special syntax. Example: PROCEDURE SafeGetBalanceQuery(UserID varchar, Dept varchar) AS BEGIN SELECT balance FROM accounts_table WHERE user_ID = UserID AND department = Dept; END;

Hibernate Criteria API for SQL Injection prevention

Use Hibernate Criteria API to construct parameterized queries programmatically. Use methods like Restrictions.eq() to specify filter conditions with user input safely bound as data. Example: Inventory inv = (Inventory) session.createCriteria(Inventory.class).add(Restrictions.eq("productDescription", userSuppliedParameter)).uniqueResult();

PERL DBI prepared statements for SQL Injection prevention

Use PERL's Database Independent Interface (DBI) with prepare() method to create a prepared statement with ? placeholders, then call execute() with user input values as arguments. Example: my $sql = "INSERT INTO foo (bar, baz) VALUES (?, ?)"; my $sth = $dbh->prepare($sql); $sth->execute($bar, $baz);

.NET OleDbCommand with OleDbParameter for SQL Injection prevention

Use .NET's OleDbCommand class with OleDbParameter to bind user input safely. Define the SQL query with placeholder symbols (?), create an OleDbCommand object, add OleDbParameter objects with the parameter name and user input value. Example: String query = "SELECT account_balance FROM user_data WHERE user_name = ?"; OleDbCommand command = new OleDbCommand(query, connection); command.Parameters.Add(new OleDbParameter("customerName", CustomerName.Text));

Ruby built-in database prepare and execute for SQL Injection prevention

Use Ruby's database prepare() method to create a prepared statement with ? placeholders, then call execute() with the user input values as arguments. Example: insert_new_user = db.prepare "INSERT INTO users (name, age, gender) VALUES (?, ?, ?)"; insert_new_user.execute 'aizatto', '20', 'male';

Ruby ActiveRecord parameterized queries for SQL Injection prevention

Use Ruby on Rails ActiveRecord methods with parameterized syntax. For queries, use conditions with ? placeholders (e.g., Project.all(:conditions => "name = ?", name)) or hash syntax (e.g., Project.all(:conditions => { :name => name })) or named parameters (e.g., Project.where("name = :name", :name => name)). For updates, use update_attributes with hash syntax. For deletes, use delete with hash syntax.

Hibernate HQL with named parameters for SQL Injection prevention

Use Hibernate Query Language (HQL) with @NamedQuery annotation to define parameterized queries. Use named parameters in the query string (e.g., :productDescription) and bind values using setParameter(). Example: @NamedQuery(name="findByDescription", query="FROM Inventory i WHERE i.productDescription = :productDescription") followed by session.getNamedQuery("findByDescription").setParameter("productDescription", userSuppliedParameter).list()

SQL Injection risks in stored procedures with dynamic SQL

SQL injection vulnerabilities can be introduced not only in application code but also in stored procedures that dynamically construct SQL. If stored procedures build SQL statements dynamically without using bind variables, they are vulnerable to SQL Injection. Use bind variables in stored procedures when constructing dynamic SQL.

ColdFusion cfqueryparam for SQL Injection prevention

Use ColdFusion's cfqueryparam tag to bind user input safely in SQL queries. Include cfqueryparam tags in the query with value attribute containing the user input and CFSQLType attribute specifying the SQL data type (e.g., CF_SQL_INTEGER). Example: <cfquery name="getFirst" dataSource="cfsnippets">SELECT * FROM courses WHERE intCourseID = <cfqueryparam value="#intCourseID#" CFSQLType="CF_SQL_INTEGER"></cfquery>

PHP PDO prepared statements with bindParam for SQL Injection prevention

Use PHP Data Objects (PDO) with prepare() method to create a prepared statement with named parameter placeholders (e.g., :name, :value), then use bindParam() to bind user input variables to the parameters by name. Example: $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $stmt->bindParam(':name', $name); $stmt->bindParam(':value', $value);

Rust SQLx macros and bind for SQL Injection prevention

Use Rust's SQLx library with two approaches: compile-time checked macros using sqlx::query_as! macro with ? placeholders (e.g., sqlx::query_as!(User, "SELECT * FROM users WHERE name = ?", username)), or runtime functions using sqlx::query_as::<_, User>() with .bind() method to bind parameters (e.g., sqlx::query_as::<_, User>("SELECT * FROM users WHERE name = ?").bind(&username)).

Rails SQL injection via string concatenation

Do not build SQL queries by concatenating user input directly into WHERE clauses. Vulnerable example: Project.where("name like '" + name + "'"). Safe pattern: Project.where("name like ?", "%#{ActiveRecord::Base.sanitize_sql_like(params[:name])}%").

Rails XSS mitigations for rich text input

If accepting HTML content from users, use a markup language like Markdown or textile instead of raw HTML. If HTML cannot be restricted, implement Content Security Policy to disallow JavaScript execution. Use the #sanitize method to allow only specific tags, but be aware this method has historical flaws and is not a complete solution.

Rails javascript: protocol XSS via link_to href

In older Rails versions, if a URL parameter contains a javascript: protocol (e.g., javascript:alert('Haxored')), the link_to helper will render it as href="javascript:alert('Haxored')", executing JavaScript when clicked. Newer Rails versions escape such links better. Use Content Security Policy to forbid execution of javascript: protocol links.

Rails XSS via redirect_to with user input

Blind redirection to user input parameters can lead to XSS. Example: redirect_to params[:to] with URL http://example.com/redirect?to[protocol]=javascript:alert(0)// executes JavaScript. Use allowlist or static mapping instead.

Rails open redirect prevention with :only_path

Use redirect_to with :only_path option set to true to strip host information and prevent open redirect attacks. However, :only_path must be in the first argument as a hash. Alternatively, validate user input against a whitelist of acceptable URLs or domains using allowlist approach.

Rails dynamic render path vulnerability

Avoid using user input to determine which view or partial to render with the render method. An attacker could cause the application to render arbitrary views such as administrative pages. If user input must influence template selection, restrict to a whitelist of acceptable template names.

Rails command injection methods to avoid

Avoid using eval(), system(), backticks, exec(), spawn(), open() with pipe syntax, Process.exec(), Process.spawn(), IO.binread(), IO.binwrite(), IO.foreach(), IO.popen(), IO.read(), IO.readlines(), and IO.write() with user-controlled input. If these must be used, apply an allowlist of possible values and validate input thoroughly.

Rails allowlist approach for open redirects

Instead of validating user input, use a static hash mapping user input keys to approved URLs: ACCEPTABLE_URLS = {'our_app_1' => 'https://www.example.com/checkout', 'our_app_2' => 'https://www.example.com/settings'}. Then redirect only if the key exists in the hash.

Rails open redirect via host and scheme manipulation

When validating redirect URLs using URI.parse(), check not only the host but also the scheme and port. Example attack: javascript://trusted.com/%0Aalert(0) bypasses host-only validation.

Rails unsafe output escaping methods to avoid

Do not use raw(), html_safe(), or <%== %> in Rails ERB templates to output user-controlled content. These methods bypass HTML escaping and create XSS vulnerabilities. The html_safe() method is confusingly named—it does not make content safe, it only marks content as safe for inclusion in HTML without escaping.

HTTP method allowlist restriction

Apply an allowlist of permitted HTTP Methods (e.g. `GET`, `POST`, `PUT`). Reject all requests not matching the allowlist with HTTP response code `405 Method Not Allowed`. Make sure the caller is authorized to use the incoming HTTP method on the resource collection, action, and record.

Access control at each REST endpoint

Non-public REST services must perform access control at each API endpoint. The access control decision should be taken locally by REST endpoints to minimize latency and reduce coupling between services. User authentication should be centralized in an Identity Provider that issues access tokens.

Workflow state validation prevents out-of-order API execution

Enforce workflow state validation on the server side for every request. Model workflows explicitly using finite states or state machines. Bind tokens or identifiers to specific workflow stages. Avoid relying on frontend logic to enforce sequencing. Reject invalid or out-of-order transitions with clear error responses. This prevents attackers from skipping required workflow steps.

Request content type validation

Reject requests containing unexpected or missing content type headers with HTTP response status `406 Unacceptable` or `415 Unsupported Media Type`. For requests with `Content-Length: 0` however, a `Content-type` header is optional. For XML content types ensure appropriate XML parser hardening. Avoid accidentally exposing unintended content types by explicitly defining content types (e.g. Jersey Java `@consumes("application/json"); @produces("application/json")`).

XXE protection in XML parsing

Use a secure parser for parsing incoming messages. If using XML, ensure the parser is not vulnerable to XXE (XML External Entity) attacks and similar attacks.

Input validation requirements for REST APIs

Do not trust input parameters/objects. Validate input for length, range, format and type. Achieve implicit input validation by using strong types like numbers, booleans, dates, times or fixed data ranges in API parameters. Constrain string inputs with regexps. Reject unexpected/illegal content. Make use of validation/sanitation libraries or frameworks. Define an appropriate request size limit and reject requests exceeding the limit with HTTP response status `413 Request Entity Too Large`. Consider logging input validation failures.

Least Privilege: Use views to limit table access

If an account only needs access to portions of a table, create a view that limits access to that portion of the data and assign the account access to the view instead of the underlying table. When using stored procedures exclusively, restrict database accounts to only execute the stored procedures they need without any direct rights to tables.

Additional defense: Least Privilege for database accounts

Minimize privileges assigned to every database account in the environment. Start from the ground up determining what access rights are required rather than removing access rights. Accounts needing only read access should only have read access to tables they need. Do not assign DBA or admin-type access to application accounts.

Primary defense: STRONGLY DISCOURAGED - Escaping User-Supplied Input

Escaping all user input before putting it in a query is very database-specific in implementation and is fragile compared to other defenses. This option cannot guarantee prevention of all SQL injections in all situations. If building an application from scratch or requiring low risk tolerance, use parameterized queries, stored procedures, or an ORM instead.

Sort order safe dynamic SQL generation

public String someMethod(boolean sortOrder) { String SQLquery = "some SQL ... order by Salary " + (sortOrder ? "ASC" : "DESC"); } Convert user input to non-String types (date, numeric, boolean, enumerated type) before appending to a query or using to select a value to append. This ensures it is safe to do so.

Primary defense: Allow-list Input Validation

Allow-list input validation is appropriate when parts of SQL queries cannot use bind variables, such as table names, column names, or sort order indicators (ASC or DESC). Map parameter values to legal/expected table or column names to ensure unvalidated user input doesn't end up in the query.

VB .NET SqlCommand stored procedure example

Try Dim command As SqlCommand = new SqlCommand("sp_getAccountBalance", connection) command.CommandType = CommandType.StoredProcedure command.Parameters.Add(new SqlParameter("@CustomerName", CustomerName.Text)) Dim reader As SqlDataReader = command.ExecuteReader() Catch se As SqlException 'error handling End Try

Java CallableStatement stored procedure example

String custname = request.getParameter("customerName"); try { CallableStatement cs = connection.prepareCall("{call sp_getAccountBalance(?)}"); cs.setString(1, custname); ResultSet results = cs.executeQuery(); } catch (SQLException se) { // logging and error handling }

Stored procedure security risk: MS SQL Server default roles

On MS SQL Server, the three main default roles are db_datareader, db_datawriter, and db_owner. If user management is centralized to only these roles, web apps may have to run as db_owner to execute stored procedures (since execute rights are not available by default). If a server is breached, the attacker gains full database rights instead of limited read-access.

Primary defense: Stored Procedures

Stored procedures are equally effective to prepared statements at preventing SQL injection when implemented safely. The SQL code for a stored procedure is defined and stored in the database itself, then called from the application. Safe stored procedures use parameterization; unsafe ones include dynamic SQL generation without proper escaping.

Hibernate Query Language (HQL) prepared statement with named parameters

Query safeHQLQuery = session.createQuery("from Inventory where productID=:productid"); safeHQLQuery.setParameter("productid", userSuppliedParameter); This is the safe version. Avoid unsafe HQL: Query unsafeHQLQuery = session.createQuery("from Inventory where productID='"+userSuppliedParameter+"'");

Safe table name validation using switch statement

String tableName; switch(PARAM): case "Value1": tableName = "fooTable"; break; case "Value2": tableName = "barTable"; break; default : throw new InputValidationException("unexpected value provided for table name");

C# .NET PreparedStatement example for SQL injection prevention

String query = "SELECT account_balance FROM user_data WHERE user_name = ?"; try { OleDbCommand command = new OleDbCommand(query, connection); command.Parameters.Add(new OleDbParameter("customerName", CustomerName Name.Text)); OleDbDataReader reader = command.ExecuteReader(); } catch (OleDbException se) { // error handling }

Java PreparedStatement example for SQL injection prevention

String custname = request.getParameter("customerName"); String query = "SELECT account_balance FROM user_data WHERE user_name = ? "; PreparedStatement pstmt = connection.prepareStatement( query ); pstmt.setString( 1, custname); ResultSet results = pstmt.executeQuery( );

Primary defense: Prepared Statements with Parameterized Queries

Prepared statements (parameterized queries) force the developer to define all SQL code first and pass in each parameter separately to the query later. The database always distinguishes between code and data regardless of user input, and attackers cannot change the intent of a query even if SQL commands are inserted.

Least Privilege: Minimize OS privileges for DBMS process

Minimize privileges of the operating system account that the DBMS runs under. Do not run the DBMS as root or system. For example, MySQL runs as system on Windows by default - change the DBMS's OS account to something more appropriate with restricted privileges.

SQL Injection definition and attack vector

SQL Injection attacks occur when an application uses dynamic database queries that use string concatenation with user-supplied input. Attackers can enter SQL code into query parameters, and the application executes the attacker's code on the database.

Least Privilege: Separate database users per application

Use different database users for different web applications instead of the same owner/admin account. Each separate web application requiring database access should have a designated database user account. This provides good granularity in access control and reduces privileges as much as possible. For example, a login page needs only select access to username and password fields, while a sign-up page needs insert privilege - different DB users can enforce this restriction.

Give your agent this brain