Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Friday, June 30, 2017

Application Content URI Rule effects

Previously I described Application Content URI Rules (ACUR) parsing and ACUR ordering. This post describes what you get from putting a URI in ACUR.

URIs in the ACUR gain the following which is otherwise unavailable:

  • Geoloc API usage
  • Audio and video capture API usage
  • Pointer lock API usage
  • Web notifications API usage
  • IndexedDB API usage
  • Clipboard API usage
  • window.external.notify access from within webview
  • window.close the primary window
  • Top level navigation in the primary window
  • Cross origin XHR and fetch to ms-appx(-web) scheme URIs
  • Cross origin dirtied canvas read access if dirtied by ms-appx(-web) scheme URIs
  • Cross origin text track for video element for tracks from ms-appx(-web) scheme URIs

URIs in the ACUR that also have full WinRT access additionally gain the following:

  • Cross origin XHR and fetch
  • Cross origin dirtied canvas read access
  • Cross origin text track for video element
  • Local audio and video WinRT plugins work with media elements

Thursday, June 1, 2017

Application Content URI Rules rule ordering

Application Content URI Rules (ACUR from now on) defines the bounds on the web that make up a Microsoft Store application. The previous blog post discussed the syntax of the Rule's Match attribute and this time I'll write about the interactions between the Rules elements.

Order

A single ApplicationContentUriRules element may have up to 100 Rule child elements. When determining if a navigation URI matches any of the ACUR the last Rule in the list with a matching match wildcard URI is used. If that Rule is an include rule then the navigation URI is determined to be an application content URI and if that Rule is an exclude rule then the navigation rule is not an application content URI. For example:

Rule Type='include' Match='https://example.com/'/
Rule Type='exclude' Match='https://example.com/'/

Given the above two rules in that order, the navigation URI https://example.com/ is not an application content URI because the last matching rule is the exclude rule. Reverse the order of the rules and get the opposite result.

WindowsRuntimeAccess

In addition to determining if a navigation URI is application content or not, a Rule may also confer varying levels of WinRT access via the optional WindowsRuntimeAccess attribute which may be set to 'none', 'allowForWeb', or 'all'. If a navigation URI matches multiple different include rules only the last rule is applied even as it applies to the WindowsRuntimeAccess attribute. For example:

Rule Type='include' Match='https://example.com/' WindowsRuntimeAccess='none'/
Rule Type='include' Match='https://example.com/' WindowsRuntimeAccess='all'/

Given the above two rules in that order, the navigation URI https://example.com/ will have access to all WinRT APIs because the last matching rule wins. Reverse the rule order and the navigation URI https://example.com/ will have no access to WinRT. There is no summation or combining of multiple matching rules - only the last matching rule wins.

Wednesday, May 31, 2017

Application Content URI Rules wildcard syntax

Application Content URI Rules (ACUR from now on) defines the bounds of the web that make up the Microsoft Store application. Package content via the ms-appx URI scheme is automatically considered part of the app. But if you have content on the web via http or https you can use ACUR to declare to Windows that those URIs are also part of your application. When your app navigates to URIs on the web those URIs will be matched against the ACUR to determine if they are part of your app or not. The documentation for how matching is done on the wildcard URIs in the ACUR Rule elements is not very helpful on MSDN so here are some notes.

Rules

You can have up to 100 Rule XML elements per ApplicationContentUriRules element. Each has a Match attribute that can be up to 2084 characters long. The content of the Match attribute is parsed with CreateUri and when matching against URIs on the web additional wildcard processing is performed. I’ll call the URI from the ACUR Rule the rule URI and the URI we compare it to found during app navigation the navigation URI.

The rule URI is matched to a navigation URI by URI component: scheme, username, password, host, port, path, query, and fragment. If a component does not exist on the rule URI then it matches any value of that component in the navigation URI. For example, a rule URI with no fragment will match a navigation URI with no fragment, with an empty string fragment, or a fragment with any value in it.

Asterisk

Each component except the port may have up to 8 asterisks. Two asterisks in a row counts as an escape and will match 1 literal asterisk. For scheme, username, password, query and fragment the asterisk matches whatever it can within the component.

Host

For the host, if the host consists of exactly one single asterisk then it matches anything. Otherwise an asterisk in a host only matches within its domain name label. For example, http://*.example.com will match http://a.example.com/ but not http://b.a.example.com/ or http://example.com/. And http://*/ will match http://example.com, http://a.example.com/, and http://b.a.example.com/. However the Store places restrictions on submitting apps that use the http://* rule or rules with an asterisk in the second effective domain name label. For example, http://*.com is also restricted for Store submission.

Path

For the path, an asterisk matches within the path segment. For example, http://example.com/a/*/c will match http://example.com/a/b/c and http://example.com/a//c but not http://example.com/a/b/b/c or http://example.com/a/c

Additionally for the path, if the path ends with a slash then it matches any path that starts with that same path. For example, http://example.com/a/ will match http://example.com/a/b and http://example.com/a/b/c/d/e/, but not http://example.com/b/.

If the path doesn’t end with a slash then there is no suffix matching performed. For example, http://example.com/a will match only http://example.com/a and no URIs with a different path.

As a part of parsing the rule URI and the navigation URI, CreateUri will perform URI normalization and so the hostname and scheme will be made lower case (casing matters in all other parts of the URI and case sensitive comparisons will be performed), IDN normalization will be performed, ‘.’ and ‘..’ path segments will be resolved and other normalizations as described in the CreateUri documentation.

Wednesday, November 2, 2016

Parsing WinMD with .NET reflection APIs

Parsing WinMD files, the containers of WinRT API metadata, is relatively simple using the appropriate .NET reflection APIs. However, figuring out which reflection APIs to use is not obvious. I've got a completed C sharp class parsing WinMD files that you can check out for reference.

Use System.Reflection.Assembly.ReflectionOnlyLoad to load the WinMD file. Don't use the normal load methods because the WinMD files contain only metadata. This will load up info about APIs defined in that WinMD, but any references to types outside of that WinMD including types found in the normal OS system WinMD files must be resolved by the app code via the System.Reflection.InteropServices.WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve event.

In this event handler you must resolve the unknown namespace reference by adding an assembly to the NamespaceResolveEventArgs's ResolvedAssemblies property. If you're only interested in OS system WinMD files you can use System.Reflection.InteropServices.WindowsRuntimeMetadata.ResolveNamespace to turn a namespace into the expected OS system WinMD path and turn that path into an assembly with ReflectionOnlyLoad.

Thursday, August 15, 2013

Moving PowerShell data into Excel

PowerShell nicely includes ConvertTo-CSV and ConvertFrom-CSV which allow you to serialize and deserialize your PowerShell objects to and from CSV. Unfortunately the CSV produced by ConvertTo-CSV is not easily opened by Excel which expects by default different sets of delimiters and such. Looking online you'll find folks who recommend using automation via COM to create a new Excel instance and copy over the data in that fashion. This turns out to be very slow and impractical if you have large sets of data. However you can use automation to open CSV files with not the default set of delimiters. So the following isn't the best but it gets Excel to open a CSV file produced via ConvertTo-CSV and is faster than the other options:
Param([Parameter(Mandatory=$true)][string]$Path);

$excel = New-Object -ComObject Excel.Application

$xlWindows=2
$xlDelimited=1 # 1 = delimited, 2 = fixed width
$xlTextQualifierDoubleQuote=1 # 1= doublt quote, -4142 = no delim, 2 = single quote
$consequitiveDelim = $False;
$tabDelim = $False;
$semicolonDelim = $False;
$commaDelim = $True;
$StartRow=1
$Semicolon=$True

$excel.visible=$true
$excel.workbooks.OpenText($Path,$xlWindows,$StartRow,$xlDelimited,$xlTextQualifierDoubleQuote,$consequitiveDelim,$tabDelim,$semicolonDelim, $commaDelim);
See Workbooks.OpenText documentation for more information.

Wednesday, August 7, 2013

Considerate MessagePort Usage

Sharing by leezie5. Two squirrels sharing food hanging from a bird feeder. Used under Creative Commons license Attribution-NonCommercial-NoDerivs 2.0 Generic.When writing a JavaScript library that uses postMessage and the message event, I must be considerate of other JS code that will be running along side my library. I shouldn't assume I'm the only sender and receiver on a caller provided MessagePort object. This means obviously I should use addEventListener("message" rather than the onmessage property (see related What if two programs did this?). But considering the actual messages traveling over the message channel I have the issue of accidentally processing another libraries messages and having another library accidentally process my own message. I have a few options for playing nice in this regard:
Require a caller provided unique MessagePort
This solves the problem but puts a lot of work on the caller who may not notice nor follow this requirement.
Uniquely mark my messages
To ensure I'm acting upon my own messages and not messages that happen to have similar properties as my own, I place a 'type' property on my postMessage data with a value of a URN unique to me and my JS library. Usually because its easy I use a UUID URN. There's no way someone will coincidentally produce this same URN. With this I can be sure I'm not processing someone else's messages. Of course there's no way to modify my postMessage data to prevent another library from accidentally processing my messages as their own. I can only hope they take similar steps as this and see that my messages are not their own.
Use caller provided MessagePort only to upgrade to new unique MessagePort
I can also make my own unique MessagePort for which only my library will have the end points. This does still require the caller to provide an initial message channel over which I can communicate my new unique MessagePort which means I still have the problems above. However it clearly reduces the surface area of the problem since I only need once message to communicate the new MessagePort.
The best solution is likely all of the above.
Photo is Sharing by leezie5. Two squirrels sharing food hanging from a bird feeder. Used under Creative Commons license Attribution-NonCommercial-NoDerivs 2.0 Generic.

Thursday, July 18, 2013

C++ constructor member initializers run in member declaration order

TL;DR: Keep your C++ class member declaration order the same as your constructor member initializers order.

C++ guarantees that the member initializers in a constructor are called in order. However the order in which they are called is the order in which the associated members are declared in the class, not the order in which they appear in the member initializer list. For instance, take the following code. I would have thought it would print "three, one, two", but in fact it prints, "one, two, three".

   
      #include "stdafx.h"
#include <iostream>

class PrintSomething {
public:
 PrintSomething(const wchar_t *name) { std::wcout << name << std::endl; }
};

class NoteOrder {
public:
        // This order doesn't matter.
 NoteOrder() : three(L"three"), one(L"one"), two(L"two") { }

 PrintSomething one;
 PrintSomething two;
 PrintSomething three;
};

int wmain(const int argc, const wchar_t* argv[])
{
 NoteOrder note; // Prints one, two, three, not three, one, two!
 return 0;
}

Thursday, August 30, 2012

Stripe Web Security CTF Summary

I was the 546th person to complete Stripe's web security CTF and again had a ton of fun applying my theoretical knowledge of web security issues to the (semi-)real world. As I went through the levels I thought about what red flags jumped out at me (or should have) that I could apply to future code reviews:

LevelIssueCode Review Red Flags
0Simple SQL injectionNo encoding when constructing SQL command strings. Constructing SQL command strings instead of SQL API
1extract($_GET);No input validation.
2Arbitrary PHP executionNo input validation. Allow file uploads. File permissions modification.
3Advanced SQL injectionConstructing SQL command strings instead of SQL API.
4HTML injection, XSS and CSRFNo encoding when constructing HTML. No CSRF counter measures. Passwords stored in plain text. Password displayed on site.
5Pingback server doesn't need to opt-inn/a - By design protocol issue.
6Script injection and XSSNo encoding while constructing script. Deny list (of dangerous characters). Passwords stored in plain text. Password displayed on site.
7Length extension attackCustom crypto code. Constructing SQL command string instead of SQL API.
8Side channel attackPassword handling code. Timing attack mitigation too clever.

More about each level in the future.

Tuesday, June 12, 2012

Application Protocols in Windows 8

In Windows 8 you can still register a desktop application to handle a particular URI scheme, but now you can also register a Metro Win8 application to handle a particular URI scheme. No more manually modifying the registry - now there's pretty UI in VS to handle this.

Thursday, May 17, 2012

Permanently Add Path to System PATH Environment Variable in PowerShell

According to MSDN the proper way to permanently add a path to your system's PATH environment variable is by modifying a registry value. Accordingly this is easily represented in a PowerShell script that first checks if the path provided is already there and otherwise appends it:
param([Parameter(Mandatory = $true)] [string] $Path);
$FullPathOriginal = (gp "HKLM:\System\CurrentControlSet\Control\Session Manager\Environment").Path;
if (!($FullPathOriginal.split(";") | ?{ $_ -like $Path })) {
    sp "HKLM:\System\CurrentControlSet\Control\Session Manager\Environment" -name Path -value ($FullPathOriginal + ";" +
 $Path);
}

Friday, March 23, 2012

Why Did This Work?

Do we have a word or phrase to describe the following situation: You code up something complicated and it compiles and works on the first try. You then spend the next ten minutes trying to figure out what's actually broken because it shouldn't be this easy.

Or in meme form:

Wednesday, March 14, 2012

Alternate IPv4 Forms - URI Host Syntax Notes

By the URI RFC there is only one way to represent a particular IPv4 address in the host of a URI. This is the standard dotted decimal notation of four bytes in decimal with no leading zeroes delimited by periods. And no leading zeros are allowed which means there's only one textual representation of a particular IPv4 address.

However as discussed in the URI RFC, there are other forms of IPv4 addresses that although not officially allowed are generally accepted. Many implementations used inet_aton to parse the address from the URI which accepts more than just dotted decimal. Instead of dotted decimal, each dot delimited part can be in decimal, octal (if preceded by a '0') or hex (if preceded by '0x' or '0X'). And that's each section individually - they don't have to match. And there need not be 4 parts: there can be between 1 and 4 (inclusive). In case of less than 4, the last part in the string represents all of the left over bytes, not just one.

For example the following are all equivalent:

192.168.1.1
Standard dotted decimal form
0300.0250.01.01
Octal
0xC0.0XA8.0x1.0X1
Hex
192.168.257
Fewer parts
0300.0XA8.257
All of the above

The bread and butter of URI related security issues is when one part of the system disagrees with another about the interpretation of the URI. So this non-standard, non-normal form syntax has been been a great source of security issues in the past. Its mostly well known now (CreateUri normalizes these non-normal forms to dotted decimal), but occasionally a good tool for bypassing naive URI blocking systems.

Friday, February 24, 2012

Web Worker Initialization Race

Elaborating on a previous brief post on the topic of Web Worker initialization race conditions, there's two important points to avoid a race condition when setting up a Worker:

  1. The parent starts the communication posting to the worker.
  2. The worker sets up its message handler in its first synchronous block of execution.

For example the following has no race becaues the spec guarentees that messages posted to a worker during its first synchronous block of execution will be queued and handled after that block. So the worker gets a chance to setup its onmessage handler. No race:

'parent.js':
   var worker = new Worker();
   worker.postMessage("initialize");

'worker.js':
   onmessage = function(e) {
      // ...
   }

The following has a race because there's no guarentee that the parent's onmessage handler is setup before the worker executes postMessage. Race (violates 1):

'parent.js':
   var worker = new Worker();
   worker.onmessage = function(e) {
      // ...
   };

'worker.js':
   postMessage("initialize");

The following has a race because the worker has no onmessage handler set in its first synchronous execution block and so the parent's postMessage may be sent before the worker sets its onmessage handler. Race (violates 2):

'parent.js':
   var worker = new Worker();
   worker.postMessage("initialize");

'worker.js':
   setTimeout(
      function() {
         onmessage = function(e) {
            // ...
         }
      },
      0);

Saturday, December 3, 2011

JavaScript Array methods in the latest browsers

Cool and (relatively) new methods on the JavaScript Array object are here in the most recent versions of your favorite browser! More about them on ECMAScript5, MSDN, the IE blog, or Mozilla's documentation. Here's the list that's got me excited:

some & every
Does your callback function return true for any (some) or all (every) of the array's elements?
filter
Filters out elements for which your callback function returns false (in a new copy of the Array).
map
Each element is replaced with the result of it run through your callback function (in a new copy of the Array).
reduce & reduceRight
Your callback is called on each element in the array in sequence (from start to finish in reduce and from finish to start in reduceRight) with the result of the previous callback call passed to the next. Reduce your array to a single value aggregated in any manner you like via your callback function.
forEach
Simply calls your callback passing in each element of your array in turn. I have vague performance concerns as compared to using a normal for loop.
indexOf & lastIndexOf
Finds the first or last (respectively) element in the array that matches the provided value via strict equality operator and returns the index of that element or -1 if there is no such element. Surprisingly, no custom comparison callback method mechanism is provided.

Thursday, December 1, 2011

Bug Spotting: Ctors with default parameters

The following code compiled just fine but did not at all act in the manner I expected:

BOOL CheckForThing(__in CObj *pObj, __in IFigMgr* pFigMgr, __in_opt LPCWSTR url)
{
    BOOL fCheck = FALSE;
    if (SubCheck(pObj))
    {
        ...
I’m calling SubCheck which looks like:
bool SubCheck(const CObj& obj);

Did you spot the bug? As you can see I should be passing in *pObj not pObj since the method takes a const CObj& not a CObj*. But then why does it compile?

It works because CObj has a constructor with all but one param with default values and CObj is derived from IUnknown:

CObj(__in_opt IUnknown * pUnkOuter, __in_opt LPCWSTR pszUrl = NULL);
Accordingly C++ uses this constructor as an implicit conversion operator. So instead of passing in my CObj, I end up creating a new CObj on the stack passing in the CObj I wanted as the outer object which has a number of issues.

The lesson is unless you really want this behavior, don't make constructors with all but 1 or 0 default parameters. If you need to do that consider using the 'explicit' keyword on the constructor.

More info about forcing single argument constructors to be explicit is available on stack overflow.

Wednesday, October 19, 2011

Bug Spotting: Smart pointers and parameter evaluation order

The following code works fine. I have a ccomptr named resolvedUri and I want to update its hostname so I do the following:
        CreateIUriBuilder(resolvedUri, 0, 0, &builder);
builder->SetHost(host);
builder->CreateUri(0xFFFFFFFF, 0, 0, &resolvedUri);


But the following similar looking code has a bug:
    ResolveHost(resolvedUri, &resolvedUri);


The issue is that doing &resolvedUri gets the address of the pointer but also clears out the pointer due to the definition of my smart pointer class:
    operator T**()  
{
T *ptrValue = mPtrValue;
mPtrValue->Release();
mPtrValue = NULL;
return &ptrValue;
}


In C++ there’s no guarantee about the order in which parameters for a function or method are evaluated. In the case above, &resolvedUri clears out the ccomptr before evaluating resolvedUri.Get() and so ResolveHostAlias gets a nullptr.

An interesting and related thread on stack overflow on undefined behavior in C++.

Tuesday, May 24, 2011

_opt Mnemonic

​I always have trouble remembering where the opt goes in SAL in the __deref_out case. The mnemonic is pretty simple: the _opt at the start of the SAL is for the pointer value at the start of the function. And the _opt at the end of the SAL is for the dereferenced pointer value at the end of the function.






SALfoo == nullptr allowed at function start?*foo == nullptr allowed at function end?
__deref_out void **fooNoNo
__deref_opt_out void **fooYesNo
__deref_out_opt void **fooNoYes
__deref_opt_out_opt void **fooYesYes
.

Sunday, May 22, 2011

PowerShell Script Batch File Wrapper

I'm trying to learn and use PowerShell more, but plenty of other folks I know don't use PowerShell. To allow them to use my scripts I use the following cmd.exe batch file to make it easy to call PowerShell scripts. To use, just name the batch file name the same as the corresponding PowerShell script filename and put it in the same directory.

@echo off
if "%1"=="/?" goto help
if "%1"=="/h" goto help
if "%1"=="-?" goto help
if "%1"=="-h" goto help

%systemroot%\system32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -Command . %~dpn0.ps1 %*
goto end

:help
%systemroot%\system32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -Command help %~dpn0.ps1 -full
goto end

:end

Additionally for PowerShell scripts that modify the current working directory I use the following batch file:

@echo off
if "%1"=="/?" goto help
if "%1"=="/h" goto help
if "%1"=="-?" goto help
if "%1"=="-h" goto help

%systemroot%\system32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -Command . %~dpn0.ps1 %*;(pwd).Path 1> %temp%\%~n0.tmp 2> nul
set /p newdir=<%temp%\%~n0.tmp
cd /d %newdir%
goto end

:help
%systemroot%\system32\windowspowershell\v1.0\powershell.exe -ExecutionPolicy RemoteSigned -Command "help %~dpn0.ps1"
goto end

:end

Wednesday, April 6, 2011

Capturing HTTPS with FiddlerCore

I used FiddlerCore in GeolocMock to edit HTTPS responses and ran into two stumbling blocks that I'll document here. The first is that I didn't check if the Fiddler root cert existed or was installed, which of course is necessary to edit HTTPS traffic. The following is my code where I check for the certs.

    if (!Fiddler.CertMaker.rootCertExists())
{
if (!Fiddler.CertMaker.createRootCert())
{
throw new Exception("Unable to create cert for FiddlerCore.");
}
}

if (!Fiddler.CertMaker.rootCertIsTrusted())
{
if (!Fiddler.CertMaker.trustRootCert())
{
throw new Exception("Unable to install FiddlerCore's cert.");
}
}

The second problem I had (which would have been solved had I read all the sample code first) was that my changes weren't being applied. In my app I only need the BeforeResponse but in order to modify the response I must also sign up for the BeforeRequest event and mark the bBufferResponse flag on the session before the response comes back. For example:

    Fiddler.FiddlerApplication.BeforeRequest += new SessionStateHandler(FiddlerApplication_BeforeRequest);
Fiddler.FiddlerApplication.BeforeResponse += new SessionStateHandler(FiddlerApplication_BeforeResponse);
...
private void FiddlerApplication_BeforeRequest(Session oSession)
{
if (IsInterestingSession(oSession))
{
oSession.bBufferResponse = true;
}
}