Den største sikkerhetsfeilen på de fleste WordPress-nettsteder er ikke en sårbarhet i et programtillegg. Det er å gi kunden “Administrator”-tilgang når de bare trenger å redigere innlegg.
Eller enda verre, å gi en “Praktikant” muligheten til å bytte temaer (switch_themes).
WordPress har et kraftig tilgangskontrollsystem (ACL) innebygd. Det kalles Roller og Rettigheter (Roles & Capabilities). I denne guiden skal vi gå utover standard “Redaktør”-rollen og lære å arkitektere sikre tillatelser.
1. Konsepter: Rolle vs rettighet (capability)
- Rettighet (Cap): En spesifikk tillatelse til å gjøre én ting.
- Eksempel:
edit_posts(redigere innlegg),publish_pages(publisere sider),install_plugins(installere tillegg).
- Eksempel:
- Rolle: En samling rettigheter.
- Eksempel:
Editor(Redaktør) =edit_posts+publish_posts+manage_categories(men IKKEinstall_plugins).
- Eksempel:
Den gylne regel: Sjekk alltid for Rettigheter, aldri Roller.
// ❌ FEIL
if ( current_user_can( 'administrator' ) ) { ... }
// ✅ RIKTIG
if ( current_user_can( 'manage_options' ) ) { ... }
2. Komplett referanse for WordPress-standardroller
WordPress kommer med seks forhåndsdefinerte roller som dekker de fleste bruksområder:
2.1 Administrator
- Rettigheter: Full tilgang til alle funksjoner
- Bruk: Nettstedseier, utvikler
- Risiko: Kan slette alt, endre temaer/tillegg, fjerne andre administratorer
- Viktige rettigheter:
manage_options,activate_plugins,switch_themes,edit_users,delete_site
2.2 Redaktør (Editor)
- Rettigheter: Administrer alt innhold, inkludert andres innlegg
- Bruk: Innholdsleder, sjefredaktør
- Begrensninger: Ingen tilgang til innstillinger, tillegg, temaer
- Viktige rettigheter:
edit_others_posts,publish_posts,manage_categories,moderate_comments
2.3 Forfatter (Author)
- Rettigheter: Opprette og publisere egne innlegg
- Bruk: Regelmessige innholdsskapere
- Begrensninger: Kan ikke redigere andres innhold, ingen sideadministrasjon
- Viktige rettigheter:
publish_posts,upload_files,edit_published_posts
2.4 Bidragsyter (Contributor)
- Rettigheter: Opprette innlegg for gjennomgang
- Bruk: Gjesteforfattere, praktikanter
- Begrensninger: Ingen publisering, ingen mediaopplastinger
- Viktige rettigheter:
edit_posts,delete_posts(kun egne, upubliserte)
2.5 Abonnent (Subscriber)
- Rettigheter: Kun profiladministrasjon
- Bruk: Kommentatorer, medlemsområder
- Viktige rettigheter:
read
2.6 Super-Admin (Multisite)
- Rettigheter: Nettverksomfattende kontroll over alle nettsteder
- Bruk: Multisite-nettverksadministratorer
- Viktige rettigheter:
manage_network,create_sites,delete_sites
3. Opprette EN egendefinert rolle
La oss si at du har en “Butikksjef” som trenger å administrere produkter, men ikke skal røre temaet eller tilleggene dine.
function wppoland_add_store_manager_role() {
add_role(
'store_manager',
'Butikksjef',
[
'read' => true,
'edit_posts' => true,
'upload_files' => true,
'manage_woocommerce' => true, // Egendefinert rettighet
]
);
}
// Kjør BARE ÉN GANG (f.eks. ved aktivering)
// add_action( 'init', 'wppoland_add_store_manager_role' );
Viktig: Roller lagres i databasen (
wp_options>wp_user_roles). Du trenger ikke å kjøreadd_roleved hver sidevisning. Kjør den én gang ved utrulling.
3.1 Praktiske eksempler på egendefinerte roller
SEO-Manager rolle:
function wppoland_add_seo_manager_role() {
add_role(
'seo_manager',
'SEO Manager',
[
'read' => true,
'edit_posts' => true,
'edit_others_posts' => true,
'edit_pages' => true,
'edit_others_pages' => true,
'publish_posts' => true,
'publish_pages' => true,
'upload_files' => true,
'manage_categories' => true,
'edit_theme_options' => true, // For SEO-innstillinger
'manage_options' => false, // Ingen generelle innstillinger
'install_plugins' => false,
'activate_plugins' => false,
]
);
}
Content Reviewer rolle:
function wppoland_add_content_reviewer_role() {
add_role(
'content_reviewer',
'Innholdsgransker',
[
'read' => true,
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'publish_posts' => false, // Kan ikke publisere
'moderate_comments' => true,
'upload_files' => false,
]
);
}
4. Legge til rettigheter til eksisterende roller
Noen ganger vil du bare la “Redaktøren” redigere menyer (som de ikke kan gjøre som standard).
function wppoland_upgrade_editor() {
$role = get_role( 'editor' );
if ( $role ) {
$role->add_cap( 'edit_theme_options' ); // Tillater meny- og widget-redigering
}
}
// Kjør én gang
4.1 Fjerne rettigheter
function wppoland_restrict_author_uploads() {
$role = get_role( 'author' );
if ( $role ) {
$role->remove_cap( 'upload_files' );
}
}
5. Krisehåndtering: Tilbakestille roller
Hvis et programtillegg rotet til databasen din eller du ved et uhell slettet ‘Administrator’-rollen (det skjer!), trenger du en hard reset.
Dette skriptet gjenoppretter standard WordPress-arkitektur.
function wppoland_reset_roles() {
if ( ! isset( $_GET['reset_roles_secret_key'] ) ) return;
require_once( ABSPATH . 'wp-admin/includes/schema.php' );
populate_roles();
echo "Roller tilbakestilt.";
exit;
}
add_action( 'init', 'wppoland_reset_roles' );
Tilgang via: https://ditt-domene.no/?reset_roles_secret_key=1
6. Beste praksis for capability-sjekking
6.1 Sjekk i maler
if ( current_user_can( 'edit_post', $post_id ) ) {
// Vis rediger-knapp
}
6.2 Sjekk i AJAX-handlere
add_action( 'wp_ajax_my_custom_action', 'my_ajax_handler' );
function my_ajax_handler() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( 'Utilstrekkelige tillatelser' );
}
// Behandle forespørsel
}
6.3 Sjekk i REST API
register_rest_route( 'myplugin/v1', '/data/', [
'methods' => 'GET',
'callback' => 'get_data',
'permission_callback' => function () {
return current_user_can( 'read' );
},
] );
7. Sammenligning av Role Editor-tillegg
| Tillegg | Pris | Best for | Spesialiteter |
|---|---|---|---|
| User Role Editor | Freemium | Enkle tilpasninger | Populært, enkelt |
| Members | Gratis | Utviklere | Kodeintegrasjon, Meta-Cap |
| PublishPress Capabilities | Freemium | Innholdsarbeidsflyter | Redaksjonelle funksjoner |
| Advanced Access Manager | Freemium | Komplekse scenarier | Multisite-støtte |
7.1 User Role Editor
// Programmatisk tilgang til URE-funksjoner
if ( function_exists( 'ure_edit_roles' ) ) {
$ure = new URE_Role_View();
// Avansert rollebehandling
}
7.2 Members-tillegg
// CPT-støtte med Members
add_action( 'members_register_caps', function() {
members_register_cap( 'custom_capability', [
'label' => __( 'Egendefinert rettighet', 'textdomain' ),
] );
} );
8. Multisite-rolleoverveielser
I en Multisite-installasjon er det viktige forskjeller:
8.1 Nettverks- vs. nettstedsroller
// Sjekk for Super-Admin
if ( is_super_admin() ) {
// Nettverksomfattende handlinger
}
// Nettstedsspesifikke rettigheter
if ( current_user_can_for_blog( $blog_id, 'manage_options' ) ) {
// Nettstedsspesifikke handlinger
}
8.2 Rollesynkronisering
function wppoland_sync_role_to_all_sites( $user_id, $role ) {
if ( ! is_multisite() ) return;
$blogs = get_sites();
foreach ( $blogs as $blog ) {
switch_to_blog( $blog->blog_id );
$user = new WP_User( $user_id );
$user->set_role( $role );
restore_current_blog();
}
}
9. WooCommerce-rolleutvidelser
WooCommerce legger til egne roller og rettigheter:
9.1 Butikksjef
// Butikksjef-rettigheter
$shop_manager_caps = [
'manage_woocommerce' => true,
'view_woocommerce_reports' => true,
'edit_product' => true,
'edit_products' => true,
'publish_products' => true,
'read_private_products' => true,
'edit_others_products' => true,
'edit_private_products' => true,
'edit_published_products' => true,
'read_product' => true,
];
9.2 Kunde-rolle
// Kunde har minimale rettigheter
add_role( 'customer', 'Kunde', [
'read' => true,
] );
9.3 Egendefinerte produktroller
function wppoland_add_product_editor_role() {
add_role( 'product_editor', 'Produktredaktør', [
'read' => true,
'edit_product' => true,
'edit_products' => true,
'edit_others_products' => false, // Kun egne produkter
'publish_products' => false, // Til gjennomgang
'read_product' => true,
'upload_files' => true,
] );
}
10. Beste praksis for sikkerhet 2026
10.1 Ikke bruk brukernavnet ‘admin’
Brute force-angrep retter seg mot bruker-ID 1 eller brukernavnet ‘admin’.
10.2 Map meta capabilities
Når du bruker Custom Post Types, ikke bare bruk edit_posts. Kartlegg granulære caps:
register_post_type( 'book', [
'capability_type' => 'book',
'map_meta_cap' => true, // Nøkkel for detaljert kontroll
] );
Nå kan du gi en bruker edit_books uten å gi dem edit_posts.
10.3 Tofaktorautentisering for administratorer
function wppoland_require_2fa_for_admins() {
$user = wp_get_current_user();
if ( in_array( 'administrator', $user->roles ) ) {
// Sjekk 2FA-status
if ( ! get_user_meta( $user->ID, 'two_factor_enabled', true ) ) {
add_action( 'admin_notices', function() {
echo '<div class="error"><p>2FA er påkrevd for administratorer!</p></div>';
} );
}
}
}
10.4 Rollebaserte admin-menyrestriksjoner
function wppoland_restrict_admin_menu() {
if ( ! current_user_can( 'manage_options' ) ) {
remove_menu_page( 'tools.php' );
remove_menu_page( 'options-general.php' );
remove_menu_page( 'plugins.php' );
remove_menu_page( 'themes.php' );
}
}
add_action( 'admin_menu', 'wppoland_restrict_admin_menu', 999 );
11. Feilsøking
11.1 “Du har ikke de nødvendige rettighetene”
- Tøm cache (objekt-cache, transients)
- Tilbakestill roller med
populate_roles() - Sjekk tilleggskonflikter
11.2 Egendefinerte roller forsvant
- Sjekk databasetabell
wp_options(Key:wp_user_roles) - Gjenopprett fra backup
- Opprett roller på nytt
11.3 Rettigheter blir ikke brukt
- Sett
map_meta_captiltrue - Navngi rettigheter korrekt
- Bruk WordPress-standard-rettigheter som referanse
11.4 Multisite-problemer
- Sjekk Super-Admin-status
- Bruk
switch_to_blog()/restore_current_blog() - Nettverksomfattende rollesynkronisering
12. FAQ
S: Hvor mange roller bør et nettsted maksimalt ha? S: Ideelt sett 4-6 roller. For mange roller fører til forvirring og administrasjonsarbeid.
S: Kan jeg slette standardroller?
S: Hva skjer med innhold fra en slettet bruker?
S: Hvordan tester jeg rettigheter som utvikler?
S: Er egendefinerte rettigheter tryggere?
S: Hvordan migrerer jeg roller mellom installasjoner?
S: Kan roller være tidsbegrenset?
Oppsummering
- Prinsippet om minste privilegium: Gi brukere kun det de trenger.
- Egendefinerte roller: Bedre enn å hacke ‘Redaktør’-rollen.
- Database: Roller lever i databasen, ikke i koden. Endringer vedvarer.
- Testing: Test alltid med forskjellige roller før du går live.
- Rettighets-tester: Sjekk alltid for spesifikke rettigheter, aldri roller.
- Meta-Caps: Bruk
map_meta_capfor Custom Post Types. - Regelmessig revisjon: Revider brukerroller minst kvartalsvis.
13. Avanserte teknikker og scenarier
13.1 Rollebasert innholdstilgang
Ofte ønsker du at brukere kun skal se sine egne innlegg, ikke andres. Her er hvordan du implementerer dette:
<?php
/**
* Begrens forfattere til sine egne innlegg i innleggslisten
*/
function wppoland_restrict_authors_to_own_posts( $query ) {
global $pagenow;
// Kun i admin-området og kun for innleggslisten
if ( ! is_admin() || $pagenow != 'edit.php' ) {
return $query;
}
$current_user = wp_get_current_user();
// Kun for forfattere og lavere roller
if ( in_array( $current_user->ID, array( 1 ) ) ) {
return $query; // Administratorer ser alt
}
if ( in_array( 'author', $current_user->roles ) ||
in_array( 'contributor', $current_user->roles ) ) {
$query->set( 'author', $current_user->ID );
}
return $query;
}
add_action( 'pre_get_posts', 'wppoland_restrict_authors_to_own_posts' );
13.2 Tidsbegrensede roller
For midlertidig tilgang, som gjesterforfattere eller tidsbegrensede prosjekter:
<?php
/**
* Tildel en rolle med utløpsdato
*/
function wppoland_schedule_role_expiry( $user_id, $role, $expiry_date ) {
if ( ! is_multisite() ) {
wp_schedule_single_event(
strtotime( $expiry_date ),
'wppoland_expire_user_role',
array( $user_id, $role )
);
}
}
/**
* Tilbakestill rolle etter utløp
*/
function wppoland_expire_user_role( $user_id, $old_role ) {
$user = new WP_User( $user_id );
// Sjekk om brukeren fortsatt har den gamle rollen
if ( in_array( $old_role, $user->roles ) ) {
$user->set_role( 'subscriber' );
}
}
add_action( 'wppoland_expire_user_role', 'wppoland_expire_user_role' );
// Eksempel: Rolle "Gjesteforfatter" utløper etter 30 dager
// wppoland_schedule_role_expiry( $user_id, 'guest_author', '+30 days' );
13.3 Roller basert på bruker-metadata
Noen ganger trenger du dynamiske roller basert på brukerattributter:
<?php
/**
* Tildel roller basert på bruker-metadata
*/
function wppoland_assign_role_from_metadata( $user_id ) {
$department = get_user_meta( $user_id, 'department', true );
$level = get_user_meta( $user_id, 'access_level', true );
if ( ! $department || ! $level ) {
return;
}
$role_name = $department . '_' . $level;
$available_roles = wp_roles()->get_names();
if ( array_key_exists( $role_name, $available_roles ) ) {
$user = new WP_User( $user_id );
$user->set_role( $role_name );
}
}
add_action( 'user_register', 'wppoland_assign_role_from_metadata' );
add_action( 'profile_update', 'wppoland_assign_role_from_metadata' );
13.4 Betingede menyelementer basert på rettigheter
Utvid admin-menyen med rollebaserte elementer:
<?php
/**
* Legg til egendefinert meny for spesifikke roller
*/
function wppoland_add_custom_admin_menu() {
// Kun for brukere med spesifikk rettighet
if ( ! current_user_can( 'view_dashboard_widgets' ) ) {
return;
}
add_menu_page(
'Mitt Dashboard',
'Mitt Dashboard',
'view_dashboard_widgets',
'my-custom-dashboard',
'wppoland_render_custom_dashboard',
'dashicons-desktop',
2
);
}
add_action( 'admin_menu', 'wppoland_add_custom_admin_menu', 99 );
function wppoland_render_custom_dashboard() {
echo '<div class="wrap">';
echo '<h1>Mitt egendefinerte dashboard</h1>';
echo '<p>Dette innholdet er kun synlig for brukere med rettigheten "view_dashboard_widgets".</p>';
echo '</div>';
}
13.3 Revisionslogg for rettighetsendringer
Spor alle endringer i brukerroller:
<?php
/**
* Logg rolleendringer
*/
function wppoland_log_role_changes( $user_id, $role, $old_roles ) {
$old_roles_str = implode( ', ', $old_roles );
$log_entry = array(
'user_id' => $user_id,
'old_roles' => $old_roles_str,
'new_role' => $role,
'changed_by' => get_current_user_id(),
'timestamp' => current_time( 'mysql' ),
'ip_address' => $_SERVER['REMOTE_ADDR'],
);
// Lagre i alternativ eller egendefinert tabell
$logs = get_option( 'wppoland_role_change_logs', array() );
$logs[] = $log_entry;
// Behold kun de siste 1000 oppføringene
if ( count( $logs ) > 1000 ) {
array_shift( $logs );
}
update_option( 'wppoland_role_change_logs', $logs );
}
add_action( 'set_user_role', 'wppoland_log_role_changes', 10, 3 );
14. Migrering og eksport/import av roller
14.1 Eksportere roller
<?php
/**
* Eksporter alle roller og rettigheter
*/
function wppoland_export_roles() {
global $wp_roles;
$roles_data = array();
foreach ( $wp_roles->roles as $role_name => $role_info ) {
$roles_data[ $role_name ] = array(
'name' => $role_info['name'],
'capabilities' => $role_info['capabilities'],
);
}
return json_encode( $roles_data, JSON_PRETTY_PRINT );
}
// Bruk:
$roles_json = wppoland_export_roles();
file_put_contents( 'roles-backup.json', $roles_json );
14.2 Importere roller
<?php
/**
* Importer roller fra JSON
*/
function wppoland_import_roles( $json_data ) {
$roles_data = json_decode( $json_data, true );
if ( ! $roles_data ) {
return false;
}
foreach ( $roles_data as $role_name => $role_info ) {
// Hopp over standardroller hvis de eksisterer
if ( get_role( $role_name ) ) {
continue;
}
add_role(
$role_name,
$role_info['name'],
$role_info['capabilities']
);
}
return true;
}
15. Ytelsesoverveielser
15.1 Mellomlagre rettigheter
WordPress mellomlagrer rettigheter automatisk, men ved mange roller kan ytelsen lide:
<?php
/**
* Optimaliser rolle-mellomlagring
*/
function wppoland_optimize_role_caching() {
// Deaktiver rolle-mellomlagring under bulk-operasjoner
add_filter( 'user_has_cap', function( $caps, $cap, $user_id, $args ) {
// Kun for spesifikke operasjoner
if ( defined( 'DOING_BULK_ACTION' ) && DOING_BULK_ACTION ) {
wp_cache_delete( $user_id, 'user_roles' );
}
return $caps;
}, 10, 4 );
}
15.2 Unngå for mange roller
Hver ekstra rolle øker kompleksiteten og vedlikeholdsbyrden. Hold antallet roller håndterbart:
- Små nettsteder: 3-4 roller (Admin, Redaktør, Forfatter, Abonnent)
- Middels nettsteder: 5-6 roller (med spesialisert roller)
- Store nettsteder: Maksimalt 8-10 roller (med klar hierarki)
16. Feilhåndtering for vanlige problemer
16.1 Rettigheter lagres ikke
<?php
/**
* Debug-funksjon for rollerelaterte problemer
*/
function wppoland_debug_roles() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
global $wp_roles;
echo '<pre>';
echo 'Nåværende roller og rettigheter:\n\n';
foreach ( $wp_roles->roles as $role_name => $role_info ) {
echo "Rolle: $role_name\n";
echo "Rettigheter: " . implode( ', ', array_keys( $role_info['capabilities'] ) ) . "\n\n";
}
echo '</pre>';
}
// Legg dette til i functions.php og kall ?debug_roles i admin
16.2 Bruker får ikke tilgang til tross for rettighet
Sjekk for konflikter med andre tillegg:
<?php
/**
* Debug: Vis alle rettigheter til en bruker
*/
function wppoland_debug_user_caps() {
$user = wp_get_current_user();
echo '<h2>Debug: Brukerrettigheter</h2>';
echo '<p>Bruker: ' . $user->display_name . '</p>';
echo '<p>Roller: ' . implode( ', ', $user->roles ) . '</p>';
echo '<h3>Alle rettigheter:</h3>';
echo '<ul>';
foreach ( $user->allcaps as $cap => $value ) {
$status = $value ? '✅' : '❌';
echo "<li>$status $cap</li>";
}
echo '</ul>';
}
// Legg dette til på test-siden din
Konklusjon
Å mestre spesifikke rettigheter er forskjellen mellom et sikkert nettsted og et hacket ett. WordPress-roller- og rettighetssystemet er en av de kraftigste funksjonene i plattformen, men det blir ofte undervurdert eller feilbrukt. Gjennom konsekvent anvendelse av prinsippet om minste privilegium, opprettelse av egendefinerte roller for spesifikke bruksområder og regelmessige revisjoner, kan du bygge et sikkert og godt strukturert WordPress-nettsted.
Husk: Gi aldri mer tilgang enn nødvendig, test alltid endringer grundig, og dokumenter rolle strukturen din for fremtidig vedlikehold og overlevering. En gjennomtenkt rettighetsstruktur er ikke bare et sikkerhetstegn, men også et tegn på profesjonell utvikling.



