#security 47 articles
ensureuser returns the login name — stop looking it up by Email gotchas / rest-api The response already carries LoginName; a follow-up siteusers filter on Email misses accounts whose UPN differs A "public mode" flag that disables the token check opens every endpoint in the Function App, not just the chat gotchas / azure-functions One Function App serves a signed-in SPFx app and an anonymous website chatbot; the website instance switches off the token check, and every other HTTP function in the same app (usage stats, storage read/write, file… A file-size limit doesn't stop a zip bomb — Office extraction needs a decompressed cap gotchas / spfx An upload-size limit only bounds the compressed archive; a crafted !ref still OOMs the tab A formatter that returns its raw input is a hole in your escaping gotchas / security The unhappy branch returns the value verbatim; about:blank inherits your origin A generated PowerShell script that embeds file names in a here-string runs code under the admin who runs it gotchas / powershell Data that tenant users can name (file paths, titles) breaks every textual PowerShell literal – expandable here-strings run $(…), ; splits CSV rows, '@ ends a literal here-string; embed data as base64 JSON instead A library your app provisions inherits the web's write permissions — and that is how an AI grounding source gets poisoned gotchas / security Any member can upload over REST and poison an AI grounded on that library; WriteSecurity: 4 does not fix it (Edit includes Manage Lists and bypasses item-level settings) — only unique permissions on the library do A non-web protocol in a formatter href silently drops the whole element gotchas / lists ms-word: in a formatter link removes the element with all children, per item, no error; open-in-app = openContextMenu A permission check that only asks "who has too much?" passes on an empty ACL gotchas / permissions "no principal outside the allow-list can write" is also satisfied when nobody can write at all; assert the opposite direction with a non-zero writer count, and read the principals strictly so a transient 429 cannot… A protocol-relative URL walks straight through your host allowlist gotchas / spfx A host check built on ^https?:// reads //evil.example/… as relative and lets it through; the browser then supplies the scheme and the request leaves for a foreign origin A provisioned list with ReadSecurity=2 looks perfect to an admin and empty to everyone else gotchas / lists ReadSecurity=2 looks perfect to an admin and empty to everyone else; WriteSecurity=2 breaks collaborative edits only A SharePoint group created by code hides its own membership — and Full Control does not get you in gotchas / security sitegroups POST defaults to OnlyAllowMembersViewMembership: true, so only a member or the account that ran provisioning can read the members; Full Control does not help and identical permission masks prove it A status code measures where the request stopped first, not what the user may do gotchas / permissions A probe that writes with a deliberately stale IF-MATCH and reads permissions off 403 vs 412 measures which gate the request hit first: SharePoint evaluates the etag BEFORE authorisation, so 412 comes back even where… A trailing-whitespace regex freezes the page when it parses AI output gotchas / spfx /\s+$/ and lazy (.+?)\s*$ are quadratic on a line with a long run of spaces that does not end the line; text from an AI model or a foreign document is untrusted input, so trim with trimEnd() and anchor captures on a… A user with Read on one page only is denied at the site root URL — link to the page, not the site gotchas / permissions When a principal has Read on a single page in Site Pages and only Limited Access on the site, opening the site URL ends on AccessDenied.aspx even though the page itself opens fine — so a link that falls back to the… An allowlist sanitizer that keeps the text of disallowed tags dumps CSS and JavaScript source into your content gotchas / security An allowlist needs two sets: tags to keep, and tags to drop WITH their subtree; otherwise a pasted web page dumps its stylesheet into the article as visible text An ECDSA signature made in Node fails crypto.subtle.verify in the browser — Node defaults to DER, WebCrypto expects raw r||s gotchas / tooling crypto.sign in Node returns a DER-encoded ECDSA signature (69–72 bytes); WebCrypto verify in an SPFx bundle expects IEEE P1363 (64 bytes for P-256) and just returns false. Sign with dsaEncoding ieee-p1363, check the… An Entra group inside a SharePoint group is invisible to every membership check SharePoint offers gotchas / security SharePoint accepts an Entra group as a member of a site group, then never expands it: currentuser/groups is direct-only and sitegroups/{id}/users returns the group, not its people — resolve with Graph checkMemberGroups… An evidence record whose "who" is written by the browser proves nothing — compare it with the server-stamped Author, and compare on the sign-in name too gotchas / lists Append-only lists let any contributor add a row with someone else's name in a text column; Author is stamped by SharePoint. Compare the two — but against Author/Name (the sign-in claim) as well, or every user whose… An image upload that accepts image/* accepts SVG — and SVG is a script gotchas / security SVG is a script: inert inside , executed when the file's own URL is opened; allow-list raster MIME types An SPFx web part that calls an intranet API makes Chrome and Edge ask every user for local network access gotchas / spfx A *.sharepoint.com page fetching a host that resolves to a private IP is a local network request – Chrome (from 142) and Edge prompt every user and a refusal is a bare Failed to fetch; pre-allow the SharePoint origin… An unparenthesized OR in your KQL query silently escapes the scope filter gotchas / search KQL AND binds tighter than OR; wrapping the query in parens is necessary but NOT sufficient (text can break out of them), and an empty custom path list must not fall back to the whole tenant Breaking inheritance copies foreign Edit grants — and Edit defeats item-level security gotchas / security Another app's groups arrive with Edit, which carries ManageLists and bypasses item-level security; break without copying and prune the ACL — but only on a genuinely polluted scope, because copyRoleAssignments=false… Breaking inheritance without copying keeps only YOU — and the re-grant forgets custom groups gotchas / permissions copyRoleAssignments=false leaves exactly one role assignment (the caller), so re-granting Owners/Members/Visitors drops every direct grant and custom group; and an account that loses a configuration read can end up… Check another user's effective permissions (without their password) snippets / rest Verify what a normal user can actually reach — from your own session, no test account; mind Open = Low bit 16 CSV export of list data hands Excel a formula, not text gotchas / security A member-written cell starting = + - @ (or TAB/CR) runs in Excel on the reader's machine; quoting doesn't disarm it, an apostrophe prefix does Fewer sites and sudden 403s usually mean a different account, not a tenant outage gotchas / security A tenant-wide snippet run from a second browser window executes as whoever is signed in there; print currentuser and the visible-site count before you blame the tenant Find externally / anonymously shared content via Search snippets / rest Oversharing / Copilot-readiness audit: ViewableByExternalUsers:1 surfaces files shared out, security-trimmed, one query HasUniqueRoleAssignments proves the break, not the hardening — and a half-done break is worse than inheritance gotchas / permissions The flag is true after the break alone, so verifying on it reports "hardened" over a list whose trim never ran; with the safe copy=true form that state is worse than inheritance. Read roleassignments and measure… Hiding a field in an SPFx web part is not a permission gotchas / security Role-based UI field hiding is cosmetic; Read on the list = REST/Export/other web parts see it; confidentiality needs a separate list, item perms, or a server tier — plus the two traps the separate list creates: a… Item-level edit rights cover every field – don't trust status, approver or link fields the user can write gotchas / permissions Unique permissions on an item don't separate fields: whoever may edit it can set Status, Approver or a lookup Id via REST – derive trust from admin-only data and version history Locking down a no-script site from code: web NoCrawl is denied even to a site collection admin, and turning off access requests returns 200 and changes nothing gotchas / security On a modern site with custom scripts disabled, NoCrawl on the WEB returns 403 via REST and CSOM even for a site collection admin, and SetUseAccessRequestDefaultAndUpdate(false) returns 200 without effect; both work… Manifest SRI does not cover scripts your SPFx bundle loads itself (pdf.js, tesseract.js, workers) gotchas / spfx Pinning the loader in the .sppkg and giving every manifest path and webpack chunk an integrity hash still leaves a hole – third-party libraries your own code injects with a script tag, fetches for a worker or that a… Narrowing a principal to Read — "already reads" checked before stripping write leaves it with nothing gotchas / permissions Edit and Contribute contain the View bit, so a "does it already read?" check passes, Read is never added, and the step that removes the write binding then removes the only binding that carried read access — the… npm audit --omit=dev overstates what SPFx actually ships gotchas / spfx SPFx keeps its Node build toolchain in dependencies, so 229 „production“ findings can hide a single real one; grep the published bundle and always include a control sample PermissionKind is 1-based — decoding BasePermissions with 1 << kind invents a security finding gotchas / permissions The flag for kind k is 1 << (k - 1), so 1 << k invents a security finding: Contribute appears to hold ManageLists (it holds ViewFormPages). Calibrate any decoder against a known level first, and note the tell — a… perUserMfaState says "disabled" even when MFA is enforced — don't report it as "user has no MFA" gotchas / graph The legacy per-user switch stays off while MFA is fully enforced; report on userRegistrationDetails instead — which omits blocked accounts and needs an undocumented Entra ID P1/P2 tenant Power Platform admin API returns nextLink on a regional host – a guard that only knows api.powerapps.com breaks paging for US tenants gotchas / rest-api Admin listings page through unitedstates.api.powerapps.com (and other one-label regional hosts); a token guard that allows only the global host rejects page two, and you never see it on a small tenant – allow exactly… Purview audit objectIdFilters can return nothing — silently gotchas / graph Narrowed to one library: 0 records, no error; without the filter 1,000 records, 38 of them for that library — ask for a window, filter by object locally, A/B every server-side filter Restoring inheritance is a one-way door — snapshot the unique assignments first gotchas / permissions resetroleinheritance throws away every unique role assignment and SharePoint keeps no copy, so an "undo" is only possible if the code saved the assignments BEFORE the call; re-breaking with copyRoleAssignments=true… SPFx adds Subresource Integrity to a script when the manifest path is { path, integrity } gotchas / spfx A component manifest you pass to SPComponentLoader.loadComponent can carry an SRI hash per script resource as path { path, integrity }; SharePoint then emits script integrity crossorigin=anonymous and the browser… Stored XSS via SharePoint list content — React won't save you gotchas / security React doesn't block javascript: hrefs; allowlist safeHref with C0-strip at every sink The tenant root site is not necessarily readable by everyone gotchas / permissions Measured: unique permissions, no Everyone except external users, an ordinary employee's mask High=0, Low=0; don't anchor a must-work-for-everyone mechanism there, measure with getusereffectivepermissions The tenant's CSP is inherited by srcdoc frames — inline scripts in embedded HTML never run gotchas / spfx Modern pages send script-src without 'unsafe-inline', and a document you build yourself (srcdoc, blob:, data:) inherits it, so every inline script in the embedded HTML is dropped; an external file from an allow-listed… Verifying CORS by header presence passes every origin — compare the value to the Origin you sent gotchas / azure-functions The header comes back for every origin (servers answer with a fallback, not an omission), so presence proves nothing; compare it to the Origin you sent, keep at least one case that expects allowed, and point the probe… Which Entra ID roles are privileged? isPrivileged is beta-only, and a hand-written list gets it wrong gotchas / graph Read isPrivileged live from beta roleDefinitions – v1.0 omits it and 400s on $select=isPrivileged; Exchange/SharePoint/Teams admins are not privileged Your URL sanitiser strips spaces — and every SharePoint file link 404s gotchas / security The C0 strip that blocks javascript: also eats the plain space, so every link to /Shared Documents/… 404s; strip to decide, return with %20 Your zip-bomb guard reads a private JSZip field — and fails open on the next upgrade gotchas / spfx entry._data.uncompressedSize is an implementation detail, and undefined → allow turns the next library upgrade into a silent loss of protection; read the declared sizes from the ZIP central directory instead