what security measures should be taken when creating/updating/retrieving entities with data from users' form submissions? We have webforms for authenticated users (anyone can create an account without admin approval) to fill out.  With their submission data I'm using the civicrm_api to create contacts and relationships.

For example:

// in hook_webform_submission_insert I do this:
$newcontact= civicrm_api3('Contact', 'create', array(
  'sequential' =&gt; 1,
  'contact_type' =&gt; 'Organization',
  'contact_sub_type' =&gt; 'Sub_Type',
  'organization_name' =&gt; $submission-&gt;data[20][0],
));


Is there any filtering I should be doing or are Drupal's security measures sufficient?

There are various hooks I could use.  Currently I'm using a combination of hook_form_alter with submit callbacks and hook_webform_submission_insert.  Would one of these or some other hook have significantly greater security measures?
Designers need to worry about two things, making sure that user-supplied data can go into the database successfully, and also that data pulled from the database can be written to the page successfully.

When adding data to the database, Drupal will use prepared statements to ensure the SQL injection does not occur. What this means is, Drupal will tell the database, "Expect to see an INSERT command that looks like {statement}." and then sends all the data. If the resulting statements does not match, there will be an error.

Drupal Fields are defined such that the system knows how the data in that field should be displayed. The database schema guarantees that only a certain data format is available. For example, if the field is a number, we know we won't get a string because the database is designed to only record numbers. Drupal can just worry about formatting it properly. Same if it's text, it will make sure that it is not displaying a URL by passing the text through check_plain() after retrieving the data from the database.

In your case, you are going to be inserting this user-supplied data into the database. The Drupal Field API should be ensuring that the data is of the correct type for the database, and that it is not too long, or improperly formatted before inserting the record. It will insert it using the prepared statement to prevent SQL injection. So, you should be fine.

Make sure you read the CiviCRM secure coding guide:
https://docs.civicrm.org/dev/en/latest/security/