WebAPI/Security/WebNFC

From MozillaWiki
Jump to: navigation, search

Name of API: WebNFC API Reference:

Brief purpose of API: Allow core (certified) and privileged apps to interact directly with NFC devices

General Use Cases: sharing content (media files, contacts) with NFC pairing, read/write NFC tags


Inherent threats:

  • Theft of sensitive data
  • Device compromise (configuring NFC device)
  • Potential for financial impact (payments via NFC) - cf the Secure Element API

Threat severity: Critical

Regular web content (unauthenticated) Use cases for unauthenticated code: None

Authorization model for normal content: None

Authorization model for installed content: None

Potential mitigations: N/A

Trusted (authenticated by publisher)

Same as for installed unauthenticated app

Certified (vouched for by trusted 3rd party)

Use cases for certified code:

  • Configure, enable/disable NFC devices.
  • Interact with NFC devices.
  • Manage NFC payments.

Security Review

Scope of Review

Gaia

  • System Application changes
  • Web Activities
  • System messages
  • Communication between system app and NFC client app
  • Certified NFC applications
  • 3rd party NFC apps

Out of scope for now:

  • Wallet Application (see Secure Element API)
  • Certified transportation/miFare applications

Gecko

  • mozNfc APIs
  • Gecko Permissions
  • Messaging (NFC:* messages, system messages)
  • NFC System worker
  • Interface to nfcd on IPC socket

Out of scope:

  • Secure elements
    • access control
    • integration with RIL

Gonk

  • NFC Daemon (nfcd)
  • Interface to lib

Documentation and reference

Key Bugs

Security Review: WebNFC bug 749325
Feature Bug (meta): https://bugzilla.mozilla.org/show_bug.cgi?id=860906
Dependent bugs: https://bugzilla.mozilla.org/showdependencytree.cgi?maxdepth=2&id=860906&hide_resolved=0


Gonk
NFC Daemon for B2G (daemon for supporting lib-nxp): bug 860907
B2G NFC: NFC Daemon for supporting libnfc-nci (daemon for supporting lib-nci): bug 906579
B2G NFC: Define protocol to communicate between nfcd and b2g: bug 897312

Gecko
WebNFC (near-field communication): bug 674741

Gaia
B2G Gaia Integration for NFC: bug 860910

Secure Element Support
NFC Secure Element Support: bug 879861 Support Nfc Access Control for Secure Element Access: bug 884594

Documentation about the NFC API:

https://developer.mozilla.org/en-US/docs/Web/API/NFC_API
https://developer.mozilla.org/en-US/docs/Web/API/NFC_API/Using_the_NFC_API
https://developer.mozilla.org/en-US/docs/Web/API/NFC_API/Using_the_NFC_emulator

Gaia

(Review Guidelines for app reviewers)

Quick overview and security highlights: (see for more details about how to use the API: https://developer.mozilla.org/en-US/docs/Web/API/NFC_API/Using_the_NFC_API)

An app using the NFC API to interact with NFC messages has to the declare in the manifest: the nfc permission (with readonly, readwrite or none if the app only receive data from the activity itself). the nfc-ndef-discovered activity: "activities": {

   "nfc-ndef-discovered": {
         "filters": {
               "type": "url",
               "url": {
                     "required":true, "pattern":"https?:.{1,16384}", "patternFlags":"i"
                    }
             }
       }
     }

Types can be: text, text/vcard, uri, smartposter.

shared/js/nfc_utils.js provides methods for coding and decoding NDEF record payloads such as Wellknown, URI, Text, SmartPoster, MIME. The handler for the nfc-ndef-discovered should filter content and match what is expected in the “type” filters defined in the manifest.

Thee application can get new content through NFC by the following ways:

  • getting content by reading a tag:
  • getting a tag: var tag = navigator.mozNfc.getNFCTag(data.sessionToken);
  • getting shared contact via a mozNfcPeer:
   navigator.mozNfc.onpeerready = function (evt) {
     var peer = navigator.mozNfc.getNFCPeer(evt.detail);
     console.log(peer instanceof MozNFCPeer); // should print true;
   };


One thing to keep in mind: sharing a file with a NFC handover as explained here: https://developer.mozilla.org/en-US/docs/Web/API/NFC_API/Using_the_NFC_API#Sending_a_Blob_to_another_MozNFCPeer_by_NFC_handover means a NFC handover between two devices will initiate a Bluetooth connection to send the file.

Other permissions that applications should NOT request: nfc-share, nfc-manager, nfc-hci-event


Gecko

1. Receives IPC messages from NFCd 2. Broadcasts system messages to all apps (which have nfc-manager permission) nfc-tech-discovered nfc-tech-lost nfc-manager-send-file The patch also adds the following? bluetooth-hfp-status-changed bluetooth-sco-status-changed

3. IPC NFC:* messages Parent listens to

 const NFC_IPC_MSG_NAMES = [
   "NFC:SendToNfcd",
   "NFC:NdefDetails",
   "NFC:NdefRead",
   "NFC:NdefWrite",
   "NFC:NdefPush",
   "NFC:NfcATagDetails",
   "NFC:NfcATagTransceive",
   "NFC:Connect",
   "NFC:Close"
 ];

Child Listens to:

 const NFC_IPC_MSG_NAMES = [
   "NFC:TechDiscovered",
   "NFC:TechLost",
   "NFC:NDEFDetailsResponse",
   "NFC:NDEFReadResponse",
   "NFC:NDEFWriteResponse",
   "NFC:NDEFPushResponse",
   "NFC:NfcATagDetailsResponse",
   "NFC:NfcATagTransceiveResponse",
   "NFC:ConnectResponse",
   "NFC:CloseResponse"
 ];


DOM parts

Child Code

Parent code


IPC names:

 const NFC_IPC_MSG_ENTRIES = [
 { permission: null,
   messages: ["NFC:AddEventListener",
              "NFC:QueryInfo",
              "NFC:CallDefaultFoundHandler",
              "NFC:CallDefaultLostHandler"] },
 { permission: "nfc",
   messages: ["NFC:ReadNDEF",
              "NFC:WriteNDEF",
              "NFC:MakeReadOnly",
              "NFC:Format",
              "NFC:Transceive"] },
 { permission: "nfc-share",
   messages: ["NFC:SendFile",
              "NFC:RegisterPeerReadyTarget",
              "NFC:UnregisterPeerReadyTarget"] },
 { permission: "nfc-manager",
   messages: ["NFC:CheckP2PRegistration",
              "NFC:NotifyUserAcceptedP2P",
              "NFC:NotifySendFileStatus",
              "NFC:ChangeRFState",
              "NFC:SetFocusApp"] }
 ];


Session Handling
Session token is set in Nfc.js. The session token is broadcast via a ”nfc-manager-tech-discovered” message. Only the app with nfc-manage can recieve this (is the system app). The system does different things based on the tech type, but basically, the app that ends up talking to the tag would call navigator.mozNfc.getNFCTag(sessiontoken). For peer connections, this is the system app itself. For other NDEF types, the system app starts a web activity, which includes the session token.

So, some important notes from this behavior: Any web app could claim to register a web activity handler for a specific ndef type


 "activities": {
   "nfc-tech-lost": {
     "filters": {
       "type": "info"
     }
   },
   "nfc-ndef-discovered": {
     "filters": {
       "type": ["device", "empty", "external-type", "mail",
                "smartposter", "smartposter-action",
                "text/vcard", "text",
                "webcontacts/contact", "webcontacts/email",
                "webtelephony/number", "websms/sms",
                "uri",
                "*"
               ]
     }
   }
 }





Gonk

General info about low-level NFC architecture (schemas, protocol stack, etc): http://mp-nfc.org/nfc_near_field_communication_architecture.html 3 operating modes: http://nfc-forum.org/our-work/specifications-and-application-documents/specifications/


Mode  Description  Exchanged data Protocols Role Notes
peer-to-peer communications between two NFC enabled phone NDEF data LLCP

SNEP (application-level)

active: bidirectional com’
reader/writer phone reads, retrieve, alter data stored in NFC tags NDEF data Tag operations [1] active:

phone initiates unidirectional connection

4 tag types:
  • 1 & 3: signed
  • 2: not signed (MIFARE)
  • 4: variable
card emulation  phone acts as a smart card (emulates or embeds a smart card) Interact with SE Same as smart card digital and analog protocols passive:

external NFC reader initiates the connection [2]

[1] Different tags can be used according to their use (sms, number phone shortcut, smart poster, bluetooth pairing…): see http://mp-nfc.org/nfc_near_field_communication_nfc_tag_types.html When exchanging voluminous data, the tag initiates the bluetooth pairing for performing the actual data exchange. [2] Communications with SE more secure when smart card is emulated?

Threats and counter-measures:

  • data corruption while transferring: can be avoided if the NFC device checks the RF field while the data is transmitted (to corrupt the data, the RF field will be significantly bigger)
  • eavesdropping and data modification: establish a secure channel. Passive connections are more difficult to attack. Tags of type 2 are insecure (not signed).
  • ata insertion: answer without delay or establish a secure channel.

(additional security which can be implemented: NFC specific key agreement)

Standardized security protocols used in Peer-to-Peer protocol:

Both are implemented in the NFC core library

Source code:

Android has its own NFC API. (<> Open NFC API) Android source code for reference:

Interesting Firefox OS code:

  • Portable NFC core library: B2G/external/libnfc-*
  • NFC Daemon: system/nfcd (ported from Android)
  • Conf files for broadcom chips on Nexus 4: /device/lge/mako/nfc (not security sensitive from what I’ve read)


Data manipulation:

NDEF is a binary message format to encapsulate one or several application payloads into a single message construct. (specs: http://www.cardsys.dk/download/NFC_Docs/NFC%20Data%20Exchange%20Format%20%28NDEF%29%20Technical%20Specification.pdf)

  • A NDEF message contains one or several NDEF records (payload length, type and optional identifier) which each contains payload of arbitrary type.
  • Payload type can be: URI, MIME, NFC-specific type formats.
  • Error handling is the responsibility of the NDEF parser.

In Gonk, NDEF messages are implemented in interface/NdefMessage.cpp, and interface/NdefRecord.cpp.

The NFC chip receives NDEF data: if it is raw data (NDEF PDU) it is converted to NDEF messages. Then messages are serialized to JSON to be sent to Gecko.

Checking: payload size is checked against MAX_PAYLOAD_SIZE when messages are sent or received: OK don’t trust data input: (data type is of not importance at this stage: is either binary stream of NDEF messages) JSON serialization Tags data handling


P2P mode: broadcom/PeerToPeer.cpp

  • Send and receive byte buffers through the LLCP protocol, called from the SnepMessenger.
  • Received bytes are put into a SnepMessage (the payload is put in a Ndef message, calling parse() so MAX_PAYLOAD_SIZE is checked)
  • Writing NdefMessage to byte buffers to send data via LLCP: call NdefRecord.writeToByteBuffer() (NdefMessage.toByteArray)
  • /!\ When sending NDEF raw data, the data is put in a std::vector<uint_8> without checking size limit -> bad ? or is content size checked before when creating a NDEF message => yes, when it’s called from SnepMessanger, the method is called with a snepMessage as an argument (which was constructed checking the max size of the payload)

Reader/writer mode: broadcom/NfcTagManager.cpp

  • Read and write NDEF messages
  • When the phone reads a tag, a NdefMessage is filled with data (doReadNdef()) calling NdefMessage.parse(): initialize NDEF message with NDEF binary data, * MAX_PAYLOAD_SIZE is checked when receiving raw data: 10MB payload limit


Communications:

Checking: implementation of a secure channel, mitigating data corruption: OK, if trusting the NFC core library In P2P mode, power off disconnects the device from all clients/servers: OK


General notes about the UX/UI of NFC

Contrary to Bluetooth, the idea behind the UX of NFC if to have a “quick and easy” way to share content:

  1. Enable NFC
  2. Tap the phones
  3. Share content (Sharing UI)
  4. Display the content

Because phones have to be very close from each other to be able to share content, user prompts are almost not used except for the Sharing UI. Especially, a user isn’t prompted to to accept to receive the content. In the case of URL sharing, the Browser is automatically launched to display the content hosted at the URL. One risk could be that a user let their phone on the corner of a desk or in their pocket while NFC is enabled, and that somebody share content without them to be aware of it (in the street, in the office, etc). This is mitigated by the fact that NFC is disabled automatically when the screen is off and/or locked.

Use cases / Security & Privacy considerations

Ref: https://webbluetoothcg.github.io/web-bluetooth/use-cases.html#risks

Communication: 4cm and less
Possible sources for content:

  • NFC cards (passive)
  • NFC tags (passive)
  • Device with NFC enabled (active)
 Action User prompt Potential threats Mitigations
 Reading a tag no 

works when screen off: no </br> works when screen locked: no </br>

Loading malicious content the user is unaware of:
  • Browser loading a malicious URL
  • Adding a contact to the Contact list
NFC is disabled when the screen is off
Sharing content (writing on a tag / NFC handover + BT) yes (sharing UI)


works when screen off: no
works when screen locked: no
NB: A photo taken from the Camera while the phone is still PIN-locked can’t be shared from the Preview panel

Receiving shared content (NFC handover + BT) no (notification after file is received)

works when screen off: no works when screen locked: no

Devices stayed paired for BT: no forced browsing?
App spoofs a web activity associated with NFC (e.g. sends nfc-ndef-discovered)   Probably ok
User places phone on something which is a NFC enabled. NFC device spams phone with unwanted material. no E.g.: stick an nfc tag to the back of someones phone, it will also navigate to a url when you unlock.
NFC enabled bluetooth for file transfers. Can an attacker take advantage of this? BT turned off after transfer is done if it was off in the settings.

In the case of the use of BT with a NFC handover, the risks applicable to the use of Bluetooth apply to NFC use cases too : https://webbluetoothcg.github.io/web-bluetooth/use-cases.html#security_privacy