Clarity needed on usage of multiple 403 forbidden header() functions at the beginning of the plugin files

The question:

Just see the following code snippet. I have came across this in one of the plugins that I am reading now.

if ( ! defined( 'ABSPATH' ) ) {
  header( 'Status: 403 Forbidden' );
  header( 'HTTP/1.1 403 Forbidden' );

I understand that this script is sending an forbidden 403 header response to the browser for unauthorized access. But why two 403 headers ? Is the second one kind of fallback to the first one ?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

The proper way to send a status (when WordPress is not available) is:

http_response_code( 403 );

See the PHP Manual for its definition.

But in Plugin files, this should never be the “default” code on top of a file header. See Worthwhile to restrict direct access of theme files? for a discussion.

In WordPress, use status_header( 403 ) if you need it.

A note on the code you’ve posted:

header( 'Status: 403 Forbidden' );
header( 'HTTP/1.1 403 Forbidden' );

The first line is a “special” treatment for PHP running in CGI mode, the second is using a specific HTTP protocol version without any check. If the connection is over HTTP 2 or 1.1, this makes no sense.

Both are wrong, because the correct way to send the proper status with header() is using the second and the third argument of that function.

So this would work better:

header( 'Status: 403 Forbidden', true, 403 );

The second argument tells PHP to overwrite other headers with the same name, the third is for the real status. The code that you posted is a good counter-example. 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment