Home > Store

The CERT C Secure Coding Standard

Register your product to gain access to bonus material or receive a coupon.

The CERT C Secure Coding Standard

eBook

  • Your Price: $46.39
  • List Price: $57.99
  • Includes EPUB and PDF
  • About eBook Formats
  • This eBook includes the following formats, accessible from your Account page after purchase:

    ePub EPUB The open industry format known for its reflowable content and usability on supported mobile devices.

    Adobe Reader PDF The popular standard, used most often with the free Acrobat® Reader® software.

    This eBook requires no passwords or activation to read. We customize your eBook by discreetly watermarking it with your name, making it uniquely yours.

Description

  • Copyright 2009
  • Pages: 720
  • Edition: 1st
  • eBook
  • ISBN-10: 0-13-280043-8
  • ISBN-13: 978-0-13-280043-3

“I’m an enthusiastic supporter of the CERT Secure Coding Initiative. Programmers have lots of sources of advice on correctness, clarity, maintainability, performance, and even safety. Advice on how specific language features affect security has been missing. The CERT® C Secure Coding Standard fills this need.”
–Randy Meyers, Chairman of ANSI C


“For years we have relied upon the CERT/CC to publish advisories documenting an endless stream of security problems. Now CERT has embodied the advice of leading technical experts to give programmers and managers the practical guidance needed to avoid those problems in new  applications and to help secure legacy systems. Well done!”

–Dr. Thomas Plum, founder of Plum Hall, Inc.

“Connectivity has sharply increased the need for secure, hacker-safe applications. By combining this CERT standard with other safety guidelines, customers gain all-round protection and approach the goal of zero-defect software.”
–Chris Tapp, Field Applications Engineer, LDRA Ltd.

“I’ve found this standard to be an indispensable collection of expert information on exactly how modern software systems fail in practice. It is the perfect place to start for establishing internal secure coding guidelines. You won’t find this information elsewhere, and, when it comes to software security, what you don’t know is often exactly what hurts you.”
–John McDonald, coauthor of The Art of Software Security Assessment


Software security has major implications for the operations and assets of organizations, as well as for the welfare of individuals. To create secure software, developers must know where the dangers lie. Secure programming in C can be more difficult than even many experienced  programmers believe.

This book is an essential desktop reference documenting the first official release of  The CERT® C Secure Coding Standard. The standard itemizes those coding errors that are the root causes of software vulnerabilities in C and prioritizes them by severity, likelihood of exploitation, and remediation costs. Each guideline provides examples of insecure code as well as secure, alternative implementations. If uniformly applied, these guidelines will eliminate the critical coding errors that lead to buffer overflows, format string vulnerabilities, integer  overflow, and other common software vulnerabilities.

Sample Content

Table of Contents

Preface               xvii
Acknowledgments     xxxi
About the Author     xxxiii


Chapter 1: Using This Standard     1
System Qualities           1
Automatically Generated Code         2
Compliance             3

Chapter 2: Preprocessor (PRE) 5
PRE00-C. Prefer inline or static functions to function-like macros          6
PRE01-C. Use parentheses within macros around parameter names          11
PRE02-C. Macro replacement lists should be parenthesized        13
PRE03-C. Prefer type definitions to defines for encoding types          15
PRE04-C. Do not reuse a standard header file name           16
PRE05-C. Understand macro replacement when concatenating tokens or performing stringification     18
PRE06-C. Enclose header files in an inclusion guard         21
PRE07-C. Avoid using repeated question marks           22
PRE08-C. Guarantee that header file names are unique          24
PRE09-C. Do not replace secure functions with less secure functions       26
PRE10-C. Wrap multistatement macros in a do-while loop          27
PRE30-C. Do not create a universal character name through concatenation        29
PRE31-C. Never invoke an unsafe macro with arguments containing assignment, increment, decrement, volatile access, or function call        30

Chapter 3: Declarations and Initialization (DCL)       33
DCL00-C. const-qualify immutable objects      35
DCL01-C. Do not reuse variable names in subscopes         36
DCL02-C. Use visually distinct identifiers      38
DCL03-C. Use a static assertion to test the value of a constant expression      39
DCL04-C. Do not declare more than one variable per declaration      42
DCL05-C. Use type definitions to improve code readability      44
DCL06-C. Use meaningful symbolic constants to represent literal values in program logic      45
DCL07-C. Include the appropriate type information in function declarators        51
DCL08-C. Properly encode relationships in constant definitions           54
DCL09-C. Declare functions that return an errno error code with a return type of errno_t       57
DCL10-C. Maintain the contract between the writer and caller of variadic functions         59
DCL11-C. Understand the type issues associated with variadic functions          62
DCL12-C. Implement abstract data types using opaque types        64
DCL13-C. Declare function parameters that are pointers to values not changed by the function as const             66
DCL14-C. Do not make assumptions about the order of global variable initialization across translation units             69
DCL15-C. Declare objects that do not need external linkage with the storage-class specifier static        70
DCL30-C. Declare objects with appropriate storage durations        72
DCL31-C. Declare identifiers before using them          74
DCL32-C. Guarantee that mutually visible identifiers are unique        78
DCL33-C. Ensure that restrict-qualified source and destination pointers in function arguments do not reference overlapping objects        80
DCL34-C. Use volatile for data that cannot be cached       82
DCL35-C. Do not convert a function using a type that does not match the function definition         84
DCL36-C. Do not declare an identifier with conflicting linkage classifications        87

Chapter 4: Expressions (EXP)        91
EXP00-C. Use parentheses for precedence of operation           93
EXP01-C. Do not take the size of a pointer to determine the size of the pointed-to type     95
EXP02-C. Be aware of the short-circuit behavior of the logical AND and OR operators      96
EXP03-C. Do not assume the size of a structure is the sum of the sizes of its members      98
EXP04-C. Do not perform byte-by-byte comparisons between structures      100
EXP05-C. Do not cast away a const qualification        102
EXP06-C. Operands to the sizeof operator should not contain side effects           104
EXP07-C. Do not diminish the benefits of constants by assuming their values in expressions          105
EXP08-C. Ensure pointer arithmetic is used correctly           107
EXP09-C. Use sizeof to determine the size of a type or variable          109
EXP10-C. Do not depend on the order of evaluation of subexpressions or the order in which side effects take place         111
EXP11-C. Do not apply operators expecting one type to data of an incompatible type      114
EXP12-C. Do not ignore values returned by functions      118
EXP30-C. Do not depend on order of evaluation between sequence points      119
EXP31-C. Avoid side effects in assertions     122
EXP32-C. Do not cast away a volatile qualification     123
EXP33-C. Do not reference uninitialized memory     124
EXP34-C. Ensure a null pointer is not dereferenced     128
EXP35-C. Do not access or modify the result of a function call after a subsequent sequence point         129
EXP36-C. Do not convert pointers into more strictly aligned pointer types         131
EXP37-C. Call functions with the arguments intended by the API         133
EXP38-C. Do not call offsetof() on bit-field members or invalid types           135

Chapter 5: Integers (INT)        139
INT00-C. Understand the data model used by your implementation(s)        141
INT01-C. Use rsize_t or size_t for all integer values representing the size of an object        145
INT02-C. Understand integer conversion rules       149
INT03-C. Use a secure integer library       153
INT04-C. Enforce limits on integer values originating from untrusted sources      155
INT05-C. Do not use input functions to convert character data if they cannot handle all possible inputs       157
INT06-C. Use strtol() or a related function to convert a string token to an integer       159
INT07-C. Use only explicitly signed or unsigned char type for numeric values       162
INT08-C. Verify that all integer values are in range        164
INT09-C. Ensure enumeration constants map to unique values        167
INT10-C. Do not assume a positive remainder when using the % operator       168
INT11-C. Take care when converting from pointer to integer or integer to pointer       170
INT12-C. Do not make assumptions about the type of a plain int bit-field when used in an expression        172
INT13-C. Use bitwise operators only on unsigned operands         174
INT14-C. Avoid performing bitwise and arithmetic operations on the same data         175
INT15-C. Use intmax_t or uintmax_t for formatted I/O on programmer-defined integer types      178
INT30-C. Ensure that unsigned integer operations do not wrap         181
INT31-C. Ensure that integer conversions do not result in lost or misinterpreted data        186
INT32-C. Ensure that operations on signed integers do not result in overflow       191
INT33-C. Ensure that division and modulo operations do not result in divide-by-zero errors     201
INT34-C. Do not shift a negative number of bits or more bits than exist in the operand    203
INT35-C. Evaluate integer expressions in a larger size before comparing or assigning to that size          207

Chapter 6: Floating Point (FLP)       211
FLP00-C. Understand the limitations of floating-point numbers       212
FLP01-C. Take care in rearranging floating-point expressions         214
FLP02-C. Consider avoiding floating-point numbers when precise computation is needed     215
FLP03-C. Detect and handle floating-point errors     218
FLP30-C. Do not use floating-point variables as loop counters     224
FLP31-C. Do not call functions expecting real values with complex values     226
FLP32-C. Prevent or detect domain and range errors in math functions     227
FLP33-C. Convert integers to floating point for floating-point operations     234
FLP34-C. Ensure that floating-point conversions are within range of the new type       236

Chapter 7: Arrays (ARR)         241
ARR00-C. Understand how arrays work        242
ARR01-C. Do not apply the sizeof operator to a pointer when taking the size of an array       245
ARR02-C. Explicitly specify array bounds, even if implicitly defined by an initializer     248
ARR30-C. Guarantee that array indices are within the valid range      250
ARR31-C. Use consistent array notation across all source files      251
ARR32-C. Ensure size arguments for variable length arrays are in a valid range      254
ARR33-C. Guarantee that copies are made into storage of sufficient size      255
ARR34-C. Ensure that array types in expressions are compatible      258
ARR35-C. Do not allow loops to iterate beyond the end of an array      259
ARR36-C. Do not subtract or compare two pointers that do not refer to the same array      261
ARR37-C. Do not add or subtract an integer to a pointer to a non-array object     263
ARR38-C. Do not add or subtract an integer to a pointer if the resulting value does not refer to a valid array element     265

Chapter 8: Characters and Strings (STR)        271
STR00-C. Represent characters using an appropriate type       273
STR01-C. Adopt and implement a consistent plan for managing strings      275
STR02-C. Sanitize data passed to complex subsystems      276
STR03-C. Do not inadvertently truncate a null-terminated byte string      280
STR04-C. Use plain <cod>char</code> for characters in the basic character set      282
STR05-C. Use pointers to const when referring to string literals       284
STR06-C. Do not assume that strtok() leaves the parse string unchanged      286
STR07-C. Use TR 24731 for remediation of existing string manipulation code      288
STR08-C. Use managed strings for development of new string manipulation code      291
STR30-C. Do not attempt to modify string literals      293
STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator      294
STR32-C. Null-terminate byte strings as required       299
STR33-C. Size wide character strings correctly      303
STR34-C. Cast characters to unsigned types before converting to larger integer sizes      305
STR35-C. Do not copy data from an unbounded source to a fixed-length array      307
STR36-C. Do not specify the bound of a character array initialized with a string literal     312
STR37-C. Arguments to character-handling functions must be representable as an unsigned char      314

Chapter 9: Memory Management (MEM)      317
MEM00-C. Allocate and free memory in the same module at the same level of abstraction    319
MEM01-C. Store a new value in pointers immediately after free()     322
MEM02-C. Immediately cast the result of a memory allocation function call into a pointer to the allocated type      324
MEM03-C. Clear sensitive information stored in reusable resources returned for reuse    328
MEM04-C. Do not perform zero-length allocations      332
MEM05-C. Avoid large stack allocations      335
MEM06-C. Ensure that sensitive data is not written out to disk     338
MEM07-C. Ensure that the arguments to calloc(), when multiplied, can be represented as a size_t      342
MEM08-C. Use realloc() only to resize dynamically allocated arrays       343
MEM09-C. Do not assume memory allocation routines initialize memory      346
MEM10-C. Use a pointer validation function       348
MEM30-C. Do not access freed memory       351
MEM31-C. Free dynamically allocated memory exactly once      353
MEM32-C. Detect and handle memory allocation errors      355
MEM33-C. Use the correct syntax for flexible array members      358
MEM34-C. Only free memory allocated dynamically      360
MEM35-C. Allocate sufficient memory for an object       362

Chapter 10: Input/Output (FIO)      367
FIO00-C. Take care when creating format strings      370
FIO01-C. Be careful using functions that use file names for identification      372
FIO02-C. Canonicalize path names originating from untrusted sources      374
FIO03-C. Do not make assumptions about fopen() and file creation      383
FIO04-C. Detect and handle input and output errors     386
FIO05-C. Identify files using multiple file attributes      389
FIO06-C. Create files with appropriate access permissions      394
FIO07-C. Prefer fseek() to rewind()      398
FIO08-C. Take care when calling remove() on an open file      399
FIO09-C. Be careful with binary data when transferring data across systems     401
FIO10-C. Take care when using the rename() function      403
FIO11-C. Take care when specifying the mode parameter of fopen()      407
FIO12-C. Prefer setvbuf() to setbuf()      408
FIO13-C. Never push back anything other than one read character      409
FIO14-C. Understand the difference between text mode and binary mode with file streams     411
FIO15-C. Ensure that file operations are performed in a secure directory    413
FIO16-C. Limit access to files by creating a jail     418
FIO30-C. Exclude user input from format strings     421
FIO31-C. Do not simultaneously open the same file multiple times     424
FIO32-C. Do not perform operations on devices that are only appropriate for files     426
FIO33-C. Detect and handle input output errors resulting in undefined behavior      431
FIO34-C. Use int to capture the return value of character I/O functions      436
FIO35-C. Use feof() and ferror() to detect end-of-file and file errors when sizeof(int) == sizeof(char)      438
FIO36-C. Do not assume a new-line character is read when using fgets()      440
FIO37-C. Do not assume character data has been read      442
FIO38-C. Do not use a copy of a FILE object for input and output      443
FIO39-C. Do not alternately input and output from a stream without an intervening flush or positioning call      444
FIO40-C. Reset strings on fgets() failure      446
FIO41-C. Do not call getc() or putc() with stream arguments that have side effects     448
FIO42-C. Ensure files are properly closed when they are no longer needed      450
FIO43-C. Do not create temporary files in shared directories      454
FIO44-C. Only use values for fsetpos() that are returned from fgetpos()         464

Chapter 11: Environment (ENV) 467
ENV00-C. Do not store the pointer to the string returned by getenv()      468
ENV01-C. Do not make assumptions about the size of an environment variable      474
ENV02-C. Beware of multiple environment variables with the same effective name      475
ENV03-C. Sanitize the environment when invoking external programs        478
ENV04-C. Do not call system() if you do not need a command processor      482
ENV30-C. Do not modify the string returned by getenv()       487
ENV31-C. Do not rely on an environment pointer following an operation that may invalidate it         489
ENV32-C. No atexit handler should terminate in any way other than by returning       494

Chapter 12: Signals (SIG)      499
SIG00-C. Mask signals handled by noninterruptible signal handlers      500
SIG01-C. Understand implementation-specific details regarding signal handler persistence    503
SIG02-C. Avoid using signals to implement normal functionality      507
SIG30-C. Call only asynchronous-safe functions within signal handlers      511
SIG31-C. Do not access or modify shared objects in signal handlers      517
SIG32-C. Do not call longjmp() from inside a signal handler      519
SIG33-C. Do not recursively invoke the raise() function      523
SIG34-C. Do not call signal() from within interruptible signal handlers     526

Chapter 13: Error Handling (ERR)     531
ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy    533
ERR01-C. Use ferror() rather than errno to check for FILE stream errors     535
ERR02-C. Avoid in-band error indicators    537
ERR03-C. Use runtime-constraint handlers when calling functions defined by TR 24731-1     541
ERR04-C. Choose an appropriate termination strategy     544
ERR05-C. Application-independent code should provide error detection without dictating error handling     549
ERR06-C. Understand the termination behavior of assert() and abort()     556
ERR30-C. Set errno to zero before calling a library function known to set errno, and check errno only after the function returns a value indicating failure  558
ERR31-C. Do not redefine errno     563
ERR32-C. Do not rely on indeterminate values of errno     564

Chapter 14: Miscellaneous (MSC)     569
MSC00-C. Compile cleanly at high warning levels    570
MSC01-C. Strive for logical completeness     572
MSC02-C. Avoid errors of omission     574
MSC03-C. Avoid errors of addition     576
MSC04-C. Use comments consistently and in a readable fashion    578
MSC05-C. Do not manipulate time_t typed values directly     580
MSC06-C. Be aware of compiler optimization when dealing with sensitive data     582
MSC07-C. Detect and remove dead code     585
MSC08-C. Library functions should validate their parameters    588
MSC09-C. Character encoding: use subset of ASCII for safety     590
MSC10-C. Character encoding: UTF-8-related issues    594
MSC11-C. Incorporate diagnostic tests using assertions    597
MSC12-C. Detect and remove code that has no effect    598
MSC13-C. Detect and remove unused values     600
MSC14-C. Do not introduce unnecessary platform dependencies     602
MSC15-C. Do not depend on undefined behavior     604
MSC30-C. Do not use the rand() function for generating pseudorandom numbers     607
MSC31-C. Ensure that return values are compared against the proper type      610

Appendix: POSIX (POS)     613
POS00-C. Avoid race conditions with multiple threads     615
POS01-C. Check for the existence of links     617
POS02-C. Follow the principle of least privilege     620
POS30-C. Use the readlink() function properly     623
POS31-C. Do not unlock or destroy another thread’s mutex     625
POS32-C. Include a mutex when using bit-fields in a multithreaded environment    626
POS33-C. Do not use vfork()     629
POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument     631
POS35-C. Avoid race conditions while checking for the existence of a symbolic link     633
POS36-C. Observe correct revocation order while relinquishing privileges     636
POS37-C. Ensure that privilege relinquishment is successful     637

Glossary     643
References     647
Index     659

Updates

Submit Errata

More Information

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020